Sun Aug 6 15:06:22 2006

Asterisk developer's documentation


Main Page | Modules | Alphabetical List | Data Structures | Directories | File List | Data Fields | Globals | Related Pages

chan_sip.c File Reference

Implementation of Session Initiation Protocol. More...

#include <stdio.h>
#include <ctype.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <net/if.h>
#include <errno.h>
#include <stdlib.h>
#include <fcntl.h>
#include <netdb.h>
#include <signal.h>
#include <sys/signal.h>
#include <netinet/in.h>
#include <netinet/in_systm.h>
#include <arpa/inet.h>
#include <netinet/ip.h>
#include <regex.h>
#include "asterisk.h"
#include "asterisk/lock.h"
#include "asterisk/channel.h"
#include "asterisk/config.h"
#include "asterisk/logger.h"
#include "asterisk/module.h"
#include "asterisk/pbx.h"
#include "asterisk/options.h"
#include "asterisk/sched.h"
#include "asterisk/io.h"
#include "asterisk/rtp.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/dnsmgr.h"
#include "asterisk/devicestate.h"
#include "asterisk/linkedlists.h"

Include dependency graph for chan_sip.c:

Go to the source code of this file.

Data Structures

struct  ast_peer_list
 The peer list: Peers and Friends ---. More...
struct  ast_user_list
 The user list: Users and friends ---. More...

Defines

#define ALLOWED_METHODS   "INVITE, ACK, CANCEL, OPTIONS, BYE, REFER, SUBSCRIBE, NOTIFY"
 SIP Methods we support.
#define CALLERID_UNKNOWN   "Unknown"
#define DEBUG_READ   0
#define DEBUG_SEND   1
#define DEC_CALL_LIMIT   0
#define DEFAULT_CALLERID   "asterisk"
#define DEFAULT_CONTEXT   "default"
#define DEFAULT_DEFAULT_EXPIRY   120
#define DEFAULT_EXPIRY   900
#define DEFAULT_FREQ_NOTOK   10 * 1000
#define DEFAULT_FREQ_OK   60 * 1000
#define DEFAULT_MAX_EXPIRY   3600
#define DEFAULT_MAX_FORWARDS   "70"
#define DEFAULT_MAXMS   2000
#define DEFAULT_MWITIME   10
#define DEFAULT_NOTIFYMIME   "application/simple-message-summary"
#define DEFAULT_REALM   "asterisk"
#define DEFAULT_REGISTRATION_TIMEOUT   20
#define DEFAULT_RETRANS   1000
#define DEFAULT_SIP_PORT   5060
#define DEFAULT_USERAGENT   "Asterisk PBX"
#define DEFAULT_VMEXTEN   "asterisk"
#define EXPIRY_GUARD_LIMIT   30
#define EXPIRY_GUARD_MIN   500
#define EXPIRY_GUARD_PCT   0.20
#define EXPIRY_GUARD_SECS   15
#define FLAG_FATAL   (1 << 1)
#define FLAG_RESPONSE   (1 << 0)
#define INC_CALL_LIMIT   1
#define IPTOS_MINCOST   0x02
#define MAX(a, b)   ((a) > (b) ? (a) : (b))
#define MAX_AUTHTRIES   3
#define MAX_RETRANS   6
#define NO_RTP   0
#define NOT_SUPPORTED   0
#define REG_STATE_AUTHSENT   2
#define REG_STATE_FAILED   7
#define REG_STATE_NOAUTH   6
#define REG_STATE_REGISTERED   3
#define REG_STATE_REGSENT   1
#define REG_STATE_REJECTED   4
#define REG_STATE_TIMEOUT   5
#define REG_STATE_UNREGISTERED   0
#define RTP   1
#define SIP_ALREADYGONE   (1 << 0)
#define SIP_CALL_LIMIT   (1 << 29)
#define SIP_CALL_ONHOLD   (1 << 28)
#define SIP_CAN_BYE   (1 << 15)
#define SIP_CAN_REINVITE   (1 << 20)
#define SIP_DEBUG_CONFIG   1 << 0
#define SIP_DEBUG_CONSOLE   1 << 1
#define SIP_DTMF   (3 << 16)
#define SIP_DTMF_AUTO   (3 << 16)
#define SIP_DTMF_INBAND   (1 << 16)
#define SIP_DTMF_INFO   (2 << 16)
#define SIP_DTMF_RFC2833   (0 << 16)
#define SIP_FLAGS_TO_COPY
#define SIP_GOTREFER   (1 << 7)
#define SIP_INC_COUNT   (1 << 31)
#define SIP_INSECURE_INVITE   (1 << 23)
#define SIP_INSECURE_PORT   (1 << 22)
#define SIP_LEN_CONTACT   256
#define SIP_MAX_HEADERS   64
#define SIP_MAX_LINES   64
#define SIP_MAX_PACKET   4096
#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_NEEDDESTROY   (1 << 1)
#define SIP_NEEDREINVITE   (1 << 5)
#define SIP_NOVIDEO   (1 << 2)
#define SIP_OPT_100REL   (1 << 1)
#define SIP_OPT_EARLY_SESSION   (1 << 3)
#define SIP_OPT_EVENTLIST   (1 << 11)
#define SIP_OPT_GRUU   (1 << 12)
#define SIP_OPT_JOIN   (1 << 4)
#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_REPLACES   (1 << 0)
#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_OSPAUTH   (3 << 26)
#define SIP_OSPAUTH_EXCLUSIVE   (3 << 26)
#define SIP_OSPAUTH_GATEWAY   (1 << 26)
#define SIP_OSPAUTH_NO   (0 << 26)
#define SIP_OSPAUTH_PROXY   (2 << 26)
#define SIP_OUTGOING   (1 << 13)
#define SIP_PAGE2_DYNAMIC   (1 << 5)
#define SIP_PAGE2_IGNOREREGEXPIRE   (1 << 3)
#define SIP_PAGE2_RT_FROMCONTACT   (1 << 4)
#define SIP_PAGE2_RTAUTOCLEAR   (1 << 2)
#define SIP_PAGE2_RTCACHEFRIENDS   (1 << 0)
#define SIP_PAGE2_RTUPDATE   (1 << 1)
#define SIP_PENDINGBYE   (1 << 6)
#define SIP_PKT_DEBUG   (1 << 0)
#define SIP_PKT_WITH_TOTAG   (1 << 1)
#define SIP_PROG_INBAND   (3 << 24)
#define SIP_PROG_INBAND_NEVER   (0 << 24)
#define SIP_PROG_INBAND_NO   (1 << 24)
#define SIP_PROG_INBAND_YES   (2 << 24)
#define SIP_PROGRESS_SENT   (1 << 4)
#define SIP_PROMISCREDIR   (1 << 8)
#define SIP_REALTIME   (1 << 11)
#define SIP_REINVITE   (3 << 20)
#define SIP_REINVITE_UPDATE   (2 << 20)
#define SIP_RINGING   (1 << 3)
#define SIP_SELFDESTRUCT   (1 << 14)
#define SIP_SENDRPID   (1 << 30)
#define SIP_TRUSTRPID   (1 << 9)
#define SIP_USECLIENTCODE   (1 << 12)
#define SIP_USEREQPHONE   (1 << 10)
#define SIPDUMPER
#define SUPPORTED   1
#define SUPPORTED_EXTENSIONS   "replaces"
 SIP Extensions we support.
#define VIDEO_CODEC_MASK   0x1fc0000

Enumerations

enum  domain_mode { SIP_DOMAIN_AUTO, SIP_DOMAIN_CONFIG }
enum  parse_register_result { PARSE_REGISTER_FAILED, PARSE_REGISTER_UPDATE, PARSE_REGISTER_QUERY }
enum  sip_auth_type { PROXY_AUTH, WWW_AUTH }
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
}
enum  subscriptiontype {
  NONE = 0, TIMEOUT, XPIDF_XML, DIALOG_INFO_XML,
  CPIM_PIDF_XML, PIDF_XML
}

Functions

static char * __get_header (struct sip_request *req, char *name, int *start)
static int __sip_ack (struct sip_pvt *p, int seqno, int resp, int sipmethod)
 __sip_ack: Acknowledges receipt of a packet and stops retransmission ---
static int __sip_autodestruct (void *data)
 __sip_autodestruct: Kill a call (called by scheduler) ---
static void __sip_destroy (struct sip_pvt *p, int lockowner)
 __sip_destroy: Execute destrucion of call structure, release memory---
static int __sip_do_register (struct sip_registry *r)
 __sip_do_register: Register with SIP proxy ---
static int __sip_pretend_ack (struct sip_pvt *p)
static int __sip_reliable_xmit (struct sip_pvt *p, int seqno, int resp, char *data, int len, int fatal, int sipmethod)
 __sip_reliable_xmit: transmit packet with retransmits ---
static int __sip_semi_ack (struct sip_pvt *p, int seqno, int resp, int sipmethod)
 __sip_semi_ack: Acks receipt of packet, keep it around (used for provisional responses) ---
static int __sip_show_channels (int fd, int argc, char *argv[], int subscriptions)
static int __sip_xmit (struct sip_pvt *p, char *data, int len)
 __sip_xmit: Transmit SIP message ---
static int __transmit_response (struct sip_pvt *p, char *msg, struct sip_request *req, int reliable)
 __transmit_response: Base transmit response function
static int _sip_show_peer (int type, int fd, struct mansession *s, struct message *m, int argc, char *argv[])
static int _sip_show_peers (int fd, int *total, struct mansession *s, struct message *m, int argc, char *argv[])
 _sip_show_peers: Execute sip show peers command
static int add_blank_header (struct sip_request *req)
 add_blank_header: Add blank header to SIP message
static void add_codec_to_sdp (const struct sip_pvt *p, int codec, int sample_rate, char **m_buf, size_t *m_size, char **a_buf, size_t *a_size, int debug)
static int add_digit (struct sip_request *req, char digit)
 add_digit: add DTMF INFO tone to sip message ---
static int add_header (struct sip_request *req, const char *var, const char *value)
 add_header: Add header to SIP message
static int add_header_contentLength (struct sip_request *req, int len)
 add_header_contentLen: Add 'Content-Length' header to SIP message
static int add_line (struct sip_request *req, const char *line)
 add_line: Add content (not header) to SIP message
static void add_noncodec_to_sdp (const struct sip_pvt *p, int format, int sample_rate, char **m_buf, size_t *m_size, char **a_buf, size_t *a_size, int debug)
static struct sip_authadd_realm_authentication (struct sip_auth *authlist, char *configuration, int lineno)
 add_realm_authentication: Add realm authentication in list ---
static void add_route (struct sip_request *req, struct sip_route *route)
 add_route: Add route header into request per learned route ---
static int add_sdp (struct sip_request *resp, struct sip_pvt *p)
 add_sdp: Add Session Description Protocol message ---
static int add_sip_domain (const char *domain, const enum domain_mode mode, const char *context)
 add_sip_domain: Add SIP domain to list of domains we are responsible for
static int add_text (struct sip_request *req, const char *text)
 add_text: Add text body to SIP message ---
static int add_vidupdate (struct sip_request *req)
 add_vidupdate: add XML encoded media control with update ---
static void append_date (struct sip_request *req)
 append_date: Append date to SIP message ---
static int append_history (struct sip_pvt *p, const char *event, const char *data)
 append_history: Append to SIP dialog history
static AST_LIST_HEAD_STATIC (domain_list, domain)
 AST_MUTEX_DEFINE_STATIC (sip_reload_lock)
 AST_MUTEX_DEFINE_STATIC (monlock)
 AST_MUTEX_DEFINE_STATIC (netlock)
 Protect the monitoring thread, so only one process can kill or start it, and not when it's doing something critical.
 AST_MUTEX_DEFINE_STATIC (iflock)
 Protect the interface list (of sip_pvt's).
 AST_MUTEX_DEFINE_STATIC (rand_lock)
 AST_MUTEX_DEFINE_STATIC (usecnt_lock)
static void ast_quiet_chan (struct ast_channel *chan)
 ast_quiet_chan: Turn off generator data
static int ast_sip_ouraddrfor (struct in_addr *them, struct in_addr *us)
 ast_sip_ouraddrfor: NAT fix - decide which IP address to use for ASterisk server? ---
static int attempt_transfer (struct sip_pvt *p1, struct sip_pvt *p2)
 attempt_transfer: Attempt transfer of SIP call ---
static int auto_congest (void *nothing)
 auto_congest: Scheduled congestion on a call ---
static void build_callid (char *callid, int len, struct in_addr ourip, char *fromdomain)
 build_callid: Build SIP CALLID header ---
static void build_contact (struct sip_pvt *p)
 build_contact: Build contact header - the contact header we send out ---
static struct sip_peerbuild_peer (const char *name, struct ast_variable *v, int realtime)
 build_peer: Build peer from config file ---
static int build_reply_digest (struct sip_pvt *p, int method, char *digest, int digest_len)
 build_reply_digest: Build reply digest ---
static void build_route (struct sip_pvt *p, struct sip_request *req, int backwards)
 build_route: Build route list from Record-Route header ---
static void build_rpid (struct sip_pvt *p)
 build_rpid: Build the Remote Party-ID & From using callingpres options ---
static struct sip_userbuild_user (const char *name, struct ast_variable *v, int realtime)
 build_user: Initiate a SIP user structure from sip.conf ---
static void build_via (struct sip_pvt *p, char *buf, int len)
 build_via: Build a Via header for a request ---
static int cb_extensionstate (char *context, char *exten, int state, void *data)
 cb_extensionstate: Callback for the devicestate notification (SUBSCRIBE) support subsystem ---
static int check_auth (struct sip_pvt *p, struct sip_request *req, char *randdata, int randlen, char *username, char *secret, char *md5secret, int sipmethod, char *uri, int reliable, int ignore)
 check_auth: Check user authorization from peer definition ---
static int check_osptoken (struct sip_pvt *p, char *token)
 check_osptoken: Validate OSP token for user authrroization ---
static void check_pendings (struct sip_pvt *p)
 check_pendings: Check pending actions on SIP call ---
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, int reliable, struct sockaddr_in *sin, int ignore)
 check_user: Find user ---
static int check_user_full (struct sip_pvt *p, struct sip_request *req, int sipmethod, char *uri, int reliable, struct sockaddr_in *sin, int ignore, char *mailbox, int mailboxlen)
 check_user_full: Check if matching user or peer is defined ---
static int check_via (struct sip_pvt *p, struct sip_request *req)
 check Via: header for hostname, port and rport request/answer
static int clear_realm_authentication (struct sip_auth *authlist)
 clear_realm_authentication: Clear realm authentication list (at reload) ---
static void clear_sip_domains (void)
 clear_sip_domains: Clear our domain list (at reload)
static char * complete_sip_debug_peer (char *line, char *word, int pos, int state)
 complete_sip_debug_peer: Support routine for 'sip debug peer' CLI ---
static char * complete_sip_peer (char *word, int state, int flags2)
 complete_sip_peer: Do completion on peer name ---
static char * complete_sip_prune_realtime_peer (char *line, char *word, int pos, int state)
 complete_sip_prune_realtime_peer: Support routine for 'sip prune realtime peer' CLI ---
static char * complete_sip_prune_realtime_user (char *line, char *word, int pos, int state)
 complete_sip_prune_realtime_user: Support routine for 'sip prune realtime user' CLI ---
static char * complete_sip_show_peer (char *line, char *word, int pos, int state)
 complete_sip_show_peer: Support routine for 'sip show peer' CLI ---
static char * complete_sip_show_user (char *line, char *word, int pos, int state)
 complete_sip_show_user: Support routine for 'sip show user' CLI ---
static char * complete_sip_user (char *word, int state, int flags2)
 complete_sip_user: Do completion on user name ---
static char * complete_sipch (char *line, char *word, int pos, int state)
 complete_sipch: Support routine for 'sip show channel' CLI ---
static char * complete_sipnotify (char *line, char *word, int pos, int state)
 complete_sipnotify: Support routine for 'sip notify' CLI ---
static int copy_all_header (struct sip_request *req, struct sip_request *orig, char *field)
 copy_all_header: Copy all headers from one request to another ---
static int copy_header (struct sip_request *req, struct sip_request *orig, char *field)
 copy_header: Copy one header field from one request to another
static void copy_request (struct sip_request *dst, struct sip_request *src)
 copy_request: copy SIP request (mostly used to save request for responses) ---
static int copy_via_headers (struct sip_pvt *p, struct sip_request *req, struct sip_request *orig, char *field)
 copy_via_headers: Copy SIP VIA Headers from the request to the response ---
static int create_addr (struct sip_pvt *dialog, char *opeer)
 create_addr: create address structure from peer 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 *r, struct sip_peer *peer)
 create_addr_from_peer: create address structure from peer reference ---
char * description ()
 Provides a description of the module.
static void destroy_association (struct sip_peer *peer)
static int determine_firstline_parts (struct sip_request *req)
 determine_firstline_parts: parse first line of incoming SIP request
static void * do_monitor (void *data)
 do_monitor: The SIP monitoring thread ---
static int do_proxy_auth (struct sip_pvt *p, struct sip_request *req, char *header, char *respheader, int sipmethod, int init)
 do_proxy_auth: Add authentication on outbound SIP packet ---
static int do_register_auth (struct sip_pvt *p, struct sip_request *req, char *header, char *respheader)
 do_register_auth: Authenticate for outbound registration ---
static const char * domain_mode_to_text (const enum domain_mode mode)
static const char * dtmfmode2str (int mode)
 dtmfmode2str: Convert DTMF mode to printable string ---
static int expire_register (void *data)
 expire_register: Expire registration of SIP peer ---
static void extract_uri (struct sip_pvt *p, struct sip_request *req)
 extract_uri: Check Contact: URI of SIP message ---
static char * find_alias (const char *name, char *_default)
static struct sip_pvtfind_call (struct sip_request *req, struct sockaddr_in *sin, const int intended_method)
 find_call: Connect incoming SIP message to current dialog or create new dialog structure
static struct sip_peerfind_peer (const char *peer, struct sockaddr_in *sin, int realtime)
 find_peer: Locate peer by name or ip address This is used on incoming SIP message to find matching peer on ip or outgoing message to find matching peer on name
static struct sip_authfind_realm_authentication (struct sip_auth *authlist, char *realm)
 find_realm_authentication: 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.
int find_sip_method (char *msg)
 find_sip_method: Find SIP method from header Strictly speaking, SIP methods are case SENSITIVE, but we don't check following Jon Postel's rule: Be gentle in what you accept, strict with what you send
static const struct cfsubscription_typesfind_subscription_type (enum subscriptiontype subtype)
 find_subscription_type: Find subscription type in array
static struct sip_userfind_user (const char *name, int realtime)
 find_user: Locate user by name Locates user by name (From: sip uri user name part) first from in-memory list (static configuration) then from realtime storage (defined in extconfig.conf)
static void free_old_route (struct sip_route *route)
 free_old_route: Remove route from route list ---
static char * func_check_sipdomain (struct ast_channel *chan, char *cmd, char *data, char *buf, size_t len)
 function_check_sipdomain: Dial plan function to check if domain is local
static char * func_header_read (struct ast_channel *chan, char *cmd, char *data, char *buf, size_t len)
 func_header_read: Read SIP header (dialplan function)
static char * function_sipchaninfo_read (struct ast_channel *chan, char *cmd, char *data, char *buf, size_t len)
 function_sipchaninfo_read: ${SIPCHANINFO()} Dialplan function - reads sip channel data
static char * function_sippeer (struct ast_channel *chan, char *cmd, char *data, char *buf, size_t len)
 function_sippeer: ${SIPPEER()} Dialplan function - reads peer data
static int get_also_info (struct sip_pvt *p, struct sip_request *oreq)
 get_also_info: Call transfer support (old way, depreciated)--
static char * get_body (struct sip_request *req, char *name)
 get_body: get a specific line from the message body
static char * get_body_by_line (char *line, char *name, int nameLen)
 get_body_by_line: Reads one line of message body
static char * get_calleridname (char *input, char *output, size_t outputsize)
 get_calleridname: Get caller id name from SIP headers ---
static int get_destination (struct sip_pvt *p, struct sip_request *oreq)
 get_destination: Find out who the call is for --
static char * get_header (struct sip_request *req, char *name)
 get_header: Get header from SIP request ---
static char * get_in_brackets (char *tmp)
 get_in_brackets: Pick out text in brackets from character string ---
static int get_msg_text (char *buf, int len, struct sip_request *req)
 get_msg_text: Get text out of a SIP MESSAGE packet ---
static int get_rdnis (struct sip_pvt *p, struct sip_request *oreq)
 get_rdnis: get referring dnis ---
static int get_refer_info (struct sip_pvt *sip_pvt, struct sip_request *outgoing_req)
 get_refer_info: Call transfer support (the REFER method) ---
static int get_rpid_num (char *input, char *output, int maxlen)
 get_rpid_num: 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 char * get_sdp (struct sip_request *req, char *name)
 get_sdp: get a specific line from the SDP
static char * get_sdp_iterate (int *iterator, struct sip_request *req, char *name)
static struct sip_pvtget_sip_pvt_byid_locked (char *callid)
 get_sip_pvt_byid_locked: Lock interface lock and find matching pvt lock ---
static char * gettag (struct sip_request *req, char *header, char *tagbuf, int tagbufsize)
 gettag: Get tag from packet
static int handle_common_options (struct ast_flags *flags, struct ast_flags *mask, struct ast_variable *v)
 handle_common_options: Handle flag-type options common to users and peers ---
static int handle_request (struct sip_pvt *p, struct sip_request *req, struct sockaddr_in *sin, int *recount, int *nounlock)
 handle_request: Handle SIP requests (methods) ---
static int handle_request_bye (struct sip_pvt *p, struct sip_request *req, int debug, int ignore)
 handle_request_bye: Handle incoming BYE request ---
static int handle_request_cancel (struct sip_pvt *p, struct sip_request *req, int debug, int ignore)
 handle_request_cancel: Handle incoming CANCEL request ---
static void handle_request_info (struct sip_pvt *p, struct sip_request *req)
 handle_request_info: Receive SIP INFO Message ---
static int handle_request_invite (struct sip_pvt *p, struct sip_request *req, int debug, int ignore, int seqno, struct sockaddr_in *sin, int *recount, char *e)
 handle_request_invite: Handle incoming INVITE request
static int handle_request_message (struct sip_pvt *p, struct sip_request *req, int debug, int ignore)
 handle_request_message: Handle incoming MESSAGE request ---
static int handle_request_options (struct sip_pvt *p, struct sip_request *req, int debug)
 handle_request_options: Handle incoming OPTIONS request
static int handle_request_refer (struct sip_pvt *p, struct sip_request *req, int debug, int ignore, int seqno, int *nounlock)
 handle_request_refer: Handle incoming REFER request ---
static int handle_request_register (struct sip_pvt *p, struct sip_request *req, int debug, int ignore, struct sockaddr_in *sin, char *e)
 handle_request_register: Handle incoming REGISTER request ---
static int handle_request_subscribe (struct sip_pvt *p, struct sip_request *req, int debug, int ignore, struct sockaddr_in *sin, int seqno, char *e)
 handle_request_subscribe: Handle incoming SUBSCRIBE request ---
static void handle_response (struct sip_pvt *p, int resp, char *rest, struct sip_request *req, int ignore, int seqno)
 handle_response: Handle SIP response in dialogue ---
static void handle_response_invite (struct sip_pvt *p, int resp, char *rest, struct sip_request *req, int ignore, int seqno)
 handle_response_invite: Handle SIP response in dialogue ---
static int handle_response_peerpoke (struct sip_pvt *p, int resp, char *rest, struct sip_request *req, int ignore, int seqno, int sipmethod)
 handle_response_peerpoke: Handle qualification responses (OPTIONS)
static int handle_response_register (struct sip_pvt *p, int resp, char *rest, struct sip_request *req, int ignore, int seqno)
 handle_response_register: Handle responses on REGISTER to services ---
static char * hangup_cause2sip (int cause)
 hangup_cause2sip: Convert Asterisk hangup causes to SIP codes
static int hangup_sip2cause (int cause)
 hangup_sip2cause: Convert SIP hangup causes to Asterisk hangup causes ---
static int init_req (struct sip_request *req, int sipmethod, char *recip)
 init_req: Initialize SIP request ---
static int init_resp (struct sip_request *req, char *resp, struct sip_request *orig)
 init_resp: Initialize SIP response, based on SIP request ---
static void initreqprep (struct sip_request *req, struct sip_pvt *p, int sipmethod)
 initreqprep: Initiate new SIP request to peer/user ---
static const char * insecure2str (int port, int invite)
 insecure2str: Convert Insecure setting to printable string ---
char * key ()
 Returns the ASTERISK_GPL_KEY.
static void list_route (struct sip_route *route)
 list_route: List all routes - mostly for debugging ---
int load_module ()
 Initialize the module.
static int lws2sws (char *msgbuf, int len)
 lws2sws: Parse multiline SIP headers into one header
static void make_our_tag (char *tagbuf, size_t len)
static int manager_sip_show_peer (struct mansession *s, struct message *m)
 manager_sip_show_peer: Show SIP peers in the manager API ---
static int manager_sip_show_peers (struct mansession *s, struct message *m)
 manager_sip_show_peers: Show SIP peers in the manager API ---
static char * nat2str (int nat)
 nat2str: Convert NAT setting to text string
static void parse_copy (struct sip_request *dst, struct sip_request *src)
 parse_copy: Copy SIP request, parse it
static void parse_moved_contact (struct sip_pvt *p, struct sip_request *req)
 parse_moved_contact: Parse 302 Moved temporalily response
static int parse_ok_contact (struct sip_pvt *pvt, struct sip_request *req)
 parse_ok_contact: Parse contact header for 200 OK on INVITE ---
static enum parse_register_result parse_register_contact (struct sip_pvt *pvt, struct sip_peer *p, struct sip_request *req)
 parse_register_contact: Parse contact header and save registration ---
static void parse_request (struct sip_request *req)
 parse_request: Parse a SIP message ----
unsigned int parse_sip_options (struct sip_pvt *pvt, char *supported)
 parse_sip_options: Parse supported header in incoming packet
static int peer_status (struct sip_peer *peer, char *status, int statuslen)
 peer_status: Report Peer status in character string
static void print_codec_to_cli (int fd, struct ast_codec_pref *pref)
 print_codec_to_cli: Print codec list from preference to CLI/manager
static void print_group (int fd, unsigned int group, int crlf)
 print_group: Print call group and pickup group ---
static int process_sdp (struct sip_pvt *p, struct sip_request *req)
 process_sdp: Process SIP SDP and activate RTP channels---
static struct sip_peerrealtime_peer (const char *peername, struct sockaddr_in *sin)
 realtime_peer: Get peer from realtime storage Checks the "sippeers" realtime family from extconfig.conf
static void realtime_update_peer (const char *peername, struct sockaddr_in *sin, const char *username, const char *fullcontact, int expirey)
 realtime_update_peer: Update peer object in realtime storage ---
static struct sip_userrealtime_user (const char *username)
 realtime_user: Load user from realtime storage Loads user from "sipusers" category in realtime (extconfig.conf) Users are matched on From: user name (the domain in skipped)
static void receive_message (struct sip_pvt *p, struct sip_request *req)
 receive_message: Receive SIP MESSAGE method messages ---
static void reg_source_db (struct sip_peer *peer)
 reg_source_db: Get registration details from Asterisk DB ---
static void register_peer_exten (struct sip_peer *peer, int onoff)
 register_peer_exten: Automatically add peer extension to dial plan ---
static int register_verify (struct sip_pvt *p, struct sockaddr_in *sin, struct sip_request *req, char *uri, int ignore)
 register_verify: Verify registration of user
static char * regstate2str (int regstate)
int reload (void)
 Reload stuff.
static int reload_config (void)
 reload_config: Re-read SIP.conf config file ---
static int reply_digest (struct sip_pvt *p, struct sip_request *req, char *header, int sipmethod, char *digest, int digest_len)
 reply_digest: reply to authentication for outbound registrations ---
static int reqprep (struct sip_request *req, struct sip_pvt *p, int sipmethod, int seqno, int newbranch)
 reqprep: Initialize a SIP request response packet ---
static int respprep (struct sip_request *resp, struct sip_pvt *p, char *msg, struct sip_request *req)
 respprep: Prepare SIP response packet ---
static int restart_monitor (void)
 restart_monitor: Start the channel monitor thread ---
static int retrans_pkt (void *data)
 retrans_pkt: Retransmit SIP message if no answer ---
static void sdpLineNum_iterator_init (int *iterator, struct sip_request *req)
static int send_request (struct sip_pvt *p, struct sip_request *req, int reliable, int seqno)
 send_request: Send SIP Request to the other part of the dialogue ---
static int send_response (struct sip_pvt *p, struct sip_request *req, int reliable, int seqno)
 send_response: Transmit response on SIP request---
static void set_destination (struct sip_pvt *p, char *uri)
 set_destination: Set destination from SIP URI ---
static int sip_addheader (struct ast_channel *chan, void *data)
 sip_addheader: Add a SIP header ---
static int sip_addrcmp (char *name, struct sockaddr_in *sin)
 sip_addrcmp: Support routine for find_peer ---
static struct sip_pvtsip_alloc (char *callid, struct sockaddr_in *sin, int useglobal_nat, const int intended_method)
 sip_alloc: Allocate SIP_PVT structure and set defaults ---
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)
 sip_call: Initiate SIP call from PBX used from the dial() application
static int sip_cancel_destroy (struct sip_pvt *p)
 sip_cancel_destroy: Cancel destruction of SIP call ---
static int sip_debug_test_addr (struct sockaddr_in *addr)
 sip_debug_test_addr: See if we pass debug IP filter
static int sip_debug_test_pvt (struct sip_pvt *p)
 sip_debug_test_pvt: Test PVT for debugging output
static void sip_destroy (struct sip_pvt *p)
 sip_destroy: Destroy SIP call structure ---
static void sip_destroy_peer (struct sip_peer *peer)
 sip_destroy_peer: Destroy peer object from memory
static void sip_destroy_user (struct sip_user *user)
 sip_destroy_user: Remove user object from in-memory storage ---
static int sip_devicestate (void *data)
 sip_devicestate: Part of PBX channel interface ---
static int sip_do_debug (int fd, int argc, char *argv[])
 sip_do_debug: Turn on SIP debugging (CLI command)
static int sip_do_debug_ip (int fd, int argc, char *argv[])
 sip_do_debug: Enable SIP Debugging in CLI ---
static int sip_do_debug_peer (int fd, int argc, char *argv[])
 sip_do_debug_peer: Turn on SIP debugging with peer mask
static int sip_do_history (int fd, int argc, char *argv[])
 sip_do_history: Enable SIP History logging (CLI) ---
static int sip_do_reload (void)
 sip_do_reload: Reload module
static int sip_dtmfmode (struct ast_channel *chan, void *data)
 sip_dtmfmode: change the DTMFmode for a SIP call (application) ---
static void sip_dump_history (struct sip_pvt *dialog)
 dump_history: 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 int sip_get_codec (struct ast_channel *chan)
 sip_get_codec: Return SIP UA's codec (part of the RTP interface) ---
static struct ast_rtpsip_get_rtp_peer (struct ast_channel *chan)
 sip_get_rtp_peer: Returns null if we can't reinvite (part of RTP interface)
static struct ast_rtpsip_get_vrtp_peer (struct ast_channel *chan)
 sip_get_vrtp_peer: Returns null if we can't reinvite video (part of RTP interface)
static int sip_getheader (struct ast_channel *chan, void *data)
 sip_getheader: Get a SIP header (dialplan app) ---
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)
 sip_indicate: 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 struct ast_channelsip_new (struct sip_pvt *i, int state, char *title)
 sip_new: Initiate a call in the SIP channel
static int sip_no_debug (int fd, int argc, char *argv[])
 sip_no_debug: Disable SIP Debugging in CLI ---
static int sip_no_history (int fd, int argc, char *argv[])
 sip_no_history: Disable SIP History logging (CLI) ---
static int sip_notify (int fd, int argc, char *argv[])
 sip_notify: Send SIP notify to peer
static int sip_park (struct ast_channel *chan1, struct ast_channel *chan2, struct sip_request *req)
 sip_park: Park a call ---
static void * sip_park_thread (void *stuff)
 sip_park_thread: Park SIP call support function
static void sip_poke_all_peers (void)
 sip_poke_all_peers: Send a poke to all known peers
static int sip_poke_noanswer (void *data)
 sip_poke_noanswer: No answer to Qualify poke ---
static int sip_poke_peer (struct sip_peer *peer)
 sip_poke_peer: Check availability of peer, also keep NAT open ---
static int sip_poke_peer_s (void *data)
static int sip_prune_realtime (int fd, int argc, char *argv[])
 sip_prune_realtime: Remove temporary realtime objects from memory (CLI) ---
static struct ast_framesip_read (struct ast_channel *ast)
 sip_read: Read SIP RTP from channel
static int sip_reg_timeout (void *data)
 sip_reg_timeout: Registration timeout, register again
static int sip_register (char *value, int lineno)
 sip_register: Parse register=> line in sip.conf and add to registry
static void sip_registry_destroy (struct sip_registry *reg)
 sip_registry_destroy: Destroy registry object ---
static int sip_reload (int fd, int argc, char *argv[])
 sip_reload: Force reload of module from cli ---
static struct ast_channelsip_request_call (const char *type, int format, void *data, int *cause)
 sip_request: PBX interface function -build SIP pvt structure ---
static int sip_reregister (void *data)
 sip_reregister: Update registration with SIP Proxy---
static struct ast_framesip_rtp_read (struct ast_channel *ast, struct sip_pvt *p)
 sip_rtp_read: Read RTP from network ---
static int sip_scheddestroy (struct sip_pvt *p, int ms)
 sip_scheddestroy: Schedule destruction of SIP call ---
static void sip_send_all_registers (void)
 sip_send_all_registers: Send all known registrations
static int sip_send_mwi_to_peer (struct sip_peer *peer)
 sip_send_mwi_to_peer: Send message waiting indication ---
static int sip_senddigit (struct ast_channel *ast, char digit)
 sip_senddigit: Send DTMF character on SIP channel
static int sip_sendtext (struct ast_channel *ast, const char *text)
 sip_sendtext: Send SIP MESSAGE text within a call ---
static int sip_set_rtp_peer (struct ast_channel *chan, struct ast_rtp *rtp, struct ast_rtp *vrtp, int codecs, int nat_active)
 sip_set_rtp_peer: Set the RTP peer for this call ---
static int sip_show_channel (int fd, int argc, char *argv[])
 sip_show_channel: Show details of one call ---
static int sip_show_channels (int fd, int argc, char *argv[])
 sip_show_channels: Show active SIP channels ---
static int sip_show_domains (int fd, int argc, char *argv[])
static int sip_show_history (int fd, int argc, char *argv[])
 sip_show_history: Show history details of one call ---
static int sip_show_inuse (int fd, int argc, char *argv[])
 sip_show_inuse: CLI Command to show calls within limits set by call_limit ---
static int sip_show_objects (int fd, int argc, char *argv[])
 sip_show_objects: List all allocated SIP Objects ---
static int sip_show_peer (int fd, int argc, char *argv[])
 sip_show_peer: Show one peer in detail ---
static int sip_show_peers (int fd, int argc, char *argv[])
 sip_show_peers: CLI Show Peers command
static int sip_show_registry (int fd, int argc, char *argv[])
 sip_show_registry: Show SIP Registry (registrations with other SIP proxies ---
static int sip_show_settings (int fd, int argc, char *argv[])
 sip_show_settings: List global settings for the SIP channel ---
static int sip_show_subscriptions (int fd, int argc, char *argv[])
 sip_show_subscriptions: Show active SIP subscriptions ---
static int sip_show_user (int fd, int argc, char *argv[])
 sip_show_user: Show one user in detail ---
static int sip_show_users (int fd, int argc, char *argv[])
 sip_show_users: CLI Command 'SIP Show Users' ---
static int sip_sipredirect (struct sip_pvt *p, const char *dest)
 sip_sipredirect: Transfer call before connect with a 302 redirect ---
static int sip_transfer (struct ast_channel *ast, const char *dest)
 sip_transfer: Transfer SIP call
static int sip_write (struct ast_channel *ast, struct ast_frame *frame)
 sip_write: Send frame to media channel (rtp) ---
static int sipsock_read (int *id, int fd, short events, void *ignore)
 sipsock_read: Read data from SIP socket ---
static const char * subscription_type2str (enum subscriptiontype subtype)
 subscription_type2str: Show subscription type in string format
static struct sip_peertemp_peer (const char *name)
 temp_peer: Create temporary peer (used in autocreatepeer mode) ---
static force_inline int thread_safe_rand (void)
 Thread-safe random number generator.
static void transmit_fake_auth_response (struct sip_pvt *p, struct sip_request *req, char *randdata, int randlen, int reliable)
 Send a fake 401 Unauthorized response when the administrator wants to hide the names of local users/peers from fishers.
static int transmit_info_with_digit (struct sip_pvt *p, char digit)
 transmit_info_with_digit: Send SIP INFO dtmf message, see Cisco documentation on cisco.co m ---
static int transmit_info_with_vidupdate (struct sip_pvt *p)
 transmit_info_with_vidupdate: Send SIP INFO with video update request ---
static int transmit_invite (struct sip_pvt *p, int sipmethod, int sendsdp, int init)
 transmit_invite: Build REFER/INVITE/OPTIONS message and transmit it ---
static int transmit_message_with_text (struct sip_pvt *p, const char *text)
 transmit_message_with_text: Transmit text with SIP MESSAGE method ---
static int transmit_notify_with_mwi (struct sip_pvt *p, int newmsgs, int oldmsgs, char *vmexten)
 transmit_notify_with_mwi: Notify user of messages waiting in voicemail ---
static int transmit_notify_with_sipfrag (struct sip_pvt *p, int cseq)
 transmit_notify_with_sipfrag: Notify a transferring party of the status of trasnfer ---
static int transmit_refer (struct sip_pvt *p, const char *dest)
 transmit_refer: Transmit SIP REFER message ---
static int transmit_register (struct sip_registry *r, int sipmethod, char *auth, char *authheader)
 transmit_register: Transmit register to SIP proxy or UA ---
static int transmit_reinvite_with_sdp (struct sip_pvt *p)
 transmit_reinvite_with_sdp: Transmit reinvite with SDP :-) ---
static int transmit_request (struct sip_pvt *p, int sipmethod, int inc, int reliable, int newbranch)
 transmit_request: transmit generic SIP request ---
static int transmit_request_with_auth (struct sip_pvt *p, int sipmethod, int inc, int reliable, int newbranch)
 transmit_request_with_auth: Transmit SIP request, auth added ---
static int transmit_response (struct sip_pvt *p, char *msg, struct sip_request *req)
 transmit_response: Transmit response, no retransmits
static int transmit_response_reliable (struct sip_pvt *p, char *msg, struct sip_request *req, int fatal)
 transmit_response_reliable: Transmit response, Make sure you get a reply
static int transmit_response_with_allow (struct sip_pvt *p, char *msg, struct sip_request *req, int reliable)
 transmit_response_with_allow: Append Accept header, content length before transmitting response ---
static int transmit_response_with_auth (struct sip_pvt *p, char *msg, struct sip_request *req, char *rand, int reliable, char *header, int stale)
static int transmit_response_with_date (struct sip_pvt *p, char *msg, struct sip_request *req)
 transmit_response_with_date: Append date and content length before transmitting response ---
static int transmit_response_with_sdp (struct sip_pvt *p, char *msg, struct sip_request *req, int retrans)
 transmit_response_with_sdp: Used for 200 OK and 183 early media ---
static int transmit_response_with_unsupported (struct sip_pvt *p, char *msg, struct sip_request *req, char *unsupported)
 transmit_response_with_unsupported: Transmit response, no retransmits
static int transmit_sip_request (struct sip_pvt *p, struct sip_request *req)
 transmit_sip_request: Transmit SIP request
static int transmit_state_notify (struct sip_pvt *p, int state, int full, int substate)
 transmit_state_notify: Used in the SUBSCRIBE notification subsystem ----
static void try_suggested_sip_codec (struct sip_pvt *p)
 Try setting codec suggested by the SIP_CODEC channel variable.
int unload_module ()
 Cleanup all module structures, sockets, etc.
static int update_call_counter (struct sip_pvt *fup, int event)
 update_call_counter: Handle call_limit for SIP users Note: This is going to be replaced by app_groupcount Thought: For realtime, we should propably update storage with inuse counter...
static void update_peer (struct sip_peer *p, int expiry)
 update_peer: Update peer data in database (if used) ---
int usecount ()
 Provides a usecount.

Variables

static struct in_addr __ourip
static const struct cfalias aliases []
 Structure for conversion between compressed SIP and "normal" SIP.
int allow_external_domains
static int apeerobjs = 0
static char * app_dtmfmode = "SIPDtmfMode"
static char * app_sipaddheader = "SIPAddHeader"
static char * app_sipgetheader = "SIPGetHeader"
static struct sip_authauthl
static int autocreatepeer = 0
static struct sockaddr_in bindaddr = { 0, }
static int callevents = 0
static const char channeltype [] = "SIP"
static struct ast_custom_function checksipdomain_function
static int compactheaders = 0
static const char config [] = "sip.conf"
static char debug_usage []
static struct sockaddr_in debugaddr
static char default_callerid [AST_MAX_EXTENSION] = DEFAULT_CALLERID
static char default_context [AST_MAX_CONTEXT] = DEFAULT_CONTEXT
static int default_expiry = DEFAULT_DEFAULT_EXPIRY
static char default_fromdomain [AST_MAX_EXTENSION] = ""
static char default_language [MAX_LANGUAGE] = ""
static char default_notifymime [AST_MAX_EXTENSION] = DEFAULT_NOTIFYMIME
static int default_qualify = 0
static char default_subscribecontext [AST_MAX_CONTEXT]
static char default_useragent [AST_MAX_EXTENSION] = DEFAULT_USERAGENT
static const char desc [] = "Session Initiation Protocol (SIP)"
static char * descrip_dtmfmode = "SIPDtmfMode(inband|info|rfc2833): Changes the dtmfmode for a SIP call\n"
static char * descrip_sipaddheader
static char * descrip_sipgetheader
static int dumphistory = 0
static int expiry = DEFAULT_EXPIRY
static time_t externexpire = 0
static char externhost [MAXHOSTNAMELEN] = ""
static struct sockaddr_in externip
static int externrefresh = 10
static int global_allowguest = 1
static int global_alwaysauthreject = 0
static int global_capability = AST_FORMAT_ULAW | AST_FORMAT_ALAW | AST_FORMAT_GSM | AST_FORMAT_H263
 Codecs that we support by default:.
static struct ast_flags global_flags = {0}
static struct ast_flags global_flags_page2 = {0}
static char global_musicclass [MAX_MUSICCLASS] = ""
static int global_mwitime = DEFAULT_MWITIME
static int global_notifyringing = 1
static char global_realm [MAXHOSTNAMELEN] = DEFAULT_REALM
static int global_reg_timeout = DEFAULT_REGISTRATION_TIMEOUT
static int global_regattempts_max = 0
static int global_rtautoclear
static int global_rtpholdtimeout = 0
static int global_rtpkeepalive = 0
static int global_rtptimeout = 0
static char global_vmexten [AST_MAX_EXTENSION] = DEFAULT_VMEXTEN
static char history_usage []
static struct sip_pvtiflist
 sip_pvt: PVT structures are used for each SIP conversation, ie. a call
static struct io_contextio
static struct ast_halocaladdr
static char mandescr_show_peer []
static char mandescr_show_peers []
static int max_expiry = DEFAULT_MAX_EXPIRY
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 struct ast_cli_entry my_clis []
static char no_debug_usage []
static char no_history_usage []
static int noncodeccapability = AST_RTP_DTMF
static const char notify_config [] = "sip_notify.conf"
ast_confignotify_types
static char notify_usage []
static int ourport
static struct sockaddr_in outboundproxyip
static int pedanticsipchecking = 0
static struct ast_peer_list peerl
 The peer list: Peers and Friends ---.
static struct ast_codec_pref prefs
static char prune_realtime_usage []
static int recordhistory = 0
static char regcontext [AST_MAX_CONTEXT] = ""
static struct ast_register_list regl
 The register list: Other SIP proxys we register with and call ---.
static int regobjs = 0
static int relaxdtmf = 0
static int rpeerobjs = 0
static int ruserobjs = 0
static struct sched_contextsched
static char show_channel_usage []
static char show_channels_usage []
static char show_domains_usage []
static char show_history_usage []
static char show_inuse_usage []
static char show_objects_usage []
static char show_peer_usage []
static char show_peers_usage []
static char show_reg_usage []
static char show_settings_usage []
static char show_subscriptions_usage []
static char show_user_usage []
static char show_users_usage []
static struct ast_custom_function sip_header_function
enum sipmethod sip_method_list
static const struct cfsip_methods sip_methods []
static const 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 char sip_reload_usage []
static int sip_reloading = 0
static struct ast_rtp_protocol sip_rtp
 sip_rtp: Interface structure with callbacks used to connect to rtp module --
static const struct ast_channel_tech sip_tech
 Definition of this channel for PBX channel registration.
static struct ast_custom_function sipchaninfo_function
static int sipdebug = 0
ast_custom_function sippeer_function
static int sipsock = -1
static int speerobjs = 0
static int srvlookup = 0
static const struct cfsubscription_types subscription_types []
static int suserobjs = 0
static char * synopsis_dtmfmode = "Change the dtmfmode for a SIP call"
static char * synopsis_sipaddheader = "Add a SIP header to the outbound call"
static char * synopsis_sipgetheader = "Get a SIP header from an incoming call"
static int tos = 0
static int usecnt = 0
static struct ast_user_list userl
 The user list: Users and friends ---.
static int videosupport = 0


Detailed Description

Implementation of Session Initiation Protocol.

Implementation of RFC 3261 - without S/MIME, TCP and TLS support Configuration file sip.conf

Todo:
SIP over TCP

SIP over TLS

Better support of forking

Definition in file chan_sip.c.


Define Documentation

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

SIP Methods we support.

Definition at line 323 of file chan_sip.c.

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

#define CALLERID_UNKNOWN   "Unknown"
 

Definition at line 127 of file chan_sip.c.

Referenced by initreqprep().

#define DEBUG_READ   0
 

Definition at line 141 of file chan_sip.c.

Referenced by ael_debug_read(), and ast_ael_compile().

#define DEBUG_SEND   1
 

Definition at line 142 of file chan_sip.c.

#define DEC_CALL_LIMIT   0
 

Definition at line 445 of file chan_sip.c.

Referenced by handle_request_invite(), handle_response(), sip_hangup(), and update_call_counter().

#define DEFAULT_CALLERID   "asterisk"
 

Definition at line 342 of file chan_sip.c.

Referenced by reload_config().

#define DEFAULT_CONTEXT   "default"
 

Definition at line 333 of file chan_sip.c.

Referenced by reload_config().

#define DEFAULT_DEFAULT_EXPIRY   120
 

Definition at line 101 of file chan_sip.c.

Referenced by reload_config().

#define DEFAULT_EXPIRY   900
 

Expire slowly

Definition at line 436 of file chan_sip.c.

#define DEFAULT_FREQ_NOTOK   10 * 1000
 

Definition at line 133 of file chan_sip.c.

#define DEFAULT_FREQ_OK   60 * 1000
 

Definition at line 132 of file chan_sip.c.

#define DEFAULT_MAX_EXPIRY   3600
 

Definition at line 102 of file chan_sip.c.

Referenced by reload_config().

#define DEFAULT_MAX_FORWARDS   "70"
 

Definition at line 104 of file chan_sip.c.

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

#define DEFAULT_MAXMS   2000
 

Definition at line 131 of file chan_sip.c.

#define DEFAULT_MWITIME   10
 

Definition at line 386 of file chan_sip.c.

Referenced by reload_config().

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

Definition at line 347 of file chan_sip.c.

Referenced by reload_config().

#define DEFAULT_REALM   "asterisk"
 

Definition at line 432 of file chan_sip.c.

Referenced by reload_config().

#define DEFAULT_REGISTRATION_TIMEOUT   20
 

Definition at line 103 of file chan_sip.c.

Referenced by reload_config().

#define DEFAULT_RETRANS   1000
 

Definition at line 135 of file chan_sip.c.

#define DEFAULT_SIP_PORT   5060
 

From RFC 3261 (former 2543)

Definition at line 328 of file chan_sip.c.

Referenced by build_peer(), check_via(), create_addr(), parse_ok_contact(), parse_register_contact(), reload_config(), set_destination(), sip_show_registry(), and temp_peer().

#define DEFAULT_USERAGENT   "Asterisk PBX"
 

Definition at line 90 of file chan_sip.c.

Referenced by reload_config().

#define DEFAULT_VMEXTEN   "asterisk"
 

Definition at line 337 of file chan_sip.c.

Referenced by reload_config().

#define EXPIRY_GUARD_LIMIT   30
 

Definition at line 109 of file chan_sip.c.

Referenced by handle_response_register().

#define EXPIRY_GUARD_MIN   500
 

Definition at line 111 of file chan_sip.c.

Referenced by handle_response_register().

#define EXPIRY_GUARD_PCT   0.20
 

Definition at line 115 of file chan_sip.c.

Referenced by handle_response_register().

#define EXPIRY_GUARD_SECS   15
 

Definition at line 108 of file chan_sip.c.

Referenced by handle_response_register().

#define FLAG_FATAL   (1 << 1)
 

Definition at line 703 of file chan_sip.c.

Referenced by __sip_reliable_xmit(), and retrans_pkt().

#define FLAG_RESPONSE   (1 << 0)
 

Definition at line 702 of file chan_sip.c.

Referenced by __sip_ack(), __sip_pretend_ack(), __sip_semi_ack(), handle_request(), and retrans_pkt().

#define INC_CALL_LIMIT   1
 

Definition at line 446 of file chan_sip.c.

Referenced by handle_request_invite(), sip_call(), sip_hangup(), and update_call_counter().

#define IPTOS_MINCOST   0x02
 

Definition at line 95 of file chan_sip.c.

#define MAX a,
 )     ((a) > (b) ? (a) : (b))
 

Definition at line 124 of file chan_sip.c.

#define MAX_AUTHTRIES   3
 

Definition at line 138 of file chan_sip.c.

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

#define MAX_RETRANS   6
 

Definition at line 137 of file chan_sip.c.

#define NO_RTP   0
 

Definition at line 150 of file chan_sip.c.

#define NOT_SUPPORTED   0
 

Definition at line 267 of file chan_sip.c.

#define REG_STATE_AUTHSENT   2
 

Definition at line 811 of file chan_sip.c.

Referenced by registry_rerequest(), regstate2str(), and transmit_register().

#define REG_STATE_FAILED   7
 

Definition at line 816 of file chan_sip.c.

Referenced by regstate2str(), and sip_reg_timeout().

#define REG_STATE_NOAUTH   6
 

Definition at line 815 of file chan_sip.c.

Referenced by registry_rerequest(), and regstate2str().

#define REG_STATE_REGISTERED   3
 

Definition at line 812 of file chan_sip.c.

Referenced by handle_response_register(), iax2_ack_registry(), and regstate2str().

#define REG_STATE_REGSENT   1
 

Definition at line 810 of file chan_sip.c.

Referenced by iax2_do_register(), regstate2str(), and transmit_register().

#define REG_STATE_REJECTED   4
 

Definition at line 813 of file chan_sip.c.

Referenced by regstate2str(), and socket_read().

#define REG_STATE_TIMEOUT   5
 

Definition at line 814 of file chan_sip.c.

Referenced by attempt_transmit(), and regstate2str().

#define REG_STATE_UNREGISTERED   0
 

Definition at line 809 of file chan_sip.c.

Referenced by regstate2str(), and sip_reg_timeout().

#define RTP   1
 

Definition at line 149 of file chan_sip.c.

#define SIP_ALREADYGONE   (1 << 0)
 

Whether or not we've already been destroyed by our peer

Definition at line 518 of file chan_sip.c.

Referenced by handle_request(), handle_request_bye(), handle_request_cancel(), handle_request_invite(), handle_request_refer(), handle_response(), handle_response_invite(), retrans_pkt(), sip_hangup(), sip_indicate(), and sip_sipredirect().

#define SIP_CALL_LIMIT   (1 << 29)
 

Definition at line 566 of file chan_sip.c.

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

#define SIP_CALL_ONHOLD   (1 << 28)
 

Definition at line 565 of file chan_sip.c.

Referenced by __sip_show_channels(), and process_sdp().

#define SIP_CAN_BYE   (1 << 15)
 

Can we send BYE for this dialog?

Definition at line 533 of file chan_sip.c.

Referenced by check_pendings(), handle_response_invite(), and sip_hangup().

#define SIP_CAN_REINVITE   (1 << 20)
 

allow peers to be reinvited to send media directly p2p

Definition at line 548 of file chan_sip.c.

Referenced by _sip_show_peer(), handle_common_options(), reload_config(), sip_get_rtp_peer(), and sip_get_vrtp_peer().

#define SIP_DEBUG_CONFIG   1 << 0
 

Definition at line 417 of file chan_sip.c.

Referenced by reload_config().

#define SIP_DEBUG_CONSOLE   1 << 1
 

Definition at line 418 of file chan_sip.c.

Referenced by sip_do_debug(), sip_do_debug_ip(), sip_do_debug_peer(), and sip_no_debug().

#define SIP_DTMF   (3 << 16)
 

three settings, uses two bits

Definition at line 535 of file chan_sip.c.

Referenced by _sip_show_peer(), check_user_full(), create_addr_from_peer(), handle_common_options(), process_sdp(), sip_alloc(), sip_dtmfmode(), sip_new(), sip_rtp_read(), sip_senddigit(), sip_show_channel(), and sip_show_settings().

#define SIP_DTMF_AUTO   (3 << 16)
 

AUTO switch between rfc2833 and in-band DTMF

Definition at line 539 of file chan_sip.c.

Referenced by check_user_full(), create_addr_from_peer(), dtmfmode2str(), handle_common_options(), process_sdp(), and sip_alloc().

#define SIP_DTMF_INBAND   (1 << 16)
 

Inband audio, only for ULAW/ALAW

Definition at line 537 of file chan_sip.c.

Referenced by dtmfmode2str(), handle_common_options(), process_sdp(), sip_dtmfmode(), sip_new(), sip_rtp_read(), and sip_senddigit().

#define SIP_DTMF_INFO   (2 << 16)
 

SIP Info messages

Definition at line 538 of file chan_sip.c.

Referenced by dtmfmode2str(), handle_common_options(), sip_dtmfmode(), and sip_senddigit().

#define SIP_DTMF_RFC2833   (0 << 16)
 

RTP DTMF

Definition at line 536 of file chan_sip.c.

Referenced by check_user_full(), create_addr_from_peer(), dtmfmode2str(), handle_common_options(), process_sdp(), reload_config(), sip_alloc(), sip_dtmfmode(), sip_rtp_read(), and sip_senddigit().

#define SIP_FLAGS_TO_COPY
 

Value:

Definition at line 572 of file chan_sip.c.

Referenced by build_peer(), build_user(), check_user_full(), create_addr_from_peer(), sip_alloc(), sip_poke_peer(), and temp_peer().

#define SIP_GOTREFER   (1 << 7)
 

Got a refer?

Definition at line 525 of file chan_sip.c.

Referenced by handle_request_refer(), and sip_set_rtp_peer().

#define SIP_INC_COUNT   (1 << 31)
 

Definition at line 570 of file chan_sip.c.

Referenced by update_call_counter().

#define SIP_INSECURE_INVITE   (1 << 23)
 

don't require authentication for incoming INVITEs

Definition at line 552 of file chan_sip.c.

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

#define SIP_INSECURE_PORT   (1 << 22)
 

don't require matching port for incoming requests

Definition at line 551 of file chan_sip.c.

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

#define SIP_LEN_CONTACT   256
 

Definition at line 118 of file chan_sip.c.

Referenced by parse_ok_contact(), and respprep().

#define SIP_MAX_HEADERS   64
 

Max amount of SIP headers to read

Definition at line 442 of file chan_sip.c.

Referenced by add_blank_header(), add_header(), and parse_request().

#define SIP_MAX_LINES   64
 

Max amount of lines in SIP attachment (like SDP)

Definition at line 443 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 329 of file chan_sip.c.

#define SIP_NAT   (3 << 18)
 

four settings, uses two bits

Definition at line 541 of file chan_sip.c.

Referenced by __sip_xmit(), _sip_show_peer(), build_via(), check_user_full(), check_via(), copy_via_headers(), create_addr_from_peer(), handle_common_options(), parse_ok_contact(), parse_register_contact(), register_verify(), retrans_pkt(), send_request(), send_response(), sip_alloc(), sip_debug_test_pvt(), sip_show_channel(), sip_show_settings(), and sip_show_users().

#define SIP_NAT_ALWAYS   (3 << 18)
 

Definition at line 545 of file chan_sip.c.

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

#define SIP_NAT_NEVER   (0 << 18)
 

No nat support

Definition at line 542 of file chan_sip.c.

Referenced by handle_common_options(), and nat2str().

#define SIP_NAT_RFC3581   (1 << 18)
 

Definition at line 543 of file chan_sip.c.

Referenced by build_via(), handle_common_options(), nat2str(), and reload_config().

#define SIP_NAT_ROUTE   (2 << 18)
 

Definition at line 544 of file chan_sip.c.

Referenced by __sip_xmit(), check_user_full(), check_via(), create_addr_from_peer(), nat2str(), parse_ok_contact(), parse_register_contact(), retrans_pkt(), send_request(), send_response(), sip_alloc(), and sip_debug_test_pvt().

#define SIP_NEEDDESTROY   (1 << 1)
 

if we need to be destroyed

Definition at line 519 of file chan_sip.c.

Referenced by __sip_show_channels(), check_pendings(), do_monitor(), handle_request(), handle_request_bye(), handle_request_cancel(), handle_request_info(), handle_request_invite(), handle_request_options(), handle_request_subscribe(), handle_response(), handle_response_invite(), handle_response_peerpoke(), handle_response_register(), receive_message(), retrans_pkt(), sip_hangup(), sip_reg_timeout(), and sip_show_channel().

#define SIP_NEEDREINVITE   (1 << 5)
 

Do we need to send another reinvite?

Definition at line 523 of file chan_sip.c.

Referenced by check_pendings(), sip_hangup(), and sip_set_rtp_peer().

#define SIP_NOVIDEO   (1 << 2)
 

Didn't get video in invite, don't offer

Definition at line 520 of file chan_sip.c.

Referenced by add_sdp(), process_sdp(), and sip_indicate().

#define SIP_OPT_100REL   (1 << 1)
 

Definition at line 270 of file chan_sip.c.

#define SIP_OPT_EARLY_SESSION   (1 << 3)
 

Definition at line 272 of file chan_sip.c.

#define SIP_OPT_EVENTLIST   (1 << 11)
 

Definition at line 280 of file chan_sip.c.

#define SIP_OPT_GRUU   (1 << 12)
 

Definition at line 281 of file chan_sip.c.

#define SIP_OPT_JOIN   (1 << 4)
 

Definition at line 273 of file chan_sip.c.

#define SIP_OPT_PATH   (1 << 5)
 

Definition at line 274 of file chan_sip.c.

#define SIP_OPT_PRECONDITION   (1 << 7)
 

Definition at line 276 of file chan_sip.c.

#define SIP_OPT_PREF   (1 << 6)
 

Definition at line 275 of file chan_sip.c.

#define SIP_OPT_PRIVACY   (1 << 8)
 

Definition at line 277 of file chan_sip.c.

#define SIP_OPT_REPLACES   (1 << 0)
 

Definition at line 269 of file chan_sip.c.

#define SIP_OPT_SDP_ANAT   (1 << 9)
 

Definition at line 278 of file chan_sip.c.

#define SIP_OPT_SEC_AGREE   (1 << 10)
 

Definition at line 279 of file chan_sip.c.

#define SIP_OPT_TARGET_DIALOG   (1 << 13)
 

Definition at line 282 of file chan_sip.c.

#define SIP_OPT_TIMER   (1 << 2)
 

Definition at line 271 of file chan_sip.c.

#define SIP_OSPAUTH   (3 << 26)
 

four settings, uses two bits

Definition at line 559 of file chan_sip.c.

Referenced by check_auth(), check_user_full(), and handle_common_options().

#define SIP_OSPAUTH_EXCLUSIVE   (3 << 26)
 

Definition at line 563 of file chan_sip.c.

Referenced by check_auth(), and handle_common_options().

#define SIP_OSPAUTH_GATEWAY   (1 << 26)
 

Definition at line 561 of file chan_sip.c.

Referenced by check_auth(), and handle_common_options().

#define SIP_OSPAUTH_NO   (0 << 26)
 

Definition at line 560 of file chan_sip.c.

Referenced by check_auth().

#define SIP_OSPAUTH_PROXY   (2 << 26)
 

Definition at line 562 of file chan_sip.c.

Referenced by check_auth(), and handle_common_options().

#define SIP_OUTGOING   (1 << 13)
 

Is this an outgoing call?

Definition at line 531 of file chan_sip.c.

Referenced by handle_request_bye(), handle_request_invite(), handle_request_subscribe(), handle_response(), handle_response_invite(), reqprep(), respprep(), sip_call(), 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 update_call_counter().

#define SIP_PAGE2_DYNAMIC   (1 << 5)
 

Is this a dynamic peer?

Definition at line 583 of file chan_sip.c.

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

#define SIP_PAGE2_IGNOREREGEXPIRE   (1 << 3)
 

Definition at line 581 of file chan_sip.c.

Referenced by build_peer(), destroy_association(), reload_config(), and sip_show_settings().

#define SIP_PAGE2_RT_FROMCONTACT   (1 << 4)
 

Definition at line 582 of file chan_sip.c.

Referenced by build_peer(), destroy_association(), parse_register_contact(), and reg_source_db().

#define SIP_PAGE2_RTAUTOCLEAR   (1 << 2)
 

Definition at line 580 of file chan_sip.c.

Referenced by expire_register(), realtime_peer(), and reload_config().

#define SIP_PAGE2_RTCACHEFRIENDS   (1 << 0)
 

Definition at line 578 of file chan_sip.c.

Referenced by complete_sip_prune_realtime_peer(), complete_sip_prune_realtime_user(), realtime_peer(), realtime_user(), reload_config(), sip_prune_realtime(), sip_show_settings(), and update_peer().

#define SIP_PAGE2_RTUPDATE   (1 << 1)
 

Definition at line 579 of file chan_sip.c.

Referenced by reload_config(), sip_show_settings(), and update_peer().

#define SIP_PENDINGBYE   (1 << 6)
 

Need to send bye after we ack?

Definition at line 524 of file chan_sip.c.

Referenced by check_pendings(), handle_response_invite(), sip_hangup(), and sip_set_rtp_peer().

#define SIP_PKT_DEBUG   (1 << 0)
 

Debug this packet

Definition at line 586 of file chan_sip.c.

Referenced by sipsock_read().

#define SIP_PKT_WITH_TOTAG   (1 << 1)
 

This packet has a to-tag

Definition at line 587 of file chan_sip.c.

Referenced by find_call(), and handle_request().

#define SIP_PROG_INBAND   (3 << 24)
 

three settings, uses two bits

Definition at line 554 of file chan_sip.c.

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

#define SIP_PROG_INBAND_NEVER   (0 << 24)
 

Definition at line 555 of file chan_sip.c.

Referenced by sip_indicate(), and sip_show_settings().

#define SIP_PROG_INBAND_NO   (1 << 24)
 

Definition at line 556 of file chan_sip.c.

Referenced by handle_common_options(), and sip_show_settings().

#define SIP_PROG_INBAND_YES   (2 << 24)
 

Definition at line 557 of file chan_sip.c.

Referenced by handle_common_options(), and sip_indicate().

#define SIP_PROGRESS_SENT   (1 << 4)
 

Have sent 183 message progress

Definition at line 522 of file chan_sip.c.

Referenced by sip_indicate(), and sip_write().

#define SIP_PROMISCREDIR   (1 << 8)
 

Promiscuous redirection

Definition at line 526 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_REALTIME   (1 << 11)
 

Flag for realtime users

Definition at line 529 of file chan_sip.c.

Referenced by build_peer(), parse_register_contact(), realtime_peer(), realtime_user(), sip_destroy_peer(), sip_destroy_user(), and update_peer().

#define SIP_REINVITE   (3 << 20)
 

two bits used

Definition at line 547 of file chan_sip.c.

Referenced by handle_common_options().

#define SIP_REINVITE_UPDATE   (2 << 20)
 

use UPDATE (RFC3311) when reinviting this peer

Definition at line 549 of file chan_sip.c.

Referenced by handle_common_options(), and transmit_reinvite_with_sdp().

#define SIP_RINGING   (1 << 3)
 

Have sent 180 ringing

Definition at line 521 of file chan_sip.c.

Referenced by sip_indicate().

#define SIP_SELFDESTRUCT   (1 << 14)
 

This is an autocreated peer

Definition at line 532 of file chan_sip.c.

Referenced by expire_register(), sip_destroy_peer(), and temp_peer().

#define SIP_SENDRPID   (1 << 30)
 

Definition at line 568 of file chan_sip.c.

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

#define SIP_TRUSTRPID   (1 << 9)
 

Trust RPID headers?

Definition at line 527 of file chan_sip.c.

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

#define SIP_USECLIENTCODE   (1 << 12)
 

Trust X-ClientCode info message

Definition at line 530 of file chan_sip.c.

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

#define SIP_USEREQPHONE   (1 << 10)
 

Add user=phone to numeric URI. Default off

Definition at line 528 of file chan_sip.c.

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

#define SIPDUMPER
 

Definition at line 100 of file chan_sip.c.

#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 266 of file chan_sip.c.

#define SUPPORTED_EXTENSIONS   "replaces"
 

SIP Extensions we support.

Definition at line 326 of file chan_sip.c.

#define VIDEO_CODEC_MASK   0x1fc0000
 

Definition at line 93 of file chan_sip.c.

Referenced by add_sdp().


Enumeration Type Documentation

enum domain_mode
 

Enumeration values:
SIP_DOMAIN_AUTO  This domain is auto-configured
SIP_DOMAIN_CONFIG  This domain is from configuration

Definition at line 487 of file chan_sip.c.

00487                  {
00488    SIP_DOMAIN_AUTO,  /*!< This domain is auto-configured */
00489    SIP_DOMAIN_CONFIG,   /*!< This domain is from configuration */
00490 };

enum parse_register_result
 

Enumeration values:
PARSE_REGISTER_FAILED 
PARSE_REGISTER_UPDATE 
PARSE_REGISTER_QUERY 

Definition at line 5882 of file chan_sip.c.

enum sip_auth_type
 

Enumeration values:
PROXY_AUTH 
WWW_AUTH 

Definition at line 202 of file chan_sip.c.

00202                    {
00203    PROXY_AUTH,
00204    WWW_AUTH,
00205 };

enum sipmethod
 

Enumeration values:
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 

Definition at line 183 of file chan_sip.c.

00183                {
00184    SIP_UNKNOWN,
00185    SIP_RESPONSE,
00186    SIP_REGISTER,
00187    SIP_OPTIONS,
00188    SIP_NOTIFY,
00189    SIP_INVITE,
00190    SIP_ACK,
00191    SIP_PRACK,
00192    SIP_BYE,
00193    SIP_REFER,
00194    SIP_SUBSCRIBE,
00195    SIP_MESSAGE,
00196    SIP_UPDATE,
00197    SIP_INFO,
00198    SIP_CANCEL,
00199    SIP_PUBLISH,
00200 } sip_method_list;

enum subscriptiontype
 

Enumeration values:
NONE 
TIMEOUT 
XPIDF_XML 
DIALOG_INFO_XML 
CPIM_PIDF_XML 
PIDF_XML 

Definition at line 160 of file chan_sip.c.

00160                       { 
00161    NONE = 0,
00162    TIMEOUT,
00163    XPIDF_XML,
00164    DIALOG_INFO_XML,
00165    CPIM_PIDF_XML,
00166    PIDF_XML
00167 };


Function Documentation

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

Definition at line 2924 of file chan_sip.c.

References find_alias(), pass, and pedanticsipchecking.

02925 {
02926    int pass;
02927 
02928    /*
02929     * Technically you can place arbitrary whitespace both before and after the ':' in
02930     * a header, although RFC3261 clearly says you shouldn't before, and place just
02931     * one afterwards.  If you shouldn't do it, what absolute idiot decided it was 
02932     * a good idea to say you can do it, and if you can do it, why in the hell would.
02933     * you say you shouldn't.
02934     * Anyways, pedanticsipchecking controls whether we allow spaces before ':',
02935     * and we always allow spaces after that for compatibility.
02936     */
02937    for (pass = 0; name && pass < 2;pass++) {
02938       int x, len = strlen(name);
02939       for (x=*start; x<req->headers; x++) {
02940          if (!strncasecmp(req->header[x], name, len)) {
02941             char *r = req->header[x] + len;  /* skip name */
02942             if (pedanticsipchecking)
02943                r = ast_skip_blanks(r);
02944 
02945             if (*r == ':') {
02946                *start = x+1;
02947                return ast_skip_blanks(r+1);
02948             }
02949          }
02950       }
02951       if (pass == 0) /* Try aliases */
02952          name = find_alias(name, NULL);
02953    }
02954 
02955    /* Don't return NULL, so get_header is always a valid pointer */
02956    return "";
02957 }

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

__sip_ack: Acknowledges receipt of a packet and stops retransmission ---

Definition at line 1362 of file chan_sip.c.

References ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_sched_del(), ast_test_flag, sip_pvt::callid, sip_pkt::data, FLAG_RESPONSE, free, sip_pvt::lock, LOG_DEBUG, sip_pkt::next, option_debug, sip_pvt::packets, sip_pvt::pendinginvite, sip_pkt::retransid, sip_pkt::seqno, sip_methods, sipdebug, and cfsip_methods::text.

Referenced by __sip_pretend_ack(), handle_request(), and handle_response().

01363 {
01364    struct sip_pkt *cur, *prev = NULL;
01365    int res = -1;
01366    int resetinvite = 0;
01367    /* Just in case... */
01368    char *msg;
01369 
01370    msg = sip_methods[sipmethod].text;
01371 
01372    ast_mutex_lock(&p->lock);
01373    cur = p->packets;
01374    while(cur) {
01375       if ((cur->seqno == seqno) && ((ast_test_flag(cur, FLAG_RESPONSE)) == resp) &&
01376          ((ast_test_flag(cur, FLAG_RESPONSE)) || 
01377           (!strncasecmp(msg, cur->data, strlen(msg)) && (cur->data[strlen(msg)] < 33)))) {
01378          if (!resp && (seqno == p->pendinginvite)) {
01379             ast_log(LOG_DEBUG, "Acked pending invite %d\n", p->pendinginvite);
01380             p->pendinginvite = 0;
01381             resetinvite = 1;
01382          }
01383          /* this is our baby */
01384          if (prev)
01385             prev->next = cur->next;
01386          else
01387             p->packets = cur->next;
01388          if (cur->retransid > -1) {
01389             if (sipdebug && option_debug > 3)
01390                ast_log(LOG_DEBUG, "** SIP TIMER: Cancelling retransmit of packet (reply received) Retransid #%d\n", cur->retransid);
01391             ast_sched_del(sched, cur->retransid);
01392          }
01393          free(cur);
01394          res = 0;
01395          break;
01396       }
01397       prev = cur;
01398       cur = cur->next;
01399    }
01400    ast_mutex_unlock(&p->lock);
01401    ast_log(LOG_DEBUG, "Stopping retransmission on '%s' of %s %d: Match %s\n", p->callid, resp ? "Response" : "Request", seqno, res ? "Not Found" : "Found");
01402    return res;
01403 }

static int __sip_autodestruct void *  data  )  [static]
 

__sip_autodestruct: Kill a call (called by scheduler) ---

Definition at line 1306 of file chan_sip.c.

References append_history(), AST_EXTENSION_DEACTIVATED, ast_log(), ast_queue_hangup(), sip_pvt::autokillid, sip_pvt::callid, LOG_DEBUG, LOG_WARNING, NONE, sip_pvt::owner, sip_destroy(), sip_pvt::subscribed, TIMEOUT, and transmit_state_notify().

Referenced by sip_scheddestroy().

01307 {
01308    struct sip_pvt *p = data;
01309 
01310 
01311    /* If this is a subscription, tell the phone that we got a timeout */
01312    if (p->subscribed) {
01313       p->subscribed = TIMEOUT;
01314       transmit_state_notify(p, AST_EXTENSION_DEACTIVATED, 1, 1);  /* Send first notification */
01315       p->subscribed = NONE;
01316       append_history(p, "Subscribestatus", "timeout");
01317       return 10000;  /* Reschedule this destruction so that we know that it's gone */
01318    }
01319 
01320    /* This scheduled event is now considered done. */
01321    p->autokillid = -1;
01322 
01323    ast_log(LOG_DEBUG, "Auto destroying call '%s'\n", p->callid);
01324    append_history(p, "AutoDestroy", "");
01325    if (p->owner) {
01326       ast_log(LOG_WARNING, "Autodestruct on call '%s' with owner in place\n", p->callid);
01327       ast_queue_hangup(p->owner);
01328    } else {
01329       sip_destroy(p);
01330    }
01331    return 0;
01332 }

static void __sip_destroy struct sip_pvt p,
int  lockowner
[static]
 

__sip_destroy: Execute destrucion of call structure, release memory---

Definition at line 2103 of file chan_sip.c.

References ast_extension_state_del(), ast_log(), ast_mutex_destroy(), ast_mutex_lock(), ast_mutex_unlock(), ast_rtp_destroy(), ast_sched_del(), ast_variables_destroy(), ast_verbose(), ASTOBJ_UNREF, sip_pvt::callid, dumphistory, free, free_old_route(), iflist, LOG_DEBUG, LOG_WARNING, sip_pvt::next, sip_history::next, sip_pkt::retransid, sip_debug_test_pvt(), sip_dump_history(), and sip_registry_destroy().

Referenced by do_monitor(), and sip_destroy().

02104 {
02105    struct sip_pvt *cur, *prev = NULL;
02106    struct sip_pkt *cp;
02107    struct sip_history *hist;
02108 
02109    if (sip_debug_test_pvt(p))
02110       ast_verbose("Destroying call '%s'\n", p->callid);
02111 
02112    if (dumphistory)
02113       sip_dump_history(p);
02114 
02115    if (p->options)
02116       free(p->options);
02117 
02118    if (p->stateid > -1)
02119       ast_extension_state_del(p->stateid, NULL);
02120    if (p->initid > -1)
02121       ast_sched_del(sched, p->initid);
02122    if (p->autokillid > -1)
02123       ast_sched_del(sched, p->autokillid);
02124 
02125    if (p->rtp) {
02126       ast_rtp_destroy(p->rtp);
02127    }
02128    if (p->vrtp) {
02129       ast_rtp_destroy(p->vrtp);
02130    }
02131    if (p->route) {
02132       free_old_route(p->route);
02133       p->route = NULL;
02134    }
02135    if (p->registry) {
02136       if (p->registry->call == p)
02137          p->registry->call = NULL;
02138       ASTOBJ_UNREF(p->registry,sip_registry_destroy);
02139    }
02140 
02141    if (p->rpid)
02142       free(p->rpid);
02143 
02144    if (p->rpid_from)
02145       free(p->rpid_from);
02146 
02147    /* Unlink us from the owner if we have one */
02148    if (p->owner) {
02149       if (lockowner)
02150          ast_mutex_lock(&p->owner->lock);
02151       ast_log(LOG_DEBUG, "Detaching from %s\n", p->owner->name);
02152       p->owner->tech_pvt = NULL;
02153       if (lockowner)
02154          ast_mutex_unlock(&p->owner->lock);
02155    }
02156    /* Clear history */
02157    while(p->history) {
02158       hist = p->history;
02159       p->history = p->history->next;
02160       free(hist);
02161    }
02162 
02163    cur = iflist;
02164    while(cur) {
02165       if (cur == p) {
02166          if (prev)
02167             prev->next = cur->next;
02168          else
02169             iflist = cur->next;
02170          break;
02171       }
02172       prev = cur;
02173       cur = cur->next;
02174    }
02175    if (!cur) {
02176       ast_log(LOG_WARNING, "Trying to destroy \"%s\", not found in dialog list?!?! \n", p->callid);
02177       return;
02178    } 
02179    while((cp = p->packets)) {
02180       p->packets = p->packets->next;
02181       if (cp->retransid > -1) {
02182          ast_sched_del(sched, cp->retransid);
02183       }
02184       free(cp);
02185    }
02186    if (p->chanvars) {
02187       ast_variables_destroy(p->chanvars);
02188       p->chanvars = NULL;
02189    }
02190    ast_mutex_destroy(&p->lock);
02191    free(p);
02192 }

static int __sip_do_register struct sip_registry r  )  [static]
 

__sip_do_register: Register with SIP proxy ---

Definition at line 5345 of file chan_sip.c.

References SIP_REGISTER, and transmit_register().

Referenced by sip_reregister().

05346 {
05347    int res;
05348 
05349    res = transmit_register(r, SIP_REGISTER, NULL, NULL);
05350    return res;
05351 }

static int __sip_pretend_ack struct sip_pvt p  )  [static]
 

Definition at line 1406 of file chan_sip.c.

References __sip_ack(), ast_log(), ast_test_flag, sip_pkt::data, find_sip_method(), FLAG_RESPONSE, LOG_WARNING, sip_pkt::method, sip_pvt::packets, sip_pkt::seqno, and sip_methods.

Referenced by sip_hangup(), and sip_reg_timeout().

01407 {
01408    struct sip_pkt *cur=NULL;
01409 
01410    while(p->packets) {
01411       if (cur == p->packets) {
01412          ast_log(LOG_WARNING, "Have a packet that doesn't want to give up! %s\n", sip_methods[cur->method].text);
01413          return -1;
01414       }
01415       cur = p->packets;
01416       if (cur->method)
01417          __sip_ack(p, p->packets->seqno, (ast_test_flag(p->packets, FLAG_RESPONSE)), cur->method);
01418       else {   /* Unknown packet type */
01419          char *c;
01420          char method[128];
01421          ast_copy_string(method, p->packets->data, sizeof(method));
01422          c = ast_skip_blanks(method); /* XXX what ? */
01423          *c = '\0';
01424          __sip_ack(p, p->packets->seqno, (ast_test_flag(p->packets, FLAG_RESPONSE)), find_sip_method(method));
01425       }
01426    }
01427    return 0;
01428 }

static int __sip_reliable_xmit struct sip_pvt p,
int  seqno,
int  resp,
char *  data,
int  len,
int  fatal,
int  sipmethod
[static]
 

__sip_reliable_xmit: transmit packet with retransmits ---

Definition at line 1267 of file chan_sip.c.

References __sip_xmit(), ast_log(), ast_sched_add_variable(), ast_set_flag, DEFAULT_RETRANS, FLAG_FATAL, sip_pvt::flags, LOG_DEBUG, malloc, option_debug, sip_pkt::owner, sip_pvt::packets, sip_pvt::pendinginvite, retrans_pkt(), SIP_INVITE, sipdebug, and sip_pvt::timer_t1.

Referenced by send_request(), and send_response().

01268 {
01269    struct sip_pkt *pkt;
01270    int siptimer_a = DEFAULT_RETRANS;
01271 
01272    pkt = malloc(sizeof(struct sip_pkt) + len + 1);
01273    if (!pkt)
01274       return -1;
01275    memset(pkt, 0, sizeof(struct sip_pkt));
01276    memcpy(pkt->data, data, len);
01277    pkt->method = sipmethod;
01278    pkt->packetlen = len;
01279    pkt->next = p->packets;
01280    pkt->owner = p;
01281    pkt->seqno = seqno;
01282    pkt->flags = resp;
01283    pkt->data[len] = '\0';
01284    pkt->timer_t1 = p->timer_t1;  /* Set SIP timer T1 */
01285    if (fatal)
01286       ast_set_flag(pkt, FLAG_FATAL);
01287    if (pkt->timer_t1)
01288       siptimer_a = pkt->timer_t1 * 2;
01289 
01290    /* Schedule retransmission */
01291    pkt->retransid = ast_sched_add_variable(sched, siptimer_a, retrans_pkt, pkt, 1);
01292    if (option_debug > 3 && sipdebug)
01293       ast_log(LOG_DEBUG, "*** SIP TIMER: Initalizing retransmit timer on packet: Id  #%d\n", pkt->retransid);
01294    pkt->next = p->packets;
01295    p->packets = pkt;
01296 
01297    __sip_xmit(pkt->owner, pkt->data, pkt->packetlen); /* Send packet */
01298    if (sipmethod == SIP_INVITE) {
01299       /* Note this is a pending invite */
01300       p->pendinginvite = seqno;
01301    }
01302    return 0;
01303 }

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

__sip_semi_ack: Acks receipt of packet, keep it around (used for provisional responses) ---

Definition at line 1431 of file chan_sip.c.

References ast_log(), ast_sched_del(), ast_test_flag, sip_pvt::callid, sip_pkt::data, FLAG_RESPONSE, LOG_DEBUG, sip_pkt::next, option_debug, sip_pvt::packets, sip_pkt::retransid, sip_pkt::seqno, sip_methods, sipdebug, and cfsip_methods::text.

Referenced by handle_response().

01432 {
01433    struct sip_pkt *cur;
01434    int res = -1;
01435    char *msg = sip_methods[sipmethod].text;
01436 
01437    cur = p->packets;
01438    while(cur) {
01439       if ((cur->seqno == seqno) && ((ast_test_flag(cur, FLAG_RESPONSE)) == resp) &&
01440          ((ast_test_flag(cur, FLAG_RESPONSE)) || 
01441           (!strncasecmp(msg, cur->data, strlen(msg)) && (cur->data[strlen(msg)] < 33)))) {
01442          /* this is our baby */
01443          if (cur->retransid > -1) {
01444             if (option_debug > 3 && sipdebug)
01445                ast_log(LOG_DEBUG, "*** SIP TIMER: Cancelling retransmission #%d - %s (got response)\n", cur->retransid, msg);
01446             ast_sched_del(sched, cur->retransid);
01447          }
01448          cur->retransid = -1;
01449          res = 0;
01450          break;
01451       }
01452       cur = cur->next;
01453    }
01454    ast_log(LOG_DEBUG, "(Provisional) Stopping retransmission (but retaining packet) on '%s' %s %d: %s\n", p->callid, resp ? "Response" : "Request", seqno, res ? "Not Found" : "Found");
01455    return res;
01456 }

static int __sip_show_channels int  fd,
int  argc,
char *  argv[],
int  subscriptions
[static]
 

Definition at line 8390 of file chan_sip.c.

References ast_cli(), ast_extension_state2str(), ast_getformatname(), ast_inet_ntoa(), ast_mutex_lock(), ast_mutex_unlock(), ast_strlen_zero(), ast_test_flag, sip_pvt::callid, sip_pvt::cid_num, sip_pvt::exten, FORMAT, FORMAT2, sip_pvt::icseq, iflist, sip_pvt::lastmsg, sip_pvt::laststate, ast_channel::nativeformats, sip_pvt::next, NONE, sip_pvt::ocseq, sip_pvt::owner, RESULT_SHOWUSAGE, RESULT_SUCCESS, sip_pvt::sa, SIP_CALL_ONHOLD, SIP_NEEDDESTROY, sip_pvt::subscribed, subscription_type2str(), and sip_pvt::username.

Referenced by sip_show_channels(), and sip_show_subscriptions().

08391 {
08392 #define FORMAT3 "%-15.15s  %-10.10s  %-11.11s  %-15.15s  %-13.13s  %-15.15s\n"
08393 #define FORMAT2 "%-15.15s  %-10.10s  %-11.11s  %-11.11s  %-4.4s  %-7.7s  %-15.15s\n"
08394 #define FORMAT  "%-15.15s  %-10.10s  %-11.11s  %5.5d/%5.5d  %-4.4s  %-3.3s %-3.3s  %-15.15s\n"
08395    struct sip_pvt *cur;
08396    char iabuf[INET_ADDRSTRLEN];
08397    int numchans = 0;
08398    if (argc != 3)
08399       return RESULT_SHOWUSAGE;
08400    ast_mutex_lock(&iflock);
08401    cur = iflist;
08402    if (!subscriptions)
08403       ast_cli(fd, FORMAT2, "Peer", "User/ANR", "Call ID", "Seq (Tx/Rx)", "Format", "Hold", "Last Message");
08404    else
08405       ast_cli(fd, FORMAT3, "Peer", "User", "Call ID", "Extension", "Last state", "Type");
08406    while (cur) {
08407       if (cur->subscribed == NONE && !subscriptions) {
08408          ast_cli(fd, FORMAT, ast_inet_ntoa(iabuf, sizeof(iabuf), cur->sa.sin_addr), 
08409             ast_strlen_zero(cur->username) ? ( ast_strlen_zero(cur->cid_num) ? "(None)" : cur->cid_num ) : cur->username, 
08410             cur->callid, 
08411             cur->ocseq, cur->icseq, 
08412             ast_getformatname(cur->owner ? cur->owner->nativeformats : 0), 
08413             ast_test_flag(cur, SIP_CALL_ONHOLD) ? "Yes" : "No",
08414             ast_test_flag(cur, SIP_NEEDDESTROY) ? "(d)" : "",
08415             cur->lastmsg );
08416          numchans++;
08417       }
08418       if (cur->subscribed != NONE && subscriptions) {
08419          ast_cli(fd, FORMAT3, ast_inet_ntoa(iabuf, sizeof(iabuf), cur->sa.sin_addr),
08420                  ast_strlen_zero(cur->username) ? ( ast_strlen_zero(cur->cid_num) ? "(None)" : cur->cid_num ) : cur->username, 
08421                  cur->callid, cur->exten, ast_extension_state2str(cur->laststate), 
08422                  subscription_type2str(cur->subscribed));
08423          numchans++;
08424       }
08425       cur = cur->next;
08426    }
08427    ast_mutex_unlock(&iflock);
08428    if (!subscriptions)
08429       ast_cli(fd, "%d active SIP channel%s\n", numchans, (numchans != 1) ? "s" : "");
08430    else
08431       ast_cli(fd, "%d active SIP subscription%s\n", numchans, (numchans != 1) ? "s" : "");
08432    return RESULT_SUCCESS;
08433 #undef FORMAT
08434 #undef FORMAT2
08435 #undef FORMAT3
08436 }

static int __sip_xmit struct sip_pvt p,
char *  data,
int  len
[static]
 

__sip_xmit: Transmit SIP message ---

Definition at line 1062 of file chan_sip.c.

References ast_inet_ntoa(), ast_log(), ast_test_flag, LOG_WARNING, sip_pvt::recv, sip_pvt::sa, SIP_NAT, SIP_NAT_ROUTE, and sipsock.

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

01063 {
01064    int res;
01065    char iabuf[INET_ADDRSTRLEN];
01066 
01067    if (ast_test_flag(p, SIP_NAT) & SIP_NAT_ROUTE)
01068       res=sendto(sipsock, data, len, 0, (struct sockaddr *)&p->recv, sizeof(struct sockaddr_in));
01069    else
01070       res=sendto(sipsock, data, len, 0, (struct sockaddr *)&p->sa, sizeof(struct sockaddr_in));
01071 
01072    if (res != len) {
01073       ast_log(LOG_WARNING, "sip_xmit of %p (len %d) to %s:%d returned %d: %s\n", data, len, ast_inet_ntoa(iabuf, sizeof(iabuf), p->sa.sin_addr), ntohs(p->sa.sin_port), res, strerror(errno));
01074    }
01075    return res;
01076 }

static int __transmit_response struct sip_pvt p,
char *  msg,
struct sip_request req,
int  reliable
[static]
 

__transmit_response: Base transmit response function

Definition at line 4208 of file chan_sip.c.

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

Referenced by transmit_response(), and transmit_response_reliable().

04209 {
04210    struct sip_request resp;
04211    int seqno = 0;
04212 
04213    if (reliable && (sscanf(get_header(req, "CSeq"), "%d ", &seqno) != 1)) {
04214       ast_log(LOG_WARNING, "Unable to determine sequence number from '%s'\n", get_header(req, "CSeq"));
04215       return -1;
04216    }
04217    respprep(&resp, p, msg, req);
04218    add_header_contentLength(&resp, 0);
04219    /* If we are cancelling an incoming invite for some reason, add information
04220       about the reason why we are doing this in clear text */
04221    if (msg[0] != '1' && p->owner && p->owner->hangupcause) {
04222       add_header(&resp, "X-Asterisk-HangupCause", ast_cause2str(p->owner->hangupcause));
04223    }
04224    add_blank_header(&resp);
04225    return send_response(p, &resp, reliable, seqno);
04226 }

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

Definition at line 7996 of file chan_sip.c.

References sip_peer::accountcode, sip_peer::addr, sip_peer::amaflags, ast_callerid_merge(), ast_cdr_flags2str(), ast_cli(), ast_codec_pref_index(), ast_describe_caller_presentation(), ast_getformatname(), ast_getformatname_multiple(), ast_inet_ntoa(), ast_sched_when(), ast_strlen_zero(), ast_test_flag, astman_send_error(), ASTOBJ_UNREF, sip_peer::auth, sip_peer::call_limit, sip_peer::callgroup, sip_peer::callingpres, sip_peer::capability, sip_peer::chanvars, sip_peer::cid_name, sip_peer::cid_num, sip_peer::context, sip_peer::defaddr, dtmfmode2str(), sip_peer::expire, mansession::fd, find_peer(), sip_peer::flags_page2, sip_peer::fromdomain, sip_peer::fromuser, sip_peer::fullcontact, sip_peer::ha, insecure2str(), sip_peer::language, sip_peer::lastmsg, sip_peer::lastmsgssent, sip_peer::mailbox, sip_auth::md5secret, sip_peer::md5secret, ast_variable::name, nat2str(), ast_variable::next, sip_auth::next, peer_status(), sip_peer::pickupgroup, sip_peer::prefs, print_codec_to_cli(), print_group(), sip_auth::realm, RESULT_SHOWUSAGE, RESULT_SUCCESS, sip_auth::secret, sip_peer::secret, SIP_CAN_REINVITE, sip_destroy_peer(), SIP_DTMF, SIP_INSECURE_INVITE, SIP_INSECURE_PORT, SIP_NAT, sip_options, SIP_PAGE2_DYNAMIC, SIP_PROMISCREDIR, SIP_SENDRPID, SIP_TRUSTRPID, SIP_USEREQPHONE, sip_peer::sipoptions, sip_peer::subscribecontext, text, sip_peer::tohost, 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().

07997 {
07998    char status[30] = "";
07999    char cbuf[256];
08000    char iabuf[INET_ADDRSTRLEN];
08001    struct sip_peer *peer;
08002    char codec_buf[512];
08003    struct ast_codec_pref *pref;
08004    struct ast_variable *v;
08005    struct sip_auth *auth;
08006    int x = 0, codec = 0, load_realtime = 0;
08007 
08008    if (argc < 4)
08009       return RESULT_SHOWUSAGE;
08010 
08011    load_realtime = (argc == 5 && !strcmp(argv[4], "load")) ? 1 : 0;
08012    peer = find_peer(argv[3], NULL, load_realtime);
08013    if (s) {    /* Manager */
08014       if (peer)
08015          ast_cli(s->fd, "Response: Success\r\n");
08016       else {
08017          snprintf (cbuf, sizeof(cbuf), "Peer %s not found.\n", argv[3]);
08018          astman_send_error(s, m, cbuf);
08019          return 0;
08020       }
08021    }
08022    if (peer && type==0 ) { /* Normal listing */
08023       ast_cli(fd,"\n\n");
08024       ast_cli(fd, "  * Name       : %s\n", peer->name);
08025       ast_cli(fd, "  Secret       : %s\n", ast_strlen_zero(peer->secret)?"<Not set>":"<Set>");
08026       ast_cli(fd, "  MD5Secret    : %s\n", ast_strlen_zero(peer->md5secret)?"<Not set>":"<Set>");
08027       auth = peer->auth;
08028       while(auth) {
08029          ast_cli(fd, "  Realm-auth   : Realm %-15.15s User %-10.20s ", auth->realm, auth->username);
08030          ast_cli(fd, "%s\n", !ast_strlen_zero(auth->secret)?"<Secret set>":(!ast_strlen_zero(auth->md5secret)?"<MD5secret set>" : "<Not set>"));
08031          auth = auth->next;
08032       }
08033       ast_cli(fd, "  Context      : %s\n", peer->context);
08034       ast_cli(fd, "  Subscr.Cont. : %s\n", ast_strlen_zero(peer->subscribecontext)?"<Not set>":peer->subscribecontext);
08035       ast_cli(fd, "  Language     : %s\n", peer->language);
08036       if (!ast_strlen_zero(peer->accountcode))
08037          ast_cli(fd, "  Accountcode  : %s\n", peer->accountcode);
08038       ast_cli(fd, "  AMA flags    : %s\n", ast_cdr_flags2str(peer->amaflags));
08039       ast_cli(fd, "  CallingPres  : %s\n", ast_describe_caller_presentation(peer->callingpres));
08040       if (!ast_strlen_zero(peer->fromuser))
08041          ast_cli(fd, "  FromUser     : %s\n", peer->fromuser);
08042       if (!ast_strlen_zero(peer->fromdomain))
08043          ast_cli(fd, "  FromDomain   : %s\n", peer->fromdomain);
08044       ast_cli(fd, "  Callgroup    : ");
08045       print_group(fd, peer->callgroup, 0);
08046       ast_cli(fd, "  Pickupgroup  : ");
08047       print_group(fd, peer->pickupgroup, 0);
08048       ast_cli(fd, "  Mailbox      : %s\n", peer->mailbox);
08049       ast_cli(fd, "  VM Extension : %s\n", peer->vmexten);
08050       ast_cli(fd, "  LastMsgsSent : %d\n", peer->lastmsgssent);
08051       ast_cli(fd, "  Call limit   : %d\n", peer->call_limit);
08052       ast_cli(fd, "  Dynamic      : %s\n", (ast_test_flag(&peer->flags_page2, SIP_PAGE2_DYNAMIC)?"Yes":"No"));
08053       ast_cli(fd, "  Callerid     : %s\n", ast_callerid_merge(cbuf, sizeof(cbuf), peer->cid_name, peer->cid_num, "<unspecified>"));
08054       ast_cli(fd, "  Expire       : %ld\n", ast_sched_when(sched, peer->expire));
08055       ast_cli(fd, "  Insecure     : %s\n", insecure2str(ast_test_flag(peer, SIP_INSECURE_PORT), ast_test_flag(peer, SIP_INSECURE_INVITE)));
08056       ast_cli(fd, "  Nat          : %s\n", nat2str(ast_test_flag(peer, SIP_NAT)));
08057       ast_cli(fd, "  ACL          : %s\n", (peer->ha?"Yes":"No"));
08058       ast_cli(fd, "  CanReinvite  : %s\n", (ast_test_flag(peer, SIP_CAN_REINVITE)?"Yes":"No"));
08059       ast_cli(fd, "  PromiscRedir : %s\n", (ast_test_flag(peer, SIP_PROMISCREDIR)?"Yes":"No"));
08060       ast_cli(fd, "  User=Phone   : %s\n", (ast_test_flag(peer, SIP_USEREQPHONE)?"Yes":"No"));
08061       ast_cli(fd, "  Trust RPID   : %s\n", (ast_test_flag(peer, SIP_TRUSTRPID) ? "Yes" : "No"));
08062       ast_cli(fd, "  Send RPID    : %s\n", (ast_test_flag(peer, SIP_SENDRPID) ? "Yes" : "No"));
08063 
08064       /* - is enumerated */
08065       ast_cli(fd, "  DTMFmode     : %s\n", dtmfmode2str(ast_test_flag(peer, SIP_DTMF)));
08066       ast_cli(fd, "  LastMsg      : %d\n", peer->lastmsg);
08067       ast_cli(fd, "  ToHost       : %s\n", peer->tohost);
08068       ast_cli(fd, "  Addr->IP     : %s Port %d\n",  peer->addr.sin_addr.s_addr ? ast_inet_ntoa(iabuf, sizeof(iabuf), peer->addr.sin_addr) : "(Unspecified)", ntohs(peer->addr.sin_port));
08069       ast_cli(fd, "  Defaddr->IP  : %s Port %d\n", ast_inet_ntoa(iabuf, sizeof(iabuf), peer->defaddr.sin_addr), ntohs(peer->defaddr.sin_port));
08070       ast_cli(fd, "  Def. Username: %s\n", peer->username);
08071       ast_cli(fd, "  SIP Options  : ");
08072       if (peer->sipoptions) {
08073          for (x=0 ; (x < (sizeof(sip_options) / sizeof(sip_options[0]))); x++) {
08074             if (peer->sipoptions & sip_options[x].id)
08075                ast_cli(fd, "%s ", sip_options[x].text);
08076          }
08077       } else
08078          ast_cli(fd, "(none)");
08079 
08080       ast_cli(fd, "\n");
08081       ast_cli(fd, "  Codecs       : ");
08082       ast_getformatname_multiple(codec_buf, sizeof(codec_buf) -1, peer->capability);
08083       ast_cli(fd, "%s\n", codec_buf);
08084       ast_cli(fd, "  Codec Order  : (");
08085       print_codec_to_cli(fd, &peer->prefs);
08086 
08087       ast_cli(fd, ")\n");
08088 
08089       ast_cli(fd, "  Status       : ");
08090       peer_status(peer, status, sizeof(status));
08091       ast_cli(fd, "%s\n",status);
08092       ast_cli(fd, "  Useragent    : %s\n", peer->useragent);
08093       ast_cli(fd, "  Reg. Contact : %s\n", peer->fullcontact);
08094       if (peer->chanvars) {
08095          ast_cli(fd, "  Variables    :\n");
08096          for (v = peer->chanvars ; v ; v = v->next)
08097             ast_cli(fd, "                 %s = %s\n", v->name, v->value);
08098       }
08099       ast_cli(fd,"\n");
08100       ASTOBJ_UNREF(peer,sip_destroy_peer);
08101    } else  if (peer && type == 1) { /* manager listing */
08102       ast_cli(fd, "Channeltype: SIP\r\n");
08103       ast_cli(fd, "ObjectName: %s\r\n", peer->name);
08104       ast_cli(fd, "ChanObjectType: peer\r\n");
08105       ast_cli(fd, "SecretExist: %s\r\n", ast_strlen_zero(peer->secret)?"N":"Y");
08106       ast_cli(fd, "MD5SecretExist: %s\r\n", ast_strlen_zero(peer->md5secret)?"N":"Y");
08107       ast_cli(fd, "Context: %s\r\n", peer->context);
08108       ast_cli(fd, "Language: %s\r\n", peer->language);
08109       if (!ast_strlen_zero(peer->accountcode))
08110          ast_cli(fd, "Accountcode: %s\r\n", peer->accountcode);
08111       ast_cli(fd, "AMAflags: %s\r\n", ast_cdr_flags2str(peer->amaflags));
08112       ast_cli(fd, "CID-CallingPres: %s\r\n", ast_describe_caller_presentation(peer->callingpres));
08113       if (!ast_strlen_zero(peer->fromuser))
08114          ast_cli(fd, "SIP-FromUser: %s\r\n", peer->fromuser);
08115       if (!ast_strlen_zero(peer->fromdomain))
08116          ast_cli(fd, "SIP-FromDomain: %s\r\n", peer->fromdomain);
08117       ast_cli(fd, "Callgroup: ");
08118       print_group(fd, peer->callgroup, 1);
08119       ast_cli(fd, "Pickupgroup: ");
08120       print_group(fd, peer->pickupgroup, 1);
08121       ast_cli(fd, "VoiceMailbox: %s\r\n", peer->mailbox);
08122       ast_cli(fd, "LastMsgsSent: %d\r\n", peer->lastmsgssent);
08123       ast_cli(fd, "Call limit: %d\r\n", peer->call_limit);
08124       ast_cli(fd, "Dynamic: %s\r\n", (ast_test_flag(&peer->flags_page2, SIP_PAGE2_DYNAMIC)?"Y":"N"));
08125       ast_cli(fd, "Callerid: %s\r\n", ast_callerid_merge(cbuf, sizeof(cbuf), peer->cid_name, peer->cid_num, ""));
08126       ast_cli(fd, "RegExpire: %ld seconds\r\n", ast_sched_when(sched,peer->expire));
08127       ast_cli(fd, "SIP-AuthInsecure: %s\r\n", insecure2str(ast_test_flag(peer, SIP_INSECURE_PORT), ast_test_flag(peer, SIP_INSECURE_INVITE)));
08128       ast_cli(fd, "SIP-NatSupport: %s\r\n", nat2str(ast_test_flag(peer, SIP_NAT)));
08129       ast_cli(fd, "ACL: %s\r\n", (peer->ha?"Y":"N"));
08130       ast_cli(fd, "SIP-CanReinvite: %s\r\n", (ast_test_flag(peer, SIP_CAN_REINVITE)?"Y":"N"));
08131       ast_cli(fd, "SIP-PromiscRedir: %s\r\n", (ast_test_flag(peer, SIP_PROMISCREDIR)?"Y":"N"));
08132       ast_cli(fd, "SIP-UserPhone: %s\r\n", (ast_test_flag(peer, SIP_USEREQPHONE)?"Y":"N"));
08133 
08134       /* - is enumerated */
08135       ast_cli(fd, "SIP-DTMFmode: %s\r\n", dtmfmode2str(ast_test_flag(peer, SIP_DTMF)));
08136       ast_cli(fd, "SIPLastMsg: %d\r\n", peer->lastmsg);
08137       ast_cli(fd, "ToHost: %s\r\n", peer->tohost);
08138       ast_cli(fd, "Address-IP: %s\r\nAddress-Port: %d\r\n",  peer->addr.sin_addr.s_addr ? ast_inet_ntoa(iabuf, sizeof(iabuf), peer->addr.sin_addr) : "", ntohs(peer->addr.sin_port));
08139       ast_cli(fd, "Default-addr-IP: %s\r\nDefault-addr-port: %d\r\n", ast_inet_ntoa(iabuf, sizeof(iabuf), peer->defaddr.sin_addr), ntohs(peer->defaddr.sin_port));
08140       ast_cli(fd, "Default-Username: %s\r\n", peer->username);
08141       ast_cli(fd, "Codecs: ");
08142       ast_getformatname_multiple(codec_buf, sizeof(codec_buf) -1, peer->capability);
08143       ast_cli(fd, "%s\r\n", codec_buf);
08144       ast_cli(fd, "CodecOrder: ");
08145       pref = &peer->prefs;
08146       for(x = 0; x < 32 ; x++) {
08147          codec = ast_codec_pref_index(pref,x);
08148          if (!codec)
08149             break;
08150          ast_cli(fd, "%s", ast_getformatname(codec));
08151          if (x < 31 && ast_codec_pref_index(pref,x+1))
08152             ast_cli(fd, ",");
08153       }
08154 
08155       ast_cli(fd, "\r\n");
08156       ast_cli(fd, "Status: ");
08157       peer_status(peer, status, sizeof(status));
08158       ast_cli(fd, "%s\r\n", status);
08159       ast_cli(fd, "SIP-Useragent: %s\r\n", peer->useragent);
08160       ast_cli(fd, "Reg-Contact : %s\r\n", peer->fullcontact);
08161       if (peer->chanvars) {
08162          for (v = peer->chanvars ; v ; v = v->next) {
08163             ast_cli(fd, "ChanVariable:\n");
08164             ast_cli(fd, " %s,%s\r\n", v->name, v->value);
08165          }
08166       }
08167 
08168       ASTOBJ_UNREF(peer,sip_destroy_peer);
08169 
08170    } else {
08171       ast_cli(fd,"Peer %s not found.\n", argv[3]);
08172       ast_cli(fd,"\n");
08173    }
08174 
08175    return RESULT_SUCCESS;
08176 }

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

_sip_show_peers: Execute sip show peers command

Definition at line 7574 of file chan_sip.c.

References ast_cli(), ast_strlen_zero(), astman_get_header(), ASTOBJ_CONTAINER_TRAVERSE, ASTOBJ_RDLOCK, ASTOBJ_UNLOCK, FORMAT2, id, name, peer_status(), peerl, and RESULT_SHOWUSAGE.

Referenced by manager_sip_show_peers(), and sip_show_peers().

07575 {
07576    regex_t regexbuf;
07577    int havepattern = 0;
07578 
07579 #define FORMAT2 "%-25.25s  %-15.15s %-3.3s %-3.3s %-3.3s %-8s %-10s\n"
07580 #define FORMAT  "%-25.25s  %-15.15s %-3.3s %-3.3s %-3.3s %-8d %-10s\n"
07581 
07582    char name[256];
07583    char iabuf[INET_ADDRSTRLEN];
07584    int total_peers = 0;
07585    int peers_online = 0;
07586    int peers_offline = 0;
07587    char *id;
07588    char idtext[256] = "";
07589 
07590    if (s) { /* Manager - get ActionID */
07591       id = astman_get_header(m,"ActionID");
07592       if (!ast_strlen_zero(id))
07593          snprintf(idtext,256,"ActionID: %s\r\n",id);
07594    }
07595 
07596    switch (argc) {
07597    case 5:
07598       if (!strcasecmp(argv[3], "like")) {
07599          if (regcomp(&regexbuf, argv[4], REG_EXTENDED | REG_NOSUB))
07600             return RESULT_SHOWUSAGE;
07601          havepattern = 1;
07602       } else
07603          return RESULT_SHOWUSAGE;
07604    case 3:
07605       break;
07606    default:
07607       return RESULT_SHOWUSAGE;
07608    }
07609 
07610    if (!s) { /* Normal list */
07611       ast_cli(fd, FORMAT2, "Name/username", "Host", "Dyn", "Nat", "ACL", "Port", "Status");
07612    } 
07613    
07614    ASTOBJ_CONTAINER_TRAVERSE(&peerl, 1, do {
07615       char status[20] = "";
07616       char srch[2000];
07617       char pstatus;
07618       
07619       ASTOBJ_RDLOCK(iterator);
07620 
07621       if (havepattern && regexec(&regexbuf, iterator->name, 0, NULL, 0)) {
07622          ASTOBJ_UNLOCK(iterator);
07623          continue;
07624       }
07625 
07626       if (!ast_strlen_zero(iterator->username) && !s)
07627          snprintf(name, sizeof(name), "%s/%s", iterator->name, iterator->username);
07628       else
07629          ast_copy_string(name, iterator->name, sizeof(name));
07630 
07631       pstatus = peer_status(iterator, status, sizeof(status));
07632       if (pstatus)   
07633          peers_online++;
07634       else  {
07635          if (pstatus == 0)
07636             peers_offline++;
07637          else {   /* Unmonitored */
07638             /* Checking if port is 0 */
07639             if ( ntohs(iterator->addr.sin_port) == 0 ) {
07640                peers_offline++;
07641             } else {
07642                peers_online++;
07643             }
07644          }
07645       }        
07646       
07647       snprintf(srch, sizeof(srch), FORMAT, name,
07648          iterator->addr.sin_addr.s_addr ? ast_inet_ntoa(iabuf, sizeof(iabuf), iterator->addr.sin_addr) : "(Unspecified)",
07649          ast_test_flag(&iterator->flags_page2, SIP_PAGE2_DYNAMIC) ? " D " : "   ",  /* Dynamic or not? */
07650          (ast_test_flag(iterator, SIP_NAT) & SIP_NAT_ROUTE) ? " N " : "   ",  /* NAT=yes? */
07651          iterator->ha ? " A " : "   ",    /* permit/deny */
07652          ntohs(iterator->addr.sin_port), status);
07653 
07654       if (!s)  {/* Normal CLI list */
07655          ast_cli(fd, FORMAT, name, 
07656          iterator->addr.sin_addr.s_addr ? ast_inet_ntoa(iabuf, sizeof(iabuf), iterator->addr.sin_addr) : "(Unspecified)",
07657          ast_test_flag(&iterator->flags_page2, SIP_PAGE2_DYNAMIC) ? " D " : "   ",  /* Dynamic or not? */
07658          (ast_test_flag(iterator, SIP_NAT) & SIP_NAT_ROUTE) ? " N " : "   ",  /* NAT=yes? */
07659          iterator->ha ? " A " : "   ",       /* permit/deny */
07660          
07661          ntohs(iterator->addr.sin_port), status);
07662       } else { /* Manager format */
07663          /* The names here need to be the same as other channels */
07664          ast_cli(fd, 
07665          "Event: PeerEntry\r\n%s"
07666          "Channeltype: SIP\r\n"
07667          "ObjectName: %s\r\n"
07668          "ChanObjectType: peer\r\n" /* "peer" or "user" */
07669          "IPaddress: %s\r\n"
07670          "IPport: %d\r\n"
07671          "Dynamic: %s\r\n"
07672          "Natsupport: %s\r\n"
07673          "ACL: %s\r\n"
07674          "Status: %s\r\n\r\n", 
07675          idtext,
07676          iterator->name, 
07677          iterator->addr.sin_addr.s_addr ? ast_inet_ntoa(iabuf, sizeof(iabuf), iterator->addr.sin_addr) : "-none-",
07678          ntohs(iterator->addr.sin_port), 
07679          ast_test_flag(&iterator->flags_page2, SIP_PAGE2_DYNAMIC) ? "yes" : "no",  /* Dynamic or not? */
07680          (ast_test_flag(iterator, SIP_NAT) & SIP_NAT_ROUTE) ? "yes" : "no",   /* NAT=yes? */
07681          iterator->ha ? "yes" : "no",       /* permit/deny */
07682          status);
07683       }
07684 
07685       ASTOBJ_UNLOCK(iterator);
07686 
07687       total_peers++;
07688    } while(0) );
07689 
07690    if (!s) {
07691       ast_cli(fd,"%d sip peers [%d online , %d offline]\n",total_peers,peers_online,peers_offline);
07692    }
07693 
07694    if (havepattern)
07695       regfree(&regexbuf);
07696 
07697    if (total)
07698       *total = total_peers;
07699    
07700 
07701    return RESULT_SUCCESS;
07702 #undef FORMAT
07703 #undef FORMAT2
07704 }

static int add_blank_header struct sip_request req  )  [static]
 

add_blank_header: Add blank header to SIP message

Definition at line 3797 of file chan_sip.c.

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

Referenced by __transmit_response(), sip_notify(), transmit_invite(), transmit_refer(), transmit_register(), transmit_request(), transmit_request_with_auth(), transmit_response_with_allow(), transmit_response_with_auth(), and transmit_response_with_date().

03798 {
03799    if (req->headers == SIP_MAX_HEADERS)  {
03800       ast_log(LOG_WARNING, "Out of SIP header space\n");
03801       return -1;
03802    }
03803    if (req->lines) {
03804       ast_log(LOG_WARNING, "Can't add more headers when lines have been added\n");
03805       return -1;
03806    }
03807    if (req->len >= sizeof(req->data) - 4) {
03808       ast_log(LOG_WARNING, "Out of space, can't add anymore\n");
03809       return -1;
03810    }
03811    req->header[req->headers] = req->data + req->len;
03812    snprintf(req->header[req->headers], sizeof(req->data) - req->len, "\r\n");
03813    req->len += strlen(req->header[req->headers]);
03814    req->headers++;
03815    return 0;   
03816 }

static void add_codec_to_sdp const struct sip_pvt p,
int  codec,
int  sample_rate,
char **  m_buf,
size_t *  m_size,
char **  a_buf,
size_t *  a_size,
int  debug
[static]
 

Definition at line 4349 of file chan_sip.c.

References ast_build_string(), AST_FORMAT_G729A, ast_getformatname(), ast_rtp_lookup_code(), ast_rtp_lookup_mime_subtype(), ast_verbose(), and sip_pvt::rtp.

Referenced by add_sdp().

04352 {
04353    int rtp_code;
04354 
04355    if (debug)
04356       ast_verbose("Adding codec 0x%x (%s) to SDP\n", codec, ast_getformatname(codec));
04357    if ((rtp_code = ast_rtp_lookup_code(p->rtp, 1, codec)) == -1)
04358       return;
04359 
04360    ast_build_string(m_buf, m_size, " %d", rtp_code);
04361    ast_build_string(a_buf, a_size, "a=rtpmap:%d %s/%d\r\n", rtp_code,
04362           ast_rtp_lookup_mime_subtype(1, codec),
04363           sample_rate);
04364    if (codec == AST_FORMAT_G729A)
04365       /* Indicate that we don't support VAD (G.729 annex B) */
04366       ast_build_string(a_buf, a_size, "a=fmtp:%d annexb=no\r\n", rtp_code);
04367 }

static int add_digit struct sip_request req,
char  digit
[static]
 

add_digit: add DTMF INFO tone to sip message ---

Definition at line 4318 of file chan_sip.c.

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

Referenced by transmit_info_with_digit().

04319 {
04320    char tmp[256];
04321 
04322    snprintf(tmp, sizeof(tmp), "Signal=%c\r\nDuration=250\r\n", digit);
04323    add_header(req, "Content-Type", "application/dtmf-relay");
04324    add_header_contentLength(req, strlen(tmp));
04325    add_line(req, tmp);
04326    return 0;
04327 }

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

add_header: Add header to SIP message

Definition at line 3753 of file chan_sip.c.

References aliases, ast_log(), compactheaders, sip_request::data, sip_request::header, sip_request::headers, sip_request::len, sip_request::lines, LOG_WARNING, and SIP_MAX_HEADERS.

03754 {
03755    int x = 0;
03756 
03757    if (req->headers == SIP_MAX_HEADERS) {
03758       ast_log(LOG_WARNING, "Out of SIP header space\n");
03759       return -1;
03760    }
03761 
03762    if (req->lines) {
03763       ast_log(LOG_WARNING, "Can't add more headers when lines have been added\n");
03764       return -1;
03765    }
03766 
03767    if (req->len >= sizeof(req->data) - 4) {
03768       ast_log(LOG_WARNING, "Out of space, can't add anymore (%s:%s)\n", var, value);
03769       return -1;
03770    }
03771 
03772    req->header[req->headers] = req->data + req->len;
03773 
03774    if (compactheaders) {
03775       for (x = 0; x < (sizeof(aliases) / sizeof(aliases[0])); x++)
03776          if (!strcasecmp(aliases[x].fullname, var))
03777             var = aliases[x].shortname;
03778    }
03779 
03780    snprintf(req->header[req->headers], sizeof(req->data) - req->len - 4, "%s: %s\r\n", var, value);
03781    req->len += strlen(req->header[req->headers]);
03782    req->headers++;
03783 
03784    return 0;   
03785 }

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

add_header_contentLen: Add 'Content-Length' header to SIP message

Definition at line 3788 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(), and transmit_state_notify().

03789 {
03790    char clen[10];
03791 
03792    snprintf(clen, sizeof(clen), "%d", len);
03793    return add_header(req, "Content-Length", clen);
03794 }

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

add_line: Add content (not header) to SIP message

Definition at line 3819 of file chan_sip.c.

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

03820 {
03821    if (req->lines == SIP_MAX_LINES)  {
03822       ast_log(LOG_WARNING, "Out of SIP line space\n");
03823       return -1;
03824    }
03825    if (!req->lines) {
03826       /* Add extra empty return */
03827       snprintf(req->data + req->len, sizeof(req->data) - req->len, "\r\n");
03828       req->len += strlen(req->data + req->len);
03829    }
03830    if (req->len >= sizeof(req->data) - 4) {
03831       ast_log(LOG_WARNING, "Out of space, can't add anymore\n");
03832       return -1;
03833    }
03834    req->line[req->lines] = req->data + req->len;
03835    snprintf(req->line[req->lines], sizeof(req->data) - req->len, "%s", line);
03836    req->len += strlen(req->line[req->lines]);
03837    req->lines++;
03838    return 0;   
03839 }

static void add_noncodec_to_sdp const struct sip_pvt p,
int  format,
int  sample_rate,
char **  m_buf,
size_t *  m_size,
char **  a_buf,
size_t *  a_size,
int  debug
[static]
 

Definition at line 4369 of file chan_sip.c.

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

Referenced by add_sdp().

04372 {
04373    int rtp_code;
04374 
04375    if (debug)
04376       ast_verbose("Adding non-codec 0x%x (%s) to SDP\n", format, ast_rtp_lookup_mime_subtype(0, format));
04377    if ((rtp_code = ast_rtp_lookup_code(p->rtp, 0, format)) == -1)
04378       return;
04379 
04380    ast_build_string(m_buf, m_size, " %d", rtp_code);
04381    ast_build_string(a_buf, a_size, "a=rtpmap:%d %s/%d\r\n", rtp_code,
04382           ast_rtp_lookup_mime_subtype(0, format),
04383           sample_rate);
04384    if (format == AST_RTP_DTMF)
04385       /* Indicate we support DTMF and FLASH... */
04386       ast_build_string(a_buf, a_size, "a=fmtp:%d 0-16\r\n", rtp_code);
04387 }

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

add_realm_authentication: Add realm authentication in list ---

Definition at line 11967 of file chan_sip.c.

References ast_log(), ast_strlen_zero(), ast_verbose(), LOG_DEBUG, LOG_ERROR, LOG_WARNING, malloc, sip_auth::md5secret, sip_auth::next, option_verbose, sip_auth::realm, secret, strsep(), and username.

Referenced by build_peer(), and reload_config().

11968 {
11969    char authcopy[256];
11970    char *username=NULL, *realm=NULL, *secret=NULL, *md5secret=NULL;
11971    char *stringp;
11972    struct sip_auth *auth;
11973    struct sip_auth *b = NULL, *a = authlist;
11974 
11975    if (ast_strlen_zero(configuration))
11976       return authlist;
11977 
11978    ast_log(LOG_DEBUG, "Auth config ::  %s\n", configuration);
11979 
11980    ast_copy_string(authcopy, configuration, sizeof(authcopy));
11981    stringp = authcopy;
11982 
11983    username = stringp;
11984    realm = strrchr(stringp, '@');
11985    if (realm) {
11986       *realm = '\0';
11987       realm++;
11988    }
11989    if (ast_strlen_zero(username) || ast_strlen_zero(realm)) {
11990       ast_log(LOG_WARNING, "Format for authentication entry is user[:secret]@realm at line %d\n", lineno);
11991       return authlist;
11992    }
11993    stringp = username;
11994    username = strsep(&stringp, ":");
11995    if (username) {
11996       secret = strsep(&stringp, ":");
11997       if (!secret) {
11998          stringp = username;
11999          md5secret = strsep(&stringp,"#");
12000       }
12001    }
12002    auth = malloc(sizeof(struct sip_auth));
12003    if (auth) {
12004       memset(auth, 0, sizeof(struct sip_auth));
12005       ast_copy_string(auth->realm, realm, sizeof(auth->realm));
12006       ast_copy_string(auth->username, username, sizeof(auth->username));
12007       if (secret)
12008          ast_copy_string(auth->secret, secret, sizeof(auth->secret));
12009       if (md5secret)
12010          ast_copy_string(auth->md5secret, md5secret, sizeof(auth->md5secret));
12011    } else {
12012       ast_log(LOG_ERROR, "Allocation of auth structure failed, Out of memory\n");
12013       return authlist;
12014    }
12015 
12016    /* Add authentication to authl */
12017    if (!authlist) {  /* No existing list */
12018       return auth;
12019    } 
12020    while(a) {
12021       b = a;
12022       a = a->next;
12023    }
12024    b->next = auth;   /* Add structure add end of list */
12025 
12026    if (option_verbose > 2)
12027       ast_verbose("Added authentication for realm %s\n", realm);
12028 
12029    return authlist;
12030 
12031 }

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

add_route: Add route header into request per learned route ---

Definition at line 3937 of file chan_sip.c.

References add_header(), and n.

Referenced by reqprep().

03938 {
03939    char r[BUFSIZ*2], *p;
03940    int n, rem = sizeof(r);
03941 
03942    if (!route) return;
03943 
03944    p = r;
03945    while (route) {
03946       n = strlen(route->hop);
03947       if ((n+3)>rem) break;
03948       if (p != r) {
03949          *p++ = ',';
03950          --rem;
03951       }
03952       *p++ = '<';
03953       ast_copy_string(p, route->hop, rem);  p += n;
03954       *p++ = '>';
03955       rem -= (n+2);
03956       route = route->next;
03957    }
03958    *p = '\0';
03959    add_header(req, "Route", r);
03960 }

static int add_sdp struct sip_request resp,
struct sip_pvt p
[static]
 

add_sdp: Add Session Description Protocol message ---

Definition at line 4390 of file chan_sip.c.

References add_codec_to_sdp(), add_header(), add_header_contentLength(), add_line(), add_noncodec_to_sdp(), ast_build_string(), ast_codec_pref_index(), AST_FORMAT_MAX_AUDIO, AST_FORMAT_MAX_VIDEO, ast_inet_ntoa(), ast_log(), ast_rtp_get_us(), AST_RTP_MAX, ast_test_flag, ast_verbose(), capability, debug, sip_pvt::jointcapability, sip_pvt::lastrtprx, sip_pvt::lastrtptx, sip_request::len, LOG_WARNING, sip_pvt::noncodeccapability, sip_pvt::ourip, sip_pvt::prefcodec, sip_pvt::prefs, sip_pvt::redircodecs, sip_pvt::redirip, sip_pvt::rtp, s, sip_pvt::sessionid, sip_pvt::sessionversion, sip_debug_test_pvt(), SIP_NOVIDEO, t, VIDEO_CODEC_MASK, sip_pvt::vredirip, and sip_pvt::vrtp.

04391 {
04392    int len = 0;
04393    int pref_codec;
04394    int alreadysent = 0;
04395    struct sockaddr_in sin;
04396    struct sockaddr_in vsin;
04397    char v[256];
04398    char s[256];
04399    char o[256];
04400    char c[256];
04401    char t[256];
04402    char m_audio[256];
04403    char m_video[256];
04404    char a_audio[1024];
04405    char a_video[1024];
04406    char *m_audio_next = m_audio;
04407    char *m_video_next = m_video;
04408    size_t m_audio_left = sizeof(m_audio);
04409    size_t m_video_left = sizeof(m_video);
04410    char *a_audio_next = a_audio;
04411    char *a_video_next = a_video;
04412    size_t a_audio_left = sizeof(a_audio);
04413    size_t a_video_left = sizeof(a_video);
04414    char iabuf[INET_ADDRSTRLEN];
04415    int x;
04416    int capability;
04417    struct sockaddr_in dest;
04418    struct sockaddr_in vdest = { 0, };
04419    int debug;
04420    
04421    debug = sip_debug_test_pvt(p);
04422 
04423    len = 0;
04424    if (!p->rtp) {
04425       ast_log(LOG_WARNING, "No way to add SDP without an RTP structure\n");
04426       return -1;
04427    }
04428    capability = p->jointcapability;
04429       
04430    if (!p->sessionid) {
04431       p->sessionid = getpid();
04432       p->sessionversion = p->sessionid;
04433    } else
04434       p->sessionversion++;
04435    ast_rtp_get_us(p->rtp, &sin);
04436    if (p->vrtp)
04437       ast_rtp_get_us(p->vrtp, &vsin);
04438 
04439    if (p->redirip.sin_addr.s_addr) {
04440       dest.sin_port = p->redirip.sin_port;
04441       dest.sin_addr = p->redirip.sin_addr;
04442       if (p->redircodecs)
04443          capability = p->redircodecs;
04444    } else {
04445       dest.sin_addr = p->ourip;
04446       dest.sin_port = sin.sin_port;
04447    }
04448 
04449    /* Determine video destination */
04450    if (p->vrtp) {
04451       if (p->vredirip.sin_addr.s_addr) {
04452          vdest.sin_port = p->vredirip.sin_port;
04453          vdest.sin_addr = p->vredirip.sin_addr;
04454       } else {
04455          vdest.sin_addr = p->ourip;
04456          vdest.sin_port = vsin.sin_port;
04457       }
04458    }
04459    if (debug){
04460       ast_verbose("We're at %s port %d\n", ast_inet_ntoa(iabuf, sizeof(iabuf), p->ourip), ntohs(sin.sin_port));   
04461       if (p->vrtp)
04462          ast_verbose("Video is at %s port %d\n", ast_inet_ntoa(iabuf, sizeof(iabuf), p->ourip), ntohs(vsin.sin_port));  
04463    }
04464 
04465    /* We break with the "recommendation" and send our IP, in order that our
04466       peer doesn't have to ast_gethostbyname() us */
04467 
04468    snprintf(v, sizeof(v), "v=0\r\n");
04469    snprintf(o, sizeof(o), "o=root %d %d IN IP4 %s\r\n", p->sessionid, p->sessionversion, ast_inet_ntoa(iabuf, sizeof(iabuf), dest.sin_addr));
04470    snprintf(s, sizeof(s), "s=session\r\n");
04471    snprintf(c, sizeof(c), "c=IN IP4 %s\r\n", ast_inet_ntoa(iabuf, sizeof(iabuf), dest.sin_addr));
04472    snprintf(t, sizeof(t), "t=0 0\r\n");
04473 
04474    ast_build_string(&m_audio_next, &m_audio_left, "m=audio %d RTP/AVP", ntohs(dest.sin_port));
04475    ast_build_string(&m_video_next, &m_video_left, "m=video %d RTP/AVP", ntohs(vdest.sin_port));
04476 
04477    /* Prefer the codec we were requested to use, first, no matter what */
04478    if (capability & p->prefcodec) {
04479       if (p->prefcodec <= AST_FORMAT_MAX_AUDIO)
04480          add_codec_to_sdp(p, p->prefcodec, 8000,
04481                 &m_audio_next, &m_audio_left,
04482                 &a_audio_next, &a_audio_left,
04483                 debug);
04484       else
04485          add_codec_to_sdp(p, p->prefcodec, 90000,
04486                 &m_video_next, &m_video_left,
04487                 &a_video_next, &a_video_left,
04488                 debug);
04489       alreadysent |= p->prefcodec;
04490    }
04491 
04492    /* Start by sending our preferred codecs */
04493    for (x = 0; x < 32; x++) {
04494       if (!(pref_codec = ast_codec_pref_index(&p->prefs, x)))
04495          break; 
04496 
04497       if (!(capability & pref_codec))
04498          continue;
04499 
04500       if (alreadysent & pref_codec)
04501          continue;
04502 
04503       if (pref_codec <= AST_FORMAT_MAX_AUDIO)
04504          add_codec_to_sdp(p, pref_codec, 8000,
04505                 &m_audio_next, &m_audio_left,
04506                 &a_audio_next, &a_audio_left,
04507                 debug);
04508       else
04509          add_codec_to_sdp(p, pref_codec, 90000,
04510                 &m_video_next, &m_video_left,
04511                 &a_video_next, &a_video_left,
04512                 debug);
04513       alreadysent |= pref_codec;
04514    }
04515 
04516    /* Now send any other common codecs, and non-codec formats: */
04517    for (x = 1; x <= ((videosupport && p->vrtp) ? AST_FORMAT_MAX_VIDEO : AST_FORMAT_MAX_AUDIO); x <<= 1) {
04518       if (!(capability & x))
04519          continue;
04520 
04521       if (alreadysent & x)
04522          continue;
04523 
04524       if (x <= AST_FORMAT_MAX_AUDIO)
04525          add_codec_to_sdp(p, x, 8000,
04526                 &m_audio_next, &m_audio_left,
04527                 &a_audio_next, &a_audio_left,
04528                 debug);
04529       else
04530          add_codec_to_sdp(p, x, 90000,
04531                 &m_video_next, &m_video_left,
04532                 &a_video_next, &a_video_left,
04533                 debug);
04534    }
04535 
04536    for (x = 1; x <= AST_RTP_MAX; x <<= 1) {
04537       if (!(p->noncodeccapability & x))
04538          continue;
04539 
04540       add_noncodec_to_sdp(p, x, 8000,
04541                 &m_audio_next, &m_audio_left,
04542                 &a_audio_next, &a_audio_left,
04543                 debug);
04544    }
04545 
04546    ast_build_string(&a_audio_next, &a_audio_left, "a=silenceSupp:off - - - -\r\n");
04547 
04548    if ((m_audio_left < 2) || (m_video_left < 2) || (a_audio_left == 0) || (a_video_left == 0))
04549       ast_log(LOG_WARNING, "SIP SDP may be truncated due to undersized buffer!!\n");
04550 
04551    ast_build_string(&m_audio_next, &m_audio_left, "\r\n");
04552    ast_build_string(&m_video_next, &m_video_left, "\r\n");
04553 
04554    len = strlen(v) + strlen(s) + strlen(o) + strlen(c) + strlen(t) + strlen(m_audio) + strlen(a_audio);
04555    if ((p->vrtp) && (!ast_test_flag(p, SIP_NOVIDEO)) && (capability & VIDEO_CODEC_MASK)) /* only if video response is appropriate */
04556       len += strlen(m_video) + strlen(a_video);
04557 
04558    add_header(resp, "Content-Type", "application/sdp");
04559    add_header_contentLength(resp, len);
04560    add_line(resp, v);
04561    add_line(resp, o);
04562    add_line(resp, s);
04563    add_line(resp, c);
04564    add_line(resp, t);
04565    add_line(resp, m_audio);
04566    add_line(resp, a_audio);
04567    if ((p->vrtp) && (!ast_test_flag(p, SIP_NOVIDEO)) && (capability & VIDEO_CODEC_MASK)) { /* only if video response is appropriate */
04568       add_line(resp, m_video);
04569       add_line(resp, a_video);
04570    }
04571 
04572    /* Update lastrtprx when we send our SDP */
04573    time(&p->lastrtprx);
04574    time(&p->lastrtptx);
04575 
04576    return 0;
04577 }

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

add_sip_domain: Add SIP domain to list of domains we are responsible for

Definition at line 11900 of file chan_sip.c.

References AST_LIST_INSERT_TAIL, AST_LIST_LOCK, AST_LIST_UNLOCK, ast_log(), ast_strlen_zero(), calloc, list, LOG_DEBUG, LOG_ERROR, LOG_WARNING, and sipdebug.

Referenced by reload_config().

11901 {
11902    struct domain *d;
11903 
11904    if (ast_strlen_zero(domain)) {
11905       ast_log(LOG_WARNING, "Zero length domain.\n");
11906       return 1;
11907    }
11908 
11909    d = calloc(1, sizeof(*d));
11910    if (!d) {
11911       ast_log(LOG_ERROR, "Allocation of domain structure failed, Out of memory\n");
11912       return 0;
11913    }
11914 
11915    ast_copy_string(d->domain, domain, sizeof(d->domain));
11916 
11917    if (!ast_strlen_zero(context))
11918       ast_copy_string(d->context, context, sizeof(d->context));
11919 
11920    d->mode = mode;
11921 
11922    AST_LIST_LOCK(&domain_list);
11923    AST_LIST_INSERT_TAIL(&domain_list, d, list);
11924    AST_LIST_UNLOCK(&domain_list);
11925 
11926    if (sipdebug)  
11927       ast_log(LOG_DEBUG, "Added local SIP domain '%s'\n", domain);
11928 
11929    return 1;
11930 }

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

add_text: Add text body to SIP message ---

Definition at line 4307 of file chan_sip.c.

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

Referenced by transmit_message_with_text().

04308 {
04309    /* XXX Convert \n's to \r\n's XXX */
04310    add_header(req, "Content-Type", "text/plain");
04311    add_header_contentLength(req, strlen(text));
04312    add_line(req, text);
04313    return 0;
04314 }

static int add_vidupdate struct sip_request req  )  [static]
 

add_vidupdate: add XML encoded media control with update ---

Definition at line 4331 of file chan_sip.c.

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

Referenced by transmit_info_with_vidupdate().

04332 {
04333    const char *xml_is_a_huge_waste_of_space =
04334       "<?xml version=\"1.0\" encoding=\"utf-8\" ?>\r\n"
04335       " <media_control>\r\n"
04336       "  <vc_primitive>\r\n"
04337       "   <to_encoder>\r\n"
04338       "    <picture_fast_update>\r\n"
04339       "    </picture_fast_update>\r\n"
04340       "   </to_encoder>\r\n"
04341       "  </vc_primitive>\r\n"
04342       " </media_control>\r\n";
04343    add_header(req, "Content-Type", "application/media_control+xml");
04344    add_header_contentLength(req, strlen(xml_is_a_huge_waste_of_space));
04345    add_line(req, xml_is_a_huge_waste_of_space);
04346    return 0;
04347 }

static void append_date struct sip_request req  )  [static]
 

append_date: Append date to SIP message ---

Definition at line 4251 of file chan_sip.c.

References add_header(), and t.

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

04252 {
04253    char tmpdat[256];
04254    struct tm tm;
04255    time_t t;
04256 
04257    time(&t);
04258    gmtime_r(&t, &tm);
04259    strftime(tmpdat, sizeof(tmpdat), "%a, %d %b %Y %T GMT", &tm);
04260    add_header(req, "Date", tmpdat);
04261 }

static int append_history struct sip_pvt p,
const char *  event,
const char *  data
[static]
 

append_history: Append to SIP dialog history

Definition at line 1129 of file chan_sip.c.

References ast_log(), sip_history::event, sip_pvt::history, LOG_WARNING, malloc, sip_history::next, and recordhistory.

Referenced by __sip_autodestruct(), cb_extensionstate(), do_register_auth(), handle_request_subscribe(), process_sdp(), retrans_pkt(), send_request(), send_response(), sip_cancel_destroy(), sip_reregister(), sip_scheddestroy(), sipsock_read(), and transmit_register().

01130 {
01131    struct sip_history *hist, *prev;
01132    char *c;
01133 
01134    if (!recordhistory || !p)
01135       return 0;
01136    if(!(hist = malloc(sizeof(struct sip_history)))) {
01137       ast_log(LOG_WARNING, "Can't allocate memory for history");
01138       return 0;
01139    }
01140    memset(hist, 0, sizeof(struct sip_history));
01141    snprintf(hist->event, sizeof(hist->event), "%-15s %s", event, data);
01142    /* Trim up nicely */
01143    c = hist->event;
01144    while(*c) {
01145       if ((*c == '\r') || (*c == '\n')) {
01146          *c = '\0';
01147          break;
01148       }
01149       c++;
01150    }
01151    /* Enqueue into history */
01152    prev = p->history;
01153    if (prev) {
01154       while(prev->next)
01155          prev = prev->next;
01156       prev->next = hist;
01157    } else {
01158       p->history = hist;
01159    }
01160    return 0;
01161 }

static AST_LIST_HEAD_STATIC domain_list  ,
domain 
[static]
 

The SIP domain list

AST_MUTEX_DEFINE_STATIC sip_reload_lock   ) 
 

AST_MUTEX_DEFINE_STATIC monlock   ) 
 

AST_MUTEX_DEFINE_STATIC netlock   ) 
 

Protect the monitoring thread, so only one process can kill or start it, and not when it's doing something critical.

AST_MUTEX_DEFINE_STATIC iflock   ) 
 

Protect the interface list (of sip_pvt's).

AST_MUTEX_DEFINE_STATIC rand_lock   ) 
 

AST_MUTEX_DEFINE_STATIC usecnt_lock   ) 
 

static void ast_quiet_chan struct ast_channel chan  )  [static]
 

ast_quiet_chan: Turn off generator data

Definition at line 10264 of file chan_sip.c.

References ast_channel::_state, ast_deactivate_generator(), AST_STATE_UP, and ast_channel::generatordata.

Referenced by attempt_transfer().

10265 {
10266    if (chan && chan->_state == AST_STATE_UP) {
10267       if (chan->generatordata)
10268          ast_deactivate_generator(chan);
10269    }
10270 }

static int ast_sip_ouraddrfor struct in_addr *  them,
struct in_addr *  us
[static]
 

ast_sip_ouraddrfor: NAT fix - decide which IP address to use for ASterisk server? ---

Definition at line 1094 of file chan_sip.c.

References ast_apply_ha(), ast_gethostbyname(), ast_inet_ntoa(), ast_log(), ast_ouraddrfor(), externexpire, externhost, externrefresh, hp, localaddr, LOG_DEBUG, and LOG_NOTICE.

Referenced by sip_alloc(), sip_notify(), sip_poke_peer(), sip_request_call(), sip_send_mwi_to_peer(), and transmit_register().

01095 {
01096    /*
01097     * Using the localaddr structure built up with localnet statements
01098     * apply it to their address to see if we need to substitute our
01099     * externip or can get away with our internal bindaddr
01100     */
01101    struct sockaddr_in theirs;
01102    theirs.sin_addr = *them;
01103    if (localaddr && externip.sin_addr.s_addr &&
01104       ast_apply_ha(localaddr, &theirs)) {
01105       char iabuf[INET_ADDRSTRLEN];
01106       if (externexpire && (time(NULL) >= externexpire)) {
01107          struct ast_hostent ahp;
01108          struct hostent *hp;
01109          time(&externexpire);
01110          externexpire += externrefresh;
01111          if ((hp = ast_gethostbyname(externhost, &ahp))) {
01112             memcpy(&externip.sin_addr, hp->h_addr, sizeof(externip.sin_addr));
01113          } else
01114             ast_log(LOG_NOTICE, "Warning: Re-lookup of '%s' failed!\n", externhost);
01115       }
01116       memcpy(us, &externip.sin_addr, sizeof(struct in_addr));
01117       ast_inet_ntoa(iabuf, sizeof(iabuf), *(struct in_addr *)&them->s_addr);
01118       ast_log(LOG_DEBUG, "Target address %s is not local, substituting externip\n", iabuf);
01119    }
01120    else if (bindaddr.sin_addr.s_addr)
01121       memcpy(us, &bindaddr.sin_addr, sizeof(struct in_addr));
01122    else
01123       return ast_ouraddrfor(them, us);
01124    return 0;
01125 }

static int attempt_transfer struct sip_pvt p1,
struct sip_pvt p2
[static]
 

attempt_transfer: Attempt transfer of SIP call ---

Definition at line 10273 of file chan_sip.c.

References ast_bridged_channel(), ast_cdr_append(), ast_channel_masquerade(), ast_log(), ast_quiet_chan(), AST_SOFTHANGUP_DEV, ast_softhangup_nolock(), LOG_NOTICE, LOG_WARNING, and sip_pvt::owner.

10274 {
10275    int res = 0;
10276    struct ast_channel 
10277       *chana = NULL,
10278       *chanb = NULL,
10279       *bridgea = NULL,
10280       *bridgeb = NULL,
10281       *peera = NULL,
10282       *peerb = NULL,
10283       *peerc = NULL,
10284       *peerd = NULL;
10285 
10286    if (!p1->owner || !p2->owner) {
10287       ast_log(LOG_WARNING, "Transfer attempted without dual ownership?\n");
10288       return -1;
10289    }
10290    chana = p1->owner;
10291    chanb = p2->owner;
10292    bridgea = ast_bridged_channel(chana);
10293    bridgeb = ast_bridged_channel(chanb);
10294    
10295    if (bridgea) {
10296       peera = chana;
10297       peerb = chanb;
10298       peerc = bridgea;
10299       peerd = bridgeb;
10300    } else if (bridgeb) {
10301       peera = chanb;
10302       peerb = chana;
10303       peerc = bridgeb;
10304       peerd = bridgea;
10305    }
10306    
10307    if (peera && peerb && peerc && (peerb != peerc)) {
10308       ast_quiet_chan(peera);
10309       ast_quiet_chan(peerb);
10310       ast_quiet_chan(peerc);
10311       ast_quiet_chan(peerd);
10312 
10313       if (peera->cdr && peerb->cdr) {
10314          peerb->cdr = ast_cdr_append(peerb->cdr, peera->cdr);
10315       } else if (peera->cdr) {
10316          peerb->cdr = peera->cdr;
10317       }
10318       peera->cdr = NULL;
10319 
10320       if (peerb->cdr && peerc->cdr) {
10321          peerb->cdr = ast_cdr_append(peerb->cdr, peerc->cdr);
10322       } else if (peerc->cdr) {
10323          peerb->cdr = peerc->cdr;
10324       }
10325       peerc->cdr = NULL;
10326       
10327       if (ast_channel_masquerade(peerb, peerc)) {
10328          ast_log(LOG_WARNING, "Failed to masquerade %s into %s\n", peerb->name, peerc->name);
10329          res = -1;
10330       }
10331       return res;
10332    } else {
10333       ast_log(LOG_NOTICE, "Transfer attempted with no appropriate bridged calls to transfer\n");
10334       if (chana)
10335          ast_softhangup_nolock(chana, AST_SOFTHANGUP_DEV);
10336       if (chanb)
10337          ast_softhangup_nolock(chanb, AST_SOFTHANGUP_DEV);
10338       return -1;
10339    }
10340    return 0;
10341 }

static int auto_congest void *  nothing  )  [static]
 

auto_congest: Scheduled congestion on a call ---

Definition at line 1990 of file chan_sip.c.

References AST_CONTROL_CONGESTION, ast_log(), ast_mutex_lock(), ast_mutex_trylock(), ast_mutex_unlock(), ast_queue_control(), sip_pvt::initid, ast_channel::lock, sip_pvt::lock, LOG_NOTICE, ast_channel::name, and sip_pvt::owner.

01991 {
01992    struct sip_pvt *p = nothing;
01993    ast_mutex_lock(&p->lock);
01994    p->initid = -1;
01995    if (p->owner) {
01996       if (!ast_mutex_trylock(&p->owner->lock)) {
01997          ast_log(LOG_NOTICE, "Auto-congesting %s\n", p->owner->name);
01998          ast_queue_control(p->owner, AST_CONTROL_CONGESTION);
01999          ast_mutex_unlock(&p->owner->lock);
02000       }
02001    }
02002    ast_mutex_unlock(&p->lock);
02003    return 0;
02004 }

static void build_callid char *  callid,
int  len,
struct in_addr  ourip,
char *  fromdomain
[static]
 

build_callid: Build SIP CALLID header ---

Definition at line 3029 of file chan_sip.c.

References ast_inet_ntoa(), ast_strlen_zero(), and thread_safe_rand().

Referenced by sip_alloc(), sip_notify(), sip_poke_peer(), sip_request_call(), sip_send_mwi_to_peer(), and transmit_register().

03030 {
03031    int res;
03032    int val;
03033    int x;
03034    char iabuf[INET_ADDRSTRLEN];
03035    for (x=0; x<4; x++) {
03036       val = thread_safe_rand();
03037       res = snprintf(callid, len, "%08x", val);
03038       len -= res;
03039       callid += res;
03040    }
03041    if (!ast_strlen_zero(fromdomain))
03042       snprintf(callid, len, "@%s", fromdomain);
03043    else
03044    /* It's not important that we really use our right IP here... */
03045       snprintf(callid, len, "@%s", ast_inet_ntoa(iabuf, sizeof(iabuf), ourip));
03046 }

static void build_contact struct sip_pvt p  )  [static]
 

build_contact: Build contact header - the contact header we send out ---

Definition at line 4707 of file chan_sip.c.

References ast_inet_ntoa(), ast_strlen_zero(), sip_pvt::exten, sip_pvt::our_contact, sip_pvt::ourip, and ourport.

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

04708 {
04709    char iabuf[INET_ADDRSTRLEN];
04710 
04711    /* Construct Contact: header */
04712    if (ourport != 5060) /* Needs to be 5060, according to the RFC */
04713       snprintf(p->our_contact, sizeof(p->our_contact), "<sip:%s%s%s:%d>", p->exten, ast_strlen_zero(p->exten) ? "" : "@", ast_inet_ntoa(iabuf, sizeof(iabuf), p->ourip), ourport);
04714    else
04715       snprintf(p->our_contact, sizeof(p->our_contact), "<sip:%s%s%s>", p->exten, ast_strlen_zero(p->exten) ? "" : "@", ast_inet_ntoa(iabuf, sizeof(iabuf), p->ourip));
04716 }

static struct sip_peer * build_peer const char *  name,
struct ast_variable v,
int  realtime
[static]
 

build_peer: Build peer from config file ---

Definition at line 12197 of file chan_sip.c.

References sip_peer::accountcode, add_realm_authentication(), sip_peer::addr, sip_peer::amaflags, ast_append_ha(), ast_callerid_split(), ast_cdr_amaflags2int(), ast_clear_flag, ast_copy_flags, ast_free_ha(), ast_get_group(), ast_get_ip(), ast_get_ip_or_srv(), ast_log(), ast_parse_allow_disallow(), ast_parse_caller_presentation(), ast_sched_del(), ast_set2_flag, ast_set_flag, ast_strdupa, ast_strlen_zero(), ast_test_flag, ast_true(), ast_variable_new(), ast_variables_destroy(), ASTOBJ_CONTAINER_FIND_UNLINK_FULL, ASTOBJ_INIT, ASTOBJ_UNMARK, ASTOBJ_UNREF, sip_peer::auth, sip_peer::call_limit, sip_peer::callgroup, sip_peer::callingpres, sip_peer::capability, sip_peer::chanvars, sip_peer::cid_name, sip_peer::cid_num, sip_peer::context, sip_peer::defaddr, default_context, default_language, DEFAULT_MAXMS, default_qualify, DEFAULT_SIP_PORT, default_subscribecontext, destroy_association(), sip_peer::expire, ast_flags::flags, sip_peer::flags_page2, format, sip_peer::fromdomain, sip_peer::fromuser, sip_peer::fullcontact, global_capability, global_musicclass, global_rtpholdtimeout, global_rtpkeepalive, global_rtptimeout, global_vmexten, sip_peer::ha, handle_common_options(), sip_peer::language, sip_peer::lastmsgssent, ast_variable::lineno, LOG_DEBUG, LOG_WARNING, sip_peer::mailbox, malloc, sip_peer::maxms, sip_peer::md5secret, sip_peer::musicclass, ast_variable::name, ast_variable::next, option_debug, peerl, sip_peer::pickupgroup, sip_peer::prefs, reg_source_db(), sip_peer::regexten, rpeerobjs, sip_peer::rtpholdtimeout, sip_peer::rtpkeepalive, sip_peer::rtptimeout, sip_peer::secret, sip_destroy_peer(), SIP_FLAGS_TO_COPY, SIP_PAGE2_DYNAMIC, SIP_PAGE2_IGNOREREGEXPIRE, SIP_PAGE2_RT_FROMCONTACT, SIP_REALTIME, SIP_USEREQPHONE, speerobjs, sip_peer::subscribecontext, sip_peer::tohost, sip_peer::username, ast_variable::value, and sip_peer::vmexten.

12198 {
12199    struct sip_peer *peer = NULL;
12200    struct ast_ha *oldha = NULL;
12201    int obproxyfound=0;
12202    int found=0;
12203    int format=0;     /* Ama flags */
12204    time_t regseconds;
12205    char *varname = NULL, *varval = NULL;
12206    struct ast_variable *tmpvar = NULL;
12207    struct ast_flags peerflags = {(0)};
12208    struct ast_flags mask = {(0)};
12209 
12210 
12211    if (!realtime)
12212       /* Note we do NOT use find_peer here, to avoid realtime recursion */
12213       /* We also use a case-sensitive comparison (unlike find_peer) so
12214          that case changes made to the peer name will be properly handled
12215          during reload
12216       */
12217       peer = ASTOBJ_CONTAINER_FIND_UNLINK_FULL(&peerl, name, name, 0, 0, strcmp);
12218 
12219    if (peer) {
12220       /* Already in the list, remove it and it will be added back (or FREE'd)  */
12221       found++;
12222    } else {
12223       peer = malloc(sizeof(*peer));
12224       if (peer) {
12225          memset(peer, 0, sizeof(*peer));
12226          if (realtime)
12227             rpeerobjs++;
12228          else
12229             speerobjs++;
12230          ASTOBJ_INIT(peer);
12231          peer->expire = -1;
12232          peer->pokeexpire = -1;
12233       } else {
12234          ast_log(LOG_WARNING, "Can't allocate SIP peer memory\n");
12235       }
12236    }
12237    /* Note that our peer HAS had its reference count incrased */
12238    if (!peer)
12239       return NULL;
12240 
12241    peer->lastmsgssent = -1;
12242    if (!found) {
12243       if (name)
12244          ast_copy_string(peer->name, name, sizeof(peer->name));
12245       peer->addr.sin_port = htons(DEFAULT_SIP_PORT);
12246       peer->addr.sin_family = AF_INET;
12247       peer->defaddr.sin_family = AF_INET;
12248    }
12249    /* If we have channel variables, remove them (reload) */
12250    if (peer->chanvars) {
12251       ast_variables_destroy(peer->chanvars);
12252       peer->chanvars = NULL;
12253    }
12254    strcpy(peer->context, default_context);
12255    strcpy(peer->subscribecontext, default_subscribecontext);
12256    strcpy(peer->vmexten, global_vmexten);
12257    strcpy(peer->language, default_language);
12258    strcpy(peer->musicclass, global_musicclass);
12259    ast_copy_flags(peer, &global_flags, SIP_USEREQPHONE);
12260    peer->secret[0] = '\0';
12261    peer->md5secret[0] = '\0';
12262    peer->cid_num[0] = '\0';
12263    peer->cid_name[0] = '\0';
12264    peer->fromdomain[0] = '\0';
12265    peer->fromuser[0] = '\0';
12266    peer->regexten[0] = '\0';
12267    peer->mailbox[0] = '\0';
12268    peer->callgroup = 0;
12269    peer->pickupgroup = 0;
12270    peer->rtpkeepalive = global_rtpkeepalive;
12271    peer->maxms = default_qualify;
12272    peer->prefs = prefs;
12273    oldha = peer->ha;
12274    peer->ha = NULL;
12275    peer->addr.sin_family = AF_INET;
12276    ast_copy_flags(peer, &global_flags, SIP_FLAGS_TO_COPY);
12277    peer->capability = global_capability;
12278    peer->rtptimeout = global_rtptimeout;
12279    peer->rtpholdtimeout = global_rtpholdtimeout;
12280    while(v) {
12281       if (handle_common_options(&peerflags, &mask, v)) {
12282          v = v->next;
12283          continue;
12284       }
12285 
12286       if (realtime && !strcasecmp(v->name, "regseconds")) {
12287          if (sscanf(v->value, "%ld", (time_t *)&regseconds) != 1)
12288             regseconds = 0;
12289       } else if (realtime && !strcasecmp(v->name, "ipaddr") && !ast_strlen_zero(v->value) ) {
12290          inet_aton(v->value, &(peer->addr.sin_addr));
12291       } else if (realtime && !strcasecmp(v->name, "name"))
12292          ast_copy_string(peer->name, v->value, sizeof(peer->name));
12293       else if (realtime && !strcasecmp(v->name, "fullcontact")) {
12294          ast_copy_string(peer->fullcontact, v->value, sizeof(peer->fullcontact));
12295          ast_set_flag((&peer->flags_page2), SIP_PAGE2_RT_FROMCONTACT);
12296       } else if (!strcasecmp(v->name, "secret")) 
12297          ast_copy_string(peer->secret, v->value, sizeof(peer->secret));
12298       else if (!strcasecmp(v->name, "md5secret")) 
12299          ast_copy_string(peer->md5secret, v->value, sizeof(peer->md5secret));
12300       else if (!strcasecmp(v->name, "auth"))
12301          peer->auth = add_realm_authentication(peer->auth, v->value, v->lineno);
12302       else if (!strcasecmp(v->name, "callerid")) {
12303          ast_callerid_split(v->value, peer->cid_name, sizeof(peer->cid_name), peer->cid_num, sizeof(peer->cid_num));
12304       } else if (!strcasecmp(v->name, "context")) {
12305          ast_copy_string(peer->context, v->value, sizeof(peer->context));
12306       } else if (!strcasecmp(v->name, "subscribecontext")) {
12307          ast_copy_string(peer->subscribecontext, v->value, sizeof(peer->subscribecontext));
12308       } else if (!strcasecmp(v->name, "fromdomain"))
12309          ast_copy_string(peer->fromdomain, v->value, sizeof(peer->fromdomain));
12310       else if (!strcasecmp(v->name, "usereqphone"))
12311          ast_set2_flag(peer, ast_true(v->value), SIP_USEREQPHONE);
12312       else if (!strcasecmp(v->name, "fromuser"))
12313          ast_copy_string(peer->fromuser, v->value, sizeof(peer->fromuser));
12314       else if (!strcasecmp(v->name, "host") || !strcasecmp(v->name, "outboundproxy")) {
12315          if (!strcasecmp(v->value, "dynamic")) {
12316             if (!strcasecmp(v->name, "outboundproxy") || obproxyfound) {
12317                ast_log(LOG_WARNING, "You can't have a dynamic outbound proxy, you big silly head at line %d.\n", v->lineno);
12318             } else {
12319                /* They'll register with us */
12320                ast_set_flag(&peer->flags_page2, SIP_PAGE2_DYNAMIC);
12321                if (!found) {
12322                   /* Initialize stuff iff we're not found, otherwise
12323                      we keep going with what we had */
12324                   memset(&peer->addr.sin_addr, 0, 4);
12325                   if (peer->addr.sin_port) {
12326                      /* If we've already got a port, make it the default rather than absolute */
12327                      peer->defaddr.sin_port = peer->addr.sin_port;
12328                      peer->addr.sin_port = 0;
12329                   }
12330                }
12331             }
12332          } else {
12333             /* Non-dynamic.  Make sure we become that way if we're not */
12334             if (peer->expire > -1)
12335                ast_sched_del(sched, peer->expire);
12336             peer->expire = -1;
12337             ast_clear_flag(&peer->flags_page2, SIP_PAGE2_DYNAMIC);   
12338             if (!obproxyfound || !strcasecmp(v->name, "outboundproxy")) {
12339                if (ast_get_ip_or_srv(&peer->addr, v->value, "_sip._udp")) {
12340                   ASTOBJ_UNREF(peer, sip_destroy_peer);
12341                   return NULL;
12342                }
12343             }
12344             if (!strcasecmp(v->name, "outboundproxy"))
12345                obproxyfound=1;
12346             else {
12347                ast_copy_string(peer->tohost, v->value, sizeof(peer->tohost));
12348                if (!peer->addr.sin_port)
12349                   peer->addr.sin_port = htons(DEFAULT_SIP_PORT);
12350             }
12351          }
12352       } else if (!strcasecmp(v->name, "defaultip")) {
12353          if (ast_get_ip(&peer->defaddr, v->value)) {
12354             ASTOBJ_UNREF(peer, sip_destroy_peer);
12355             return NULL;
12356          }
12357       } else if (!strcasecmp(v->name, "permit") || !strcasecmp(v->name, "deny")) {
12358          peer->ha = ast_append_ha(v->name, v->value, peer->ha);
12359       } else if (!strcasecmp(v->name, "port")) {
12360          if (!realtime && ast_test_flag(&peer->flags_page2, SIP_PAGE2_DYNAMIC))
12361             peer->defaddr.sin_port = htons(atoi(v->value));
12362          else
12363             peer->addr.sin_port = htons(atoi(v->value));
12364       } else if (!strcasecmp(v->name, "callingpres")) {
12365          peer->callingpres = ast_parse_caller_presentation(v->value);
12366          if (peer->callingpres == -1)
12367             peer->callingpres = atoi(v->value);
12368       } else if (!strcasecmp(v->name, "username")) {
12369          ast_copy_string(peer->username, v->value, sizeof(peer->username));
12370       } else if (!strcasecmp(v->name, "language")) {
12371          ast_copy_string(peer->language, v->value, sizeof(peer->language));
12372       } else if (!strcasecmp(v->name, "regexten")) {
12373          ast_copy_string(peer->regexten, v->value, sizeof(peer->regexten));
12374       } else if (!strcasecmp(v->name, "call-limit") || !strcasecmp(v->name, "incominglimit")) {
12375          peer->call_limit = atoi(v->value);
12376          if (peer->call_limit < 0)
12377             peer->call_limit = 0;
12378       } else if (!strcasecmp(v->name, "amaflags")) {
12379          format = ast_cdr_amaflags2int(v->value);
12380          if (format < 0) {
12381             ast_log(LOG_WARNING, "Invalid AMA Flags for peer: %s at line %d\n", v->value, v->lineno);
12382          } else {
12383             peer->amaflags = format;
12384          }
12385       } else if (!strcasecmp(v->name, "accountcode")) {
12386          ast_copy_string(peer->accountcode, v->value, sizeof(peer->accountcode));
12387       } else if (!strcasecmp(v->name, "musicclass") || !strcasecmp(v->name, "musiconhold")) {
12388          ast_copy_string(peer->musicclass, v->value, sizeof(peer->musicclass));
12389       } else if (!strcasecmp(v->name, "mailbox")) {
12390          ast_copy_string(peer->mailbox, v->value, sizeof(peer->mailbox));
12391       } else if (!strcasecmp(v->name, "vmexten")) {
12392          ast_copy_string(peer->vmexten, v->value, sizeof(peer->vmexten));
12393       } else if (!strcasecmp(v->name, "callgroup")) {
12394          peer->callgroup = ast_get_group(v->value);
12395       } else if (!strcasecmp(v->name, "pickupgroup")) {
12396          peer->pickupgroup = ast_get_group(v->value);
12397       } else if (!strcasecmp(v->name, "allow")) {
12398          ast_parse_allow_disallow(&peer->prefs, &peer->capability, v->value, 1);
12399       } else if (!strcasecmp(v->name, "disallow")) {
12400          ast_parse_allow_disallow(&peer->prefs, &peer->capability, v->value, 0);
12401       } else if (!strcasecmp(v->name, "rtptimeout")) {
12402          if ((sscanf(v->value, "%d", &peer->rtptimeout) != 1) || (peer->rtptimeout < 0)) {
12403             ast_log(LOG_WARNING, "'%s' is not a valid RTP hold time at line %d.  Using default.\n", v->value, v->lineno);
12404             peer->rtptimeout = global_rtptimeout;
12405          }
12406       } else if (!strcasecmp(v->name, "rtpholdtimeout")) {
12407          if ((sscanf(v->value, "%d", &peer->rtpholdtimeout) != 1) || (peer->rtpholdtimeout < 0)) {
12408             ast_log(LOG_WARNING, "'%s' is not a valid RTP hold time at line %d.  Using default.\n", v->value, v->lineno);
12409             peer->rtpholdtimeout = global_rtpholdtimeout;
12410          }
12411       } else if (!strcasecmp(v->name, "rtpkeepalive")) {
12412          if ((sscanf(v->value, "%d", &peer->rtpkeepalive) != 1) || (peer->rtpkeepalive < 0)) {
12413             ast_log(LOG_WARNING, "'%s' is not a valid RTP keepalive time at line %d.  Using default.\n", v->value, v->lineno);
12414             peer->rtpkeepalive = global_rtpkeepalive;
12415          }
12416       } else if (!strcasecmp(v->name, "setvar")) {
12417          /* Set peer channel variable */
12418          varname = ast_strdupa(v->value);
12419          if (varname && (varval = strchr(varname,'='))) {
12420             *varval = '\0';
12421             varval++;
12422             if ((tmpvar = ast_variable_new(varname, varval))) {
12423                tmpvar->next = peer->chanvars;
12424                peer->chanvars = tmpvar;
12425             }
12426          }
12427       } else if (!strcasecmp(v->name, "qualify")) {
12428          if (!strcasecmp(v->value, "no")) {
12429             peer->maxms = 0;
12430          } else if (!strcasecmp(v->value, "yes")) {
12431             peer->maxms = DEFAULT_MAXMS;
12432          } else if (sscanf(v->value, "%d", &peer->maxms) != 1) {
12433             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);
12434             peer->maxms = 0;
12435          }
12436       }
12437       /* else if (strcasecmp(v->name,"type"))
12438        * ast_log(LOG_WARNING, "Ignoring %s\n", v->name);
12439        */
12440       v=v->next;
12441    }
12442    if (!ast_test_flag((&global_flags_page2), SIP_PAGE2_IGNOREREGEXPIRE) && ast_test_flag(&peer->flags_page2, SIP_PAGE2_DYNAMIC) && realtime) {
12443       time_t nowtime;
12444 
12445       time(&nowtime);
12446       if ((nowtime - regseconds) > 0) {
12447          destroy_association(peer);
12448          memset(&peer->addr, 0, sizeof(peer->addr));
12449          if (option_debug)
12450             ast_log(LOG_DEBUG, "Bah, we're expired (%d/%d/%d)!\n", (int)(nowtime - regseconds), (int)regseconds, (int)nowtime);
12451       }
12452    }
12453    ast_copy_flags(peer, &peerflags, mask.flags);
12454    if (!found && ast_test_flag(&peer->flags_page2, SIP_PAGE2_DYNAMIC) && !ast_test_flag(peer, SIP_REALTIME))
12455       reg_source_db(peer);
12456    ASTOBJ_UNMARK(peer);
12457    ast_free_ha(oldha);
12458    return peer;
12459 }

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

build_reply_digest: Build reply digest ---

Definition at line 9108 of file chan_sip.c.

References ast_inet_ntoa(), ast_log(), ast_md5_hash(), 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_pvt::peermd5secret, sip_pvt::peersecret, sip_pvt::qop, sip_pvt::realm, sip_pvt::sa, sip_auth::secret, secret, sip_methods, sipdebug, text, thread_safe_rand(), sip_pvt::uri, sip_auth::username, sip_pvt::username, and username.

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

09109 {
09110    char a1[256];
09111    char a2[256];
09112    char a1_hash[256];
09113    char a2_hash[256];
09114    char resp[256];
09115    char resp_hash[256];
09116    char uri[256];
09117    char cnonce[80];
09118    char iabuf[INET_ADDRSTRLEN];
09119    char *username;
09120    char *secret;
09121    char *md5secret;
09122    struct sip_auth *auth = (struct sip_auth *) NULL;  /* Realm authentication */
09123 
09124    if (!ast_strlen_zero(p->domain))
09125       ast_copy_string(uri, p->domain, sizeof(uri));
09126    else if (!ast_strlen_zero(p->uri))
09127       ast_copy_string(uri, p->uri, sizeof(uri));
09128    else
09129       snprintf(uri, sizeof(uri), "sip:%s@%s",p->username, ast_inet_ntoa(iabuf, sizeof(iabuf), p->sa.sin_addr));
09130 
09131    snprintf(cnonce, sizeof(cnonce), "%08x", thread_safe_rand());
09132 
09133    /* Check if we have separate auth credentials */
09134    if ((auth = find_realm_authentication(authl, p->realm))) {
09135       username = auth->username;
09136       secret = auth->secret;
09137       md5secret = auth->md5secret;
09138       if (sipdebug)
09139          ast_log(LOG_DEBUG,"Using realm %s authentication for call %s\n", p->realm, p->callid);
09140    } else {
09141       /* No authentication, use peer or register= config */
09142       username = p->authname;
09143       secret =  p->peersecret;
09144       md5secret = p->peermd5secret;
09145    }
09146    if (ast_strlen_zero(username))   /* We have no authentication */
09147       return -1;
09148  
09149 
09150    /* Calculate SIP digest response */
09151    snprintf(a1,sizeof(a1),"%s:%s:%s", username, p->realm, secret);
09152    snprintf(a2,sizeof(a2),"%s:%s", sip_methods[method].text, uri);
09153    if (!ast_strlen_zero(md5secret))
09154       ast_copy_string(a1_hash, md5secret, sizeof(a1_hash));
09155    else
09156       ast_md5_hash(a1_hash,a1);
09157    ast_md5_hash(a2_hash,a2);
09158 
09159    p->noncecount++;
09160    if (!ast_strlen_zero(p->qop))
09161       snprintf(resp,sizeof(resp),"%s:%s:%08x:%s:%s:%s", a1_hash, p->nonce, p->noncecount, cnonce, "auth", a2_hash);
09162    else
09163       snprintf(resp,sizeof(resp),"%s:%s:%s", a1_hash, p->nonce, a2_hash);
09164    ast_md5_hash(resp_hash, resp);
09165    /* XXX We hard code our qop to "auth" for now.  XXX */
09166    if (!ast_strlen_zero(p->qop))
09167       snprintf(digest, digest_len, "Digest username=\"%s\", realm=\"%s\", algorithm=MD5, uri=\"%s\", nonce=\"%s\", response=\"%s\", opaque=\"%s\", qop=auth, cnonce=\"%s\", nc=%08x", username, p->realm, uri, p->nonce, resp_hash, p->opaque, cnonce, p->noncecount);
09168    else
09169       snprintf(digest, digest_len, "Digest username=\"%s\", realm=\"%s\", algorithm=MD5, uri=\"%s\", nonce=\"%s\", response=\"%s\", opaque=\"%s\"", username, p->realm, uri, p->nonce, resp_hash, p->opaque);
09170 
09171    return 0;
09172 }

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

build_route: Build route list from Record-Route header ---

Definition at line 6065 of file chan_sip.c.

References __get_header(), ast_log(), ast_strlen_zero(), free_old_route(), get_header(), sip_route::hop, list_route(), LOG_DEBUG, malloc, sip_route::next, sip_pvt::route, sip_pvt::route_persistant, and sip_debug_test_pvt().

Referenced by handle_request_invite(), and handle_response_invite().

06066 {
06067    struct sip_route *thishop, *head, *tail;
06068    int start = 0;
06069    int len;
06070    char *rr, *contact, *c;
06071 
06072    /* Once a persistant route is set, don't fool with it */
06073    if (p->route && p->route_persistant) {
06074       ast_log(LOG_DEBUG, "build_route: Retaining previous route: <%s>\n", p->route->hop);
06075       return;
06076    }
06077 
06078    if (p->route) {
06079       free_old_route(p->route);
06080       p->route = NULL;
06081    }
06082    
06083    p->route_persistant = backwards;
06084    
06085    /* We build up head, then assign it to p->route when we're done */
06086    head = NULL;  tail = head;
06087    /* 1st we pass through all the hops in any Record-Route headers */
06088    for (;;) {
06089       /* Each Record-Route header */
06090       rr = __get_header(req, "Record-Route", &start);
06091       if (*rr == '\0') break;
06092       for (;;) {
06093          /* Each route entry */
06094          /* Find < */
06095          rr = strchr(rr, '<');
06096          if (!rr) break; /* No more hops */
06097          ++rr;
06098          len = strcspn(rr, ">") + 1;
06099          /* Make a struct route */
06100          thishop = malloc(sizeof(*thishop) + len);
06101          if (thishop) {
06102             ast_copy_string(thishop->hop, rr, len);
06103             ast_log(LOG_DEBUG, "build_route: Record-Route hop: <%s>\n", thishop->hop);
06104             /* Link in */
06105             if (backwards) {
06106                /* Link in at head so they end up in reverse order */
06107                thishop->next = head;
06108                head = thishop;
06109                /* If this was the first then it'll be the tail */
06110                if (!tail) tail = thishop;
06111             } else {
06112                thishop->next = NULL;
06113                /* Link in at the end */
06114                if (tail)
06115                   tail->next = thishop;
06116                else
06117                   head = thishop;
06118                tail = thishop;
06119             }
06120          }
06121          rr += len;
06122       }
06123    }
06124 
06125    /* Only append the contact if we are dealing with a strict router */
06126    if (!head || (!ast_strlen_zero(head->hop) && strstr(head->hop,";lr") == NULL) ) {
06127       /* 2nd append the Contact: if there is one */
06128       /* Can be multiple Contact headers, comma separated values - we just take the first */
06129       contact = get_header(req, "Contact");
06130       if (!ast_strlen_zero(contact)) {
06131          ast_log(LOG_DEBUG, "build_route: Contact hop: %s\n", contact);
06132          /* Look for <: delimited address */
06133          c = strchr(contact, '<');
06134          if (c) {
06135             /* Take to > */
06136             ++c;
06137             len = strcspn(c, ">") + 1;
06138          } else {
06139             /* No <> - just take the lot */
06140             c = contact;
06141             len = strlen(contact) + 1;
06142          }
06143          thishop = malloc(sizeof(*thishop) + len);
06144          if (thishop) {
06145             ast_copy_string(thishop->hop, c, len);
06146             thishop->next = NULL;
06147             /* Goes at the end */
06148             if (tail)
06149                tail->next = thishop;
06150             else
06151                head = thishop;
06152          }
06153       }
06154    }
06155 
06156    /* Store as new route */
06157    p->route = head;
06158 
06159    /* For debugging dump what we ended up with */
06160    if (sip_debug_test_pvt(p))
06161       list_route(p->route);
06162 }

static void build_rpid struct sip_pvt p  )  [static]
 

build_rpid: Build the Remote Party-ID & From using callingpres options ---

Definition at line 4719 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_strlen_zero(), sip_pvt::callingpres, ast_channel::cid, ast_callerid::cid_name, ast_callerid::cid_num, default_callerid, sip_pvt::fromdomain, sip_pvt::fromuser, LOG_WARNING, sip_pvt::ourip, sip_pvt::owner, sip_pvt::rpid, sip_pvt::rpid_from, strdup, and sip_pvt::tag.

Referenced by initreqprep().

04720 {
04721    int send_pres_tags = 1;
04722    const char *privacy=NULL;
04723    const char *screen=NULL;
04724    char buf[256];
04725    const char *clid = default_callerid;
04726    const char *clin = NULL;
04727    char iabuf[INET_ADDRSTRLEN];
04728    const char *fromdomain;
04729 
04730    if (p->rpid || p->rpid_from)
04731       return;
04732 
04733    if (p->owner && p->owner->cid.cid_num)
04734       clid = p->owner->cid.cid_num;
04735    if (p->owner && p->owner->cid.cid_name)
04736       clin = p->owner->cid.cid_name;
04737    if (ast_strlen_zero(clin))
04738       clin = clid;
04739 
04740    switch (p->callingpres) {
04741    case AST_PRES_ALLOWED_USER_NUMBER_NOT_SCREENED:
04742       privacy = "off";
04743       screen = "no";
04744       break;
04745    case AST_PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN:
04746       privacy = "off";
04747       screen = "pass";
04748       break;
04749    case AST_PRES_ALLOWED_USER_NUMBER_FAILED_SCREEN:
04750       privacy = "off";
04751       screen = "fail";
04752       break;
04753    case AST_PRES_ALLOWED_NETWORK_NUMBER:
04754       privacy = "off";
04755       screen = "yes";
04756       break;
04757    case AST_PRES_PROHIB_USER_NUMBER_NOT_SCREENED:
04758       privacy = "full";
04759       screen = "no";
04760       break;
04761    case AST_PRES_PROHIB_USER_NUMBER_PASSED_SCREEN:
04762       privacy = "full";
04763       screen = "pass";
04764       break;
04765    case AST_PRES_PROHIB_USER_NUMBER_FAILED_SCREEN:
04766       privacy = "full";
04767       screen = "fail";
04768       break;
04769    case AST_PRES_PROHIB_NETWORK_NUMBER:
04770       privacy = "full";
04771       screen = "pass";
04772       break;
04773    case AST_PRES_NUMBER_NOT_AVAILABLE:
04774       send_pres_tags = 0;
04775       break;
04776    default:
04777       ast_log(LOG_WARNING, "Unsupported callingpres (%d)\n", p->callingpres);
04778       if ((p->callingpres & AST_PRES_RESTRICTION) != AST_PRES_ALLOWED)
04779          privacy = "full";
04780       else
04781          privacy = "off";
04782       screen = "no";
04783       break;
04784    }
04785    
04786    fromdomain = ast_strlen_zero(p->fromdomain) ? ast_inet_ntoa(iabuf, sizeof(iabuf), p->ourip) : p->fromdomain;
04787 
04788    snprintf(buf, sizeof(buf), "\"%s\" <sip:%s@%s>", clin, clid, fromdomain);
04789    if (send_pres_tags)
04790       snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), ";privacy=%s;screen=%s", privacy, screen);
04791    p->rpid = strdup(buf);
04792 
04793    snprintf(buf, sizeof(buf), "\"%s\" <sip:%s@%s>;tag=%s", clin,
04794        ast_strlen_zero(p->fromuser) ? clid : p->fromuser,
04795        fromdomain, p->tag);
04796    p->rpid_from = strdup(buf);
04797 }

static struct sip_user * build_user const char *  name,
struct ast_variable v,
int  realtime
[static]
 

build_user: Initiate a SIP user structure from sip.conf ---

Definition at line 12064 of file chan_sip.c.

References ast_append_ha(), ast_callerid_split(), ast_cdr_amaflags2int(), ast_copy_flags, ast_free_ha(), ast_get_group(), ast_log(), ast_parse_allow_disallow(), ast_parse_caller_presentation(), ast_strdupa, ast_variable_new(), ASTOBJ_INIT, default_context, default_language, ast_flags::flags, format, global_capability, global_musicclass, handle_common_options(), ast_variable::lineno, LOG_WARNING, malloc, ast_variable::name, ast_variable::next, SIP_FLAGS_TO_COPY, suserobjs, user, and ast_variable::value.

12065 {
12066    struct sip_user *user;
12067    int format;
12068    struct ast_ha *oldha = NULL;
12069    char *varname = NULL, *varval = NULL;
12070    struct ast_variable *tmpvar = NULL;
12071    struct ast_flags userflags = {(0)};
12072    struct ast_flags mask = {(0)};
12073 
12074 
12075    user = (struct sip_user *)malloc(sizeof(struct sip_user));
12076    if (!user) {
12077       return NULL;
12078    }
12079    memset(user, 0, sizeof(struct sip_user));
12080    suserobjs++;
12081    ASTOBJ_INIT(user);
12082    ast_copy_string(user->name, name, sizeof(user->name));
12083    oldha = user->ha;
12084    user->ha = NULL;
12085    ast_copy_flags(user, &global_flags, SIP_FLAGS_TO_COPY);
12086    user->capability = global_capability;
12087    user->prefs = prefs;
12088    /* set default context */
12089    strcpy(user->context, default_context);
12090    strcpy(user->language, default_language);
12091    strcpy(user->musicclass, global_musicclass);
12092    while(v) {
12093       if (handle_common_options(&userflags, &mask, v)) {
12094          v = v->next;
12095          continue;
12096       }
12097 
12098       if (!strcasecmp(v->name, "context")) {
12099          ast_copy_string(user->context, v->value, sizeof(user->context));
12100       } else if (!strcasecmp(v->name, "subscribecontext")) {
12101          ast_copy_string(user->subscribecontext, v->value, sizeof(user->subscribecontext));
12102       } else if (!strcasecmp(v->name, "setvar")) {
12103          varname = ast_strdupa(v->value);
12104          if (varname && (varval = strchr(varname,'='))) {
12105             *varval = '\0';
12106             varval++;
12107             if ((tmpvar = ast_variable_new(varname, varval))) {
12108                tmpvar->next = user->chanvars;
12109                user->chanvars = tmpvar;
12110             }
12111          }
12112       } else if (!strcasecmp(v->name, "permit") ||
12113                !strcasecmp(v->name, "deny")) {
12114          user->ha = ast_append_ha(v->name, v->value, user->ha);
12115       } else if (!strcasecmp(v->name, "secret")) {
12116          ast_copy_string(user->secret, v->value, sizeof(user->secret)); 
12117       } else if (!strcasecmp(v->name, "md5secret")) {
12118          ast_copy_string(user->md5secret, v->value, sizeof(user->md5secret));
12119       } else if (!strcasecmp(v->name, "callerid")) {
12120          ast_callerid_split(v->value, user->cid_name, sizeof(user->cid_name), user->cid_num, sizeof(user->cid_num));
12121       } else if (!strcasecmp(v->name, "callgroup")) {
12122          user->callgroup = ast_get_group(v->value);
12123       } else if (!strcasecmp(v->name, "pickupgroup")) {
12124          user->pickupgroup = ast_get_group(v->value);
12125       } else if (!strcasecmp(v->name, "language")) {
12126          ast_copy_string(user->language, v->value, sizeof(user->language));
12127       } else if (!strcasecmp(v->name, "musicclass") || !strcasecmp(v->name, "musiconhold")) {
12128          ast_copy_string(user->musicclass, v->value, sizeof(user->musicclass));
12129       } else if (!strcasecmp(v->name, "accountcode")) {
12130          ast_copy_string(user->accountcode, v->value, sizeof(user->accountcode));
12131       } else if (!strcasecmp(v->name, "call-limit") || !strcasecmp(v->name, "incominglimit")) {
12132          user->call_limit = atoi(v->value);
12133          if (user->call_limit < 0)
12134             user->call_limit = 0;
12135       } else if (!strcasecmp(v->name, "amaflags")) {
12136          format = ast_cdr_amaflags2int(v->value);
12137          if (format < 0) {
12138             ast_log(LOG_WARNING, "Invalid AMA Flags: %s at line %d\n", v->value, v->lineno);
12139          } else {
12140             user->amaflags = format;
12141          }
12142       } else if (!strcasecmp(v->name, "allow")) {
12143          ast_parse_allow_disallow(&user->prefs, &user->capability, v->value, 1);
12144       } else if (!strcasecmp(v->name, "disallow")) {
12145          ast_parse_allow_disallow(&user->prefs, &user->capability, v->value, 0);
12146       } else if (!strcasecmp(v->name, "callingpres")) {
12147          user->callingpres = ast_parse_caller_presentation(v->value);
12148          if (user->callingpres == -1)
12149             user->callingpres = atoi(v->value);
12150       }
12151       /*else if (strcasecmp(v->name,"type"))
12152        * ast_log(LOG_WARNING, "Ignoring %s\n", v->name);
12153        */
12154       v = v->next;
12155    }
12156    ast_copy_flags(user, &userflags, mask.flags);
12157    ast_free_ha(oldha);
12158    return user;
12159 }

static void build_via struct sip_pvt p,
char *  buf,
int  len
[static]
 

build_via: Build a Via header for a request ---

Definition at line 1081 of file chan_sip.c.

References ast_inet_ntoa(), ast_test_flag, sip_pvt::branch, sip_pvt::ourip, ourport, SIP_NAT, and SIP_NAT_RFC3581.

Referenced by reqprep(), sip_alloc(), sip_notify(), sip_poke_peer(), sip_request_call(), sip_send_mwi_to_peer(), transmit_invite(), and transmit_register().

01082 {
01083    char iabuf[INET_ADDRSTRLEN];
01084 
01085    /* z9hG4bK is a magic cookie.  See RFC 3261 section 8.1.1.7 */
01086    if (ast_test_flag(p, SIP_NAT) & SIP_NAT_RFC3581)
01087       snprintf(buf, len, "SIP/2.0/UDP %s:%d;branch=z9hG4bK%08x;rport", ast_inet_ntoa(iabuf, sizeof(iabuf), p->ourip), ourport, p->branch);
01088    else /* Work around buggy UNIDEN UIP200 firmware */
01089       snprintf(buf, len, "SIP/2.0/UDP %s:%d;branch=z9hG4bK%08x", ast_inet_ntoa(iabuf, sizeof(iabuf), p->ourip), ourport, p->branch);
01090 }

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

cb_extensionstate: Callback for the devicestate notification (SUBSCRIBE) support subsystem ---

Definition at line 6408 of file chan_sip.c.

References append_history(), AST_EXTENSION_DEACTIVATED, AST_EXTENSION_REMOVED, ast_extension_state2str(), ast_verbose(), sip_pvt::autokillid, sip_pvt::laststate, NONE, option_debug, sip_cancel_destroy(), sip_scheddestroy(), sip_pvt::stateid, sip_pvt::subscribed, transmit_state_notify(), sip_pvt::username, VERBOSE_PREFIX_1, and VERBOSE_PREFIX_2.

Referenced by handle_request_subscribe().

06409 {
06410    struct sip_pvt *p = data;
06411 
06412    switch(state) {
06413    case AST_EXTENSION_DEACTIVATED:  /* Retry after a while */
06414    case AST_EXTENSION_REMOVED:   /* Extension is gone */
06415       if (p->autokillid > -1)
06416          sip_cancel_destroy(p);  /* Remove subscription expiry for renewals */
06417       sip_scheddestroy(p, 15000);   /* Delete subscription in 15 secs */
06418       ast_verbose(VERBOSE_PREFIX_2 "Extension state: Watcher for hint %s %s. Notify User %s\n", exten, state == AST_EXTENSION_DEACTIVATED ? "deactivated" : "removed", p->username);
06419       p->stateid = -1;
06420       p->subscribed = NONE;
06421       append_history(p, "Subscribestatus", state == AST_EXTENSION_REMOVED ? "HintRemoved" : "Deactivated");
06422       break;
06423    default: /* Tell user */
06424       p->laststate = state;
06425       break;
06426    }
06427    transmit_state_notify(p, state, 1, 1);
06428 
06429    if (option_debug > 1)
06430       ast_verbose(VERBOSE_PREFIX_1 "Extension Changed %s new state %s for Notify User %s\n", exten, ast_extension_state2str(state), p->username);
06431    return 0;
06432 }

static int check_auth struct sip_pvt p,
struct sip_request req,
char *  randdata,
int  randlen,
char *  username,
char *  secret,
char *  md5secret,
int  sipmethod,
char *  uri,
int  reliable,
int  ignore
[static]
 

check_auth: Check user authorization from peer definition ---

Definition at line 6183 of file chan_sip.c.

References ast_log(), ast_md5_hash(), ast_strlen_zero(), ast_test_flag, check_osptoken(), get_header(), global_allowguest, global_realm, LOG_DEBUG, LOG_NOTICE, sip_methods, SIP_OSPAUTH, SIP_OSPAUTH_EXCLUSIVE, SIP_OSPAUTH_GATEWAY, SIP_OSPAUTH_NO, SIP_OSPAUTH_PROXY, SIP_REGISTER, sip_scheddestroy(), SIP_SUBSCRIBE, sipdebug, text, thread_safe_rand(), and transmit_response_with_auth().

Referenced by check_user_full(), and register_verify().

06184 {
06185    int res = -1;
06186    char *response = "407 Proxy Authentication Required";
06187    char *reqheader = "Proxy-Authorization";
06188    char *respheader = "Proxy-Authenticate";
06189    char *authtoken;
06190 #ifdef OSP_SUPPORT
06191    char *osptoken;
06192 #endif
06193    /* Always OK if no secret */
06194    if (ast_strlen_zero(secret) && ast_strlen_zero(md5secret)
06195 #ifdef OSP_SUPPORT
06196        && !ast_test_flag(p, SIP_OSPAUTH)
06197        && global_allowguest != 2
06198 #endif
06199       )
06200       return 0;
06201    if (sipmethod == SIP_REGISTER || sipmethod == SIP_SUBSCRIBE) {
06202       /* On a REGISTER, we have to use 401 and its family of headers instead of 407 and its family
06203          of headers -- GO SIP!  Whoo hoo!  Two things that do the same thing but are used in
06204          different circumstances! What a surprise. */
06205       response = "401 Unauthorized";
06206       reqheader = "Authorization";
06207       respheader = "WWW-Authenticate";
06208    }
06209 #ifdef OSP_SUPPORT
06210    else {
06211       ast_log (LOG_DEBUG, "Checking OSP Authentication!\n");
06212       osptoken = get_header (req, "P-OSP-Auth-Token");
06213       switch (ast_test_flag (p, SIP_OSPAUTH)) {
06214          case SIP_OSPAUTH_NO:
06215             break;
06216          case SIP_OSPAUTH_GATEWAY:
06217             if (ast_strlen_zero (osptoken)) {
06218                if (ast_strlen_zero (secret) && ast_strlen_zero (md5secret)) {
06219                   return (0);
06220                }
06221             }
06222             else {
06223                return (check_osptoken (p, osptoken));
06224             }
06225             break;
06226          case SIP_OSPAUTH_PROXY:
06227             if (ast_strlen_zero (osptoken)) {
06228                return (0);
06229             } 
06230             else {
06231                return (check_osptoken (p, osptoken));
06232             }
06233             break;
06234          case SIP_OSPAUTH_EXCLUSIVE:
06235             if (ast_strlen_zero (osptoken)) {
06236                return (-1);
06237             }
06238             else {
06239                return (check_osptoken (p, osptoken));
06240             }
06241             break;
06242          default:
06243             return (-1);
06244       }
06245    }
06246 #endif   
06247    authtoken =  get_header(req, reqheader);  
06248    if (ignore && !ast_strlen_zero(randdata) && ast_strlen_zero(authtoken)) {
06249       /* This is a retransmitted invite/register/etc, don't reconstruct authentication
06250          information */
06251       if (!ast_strlen_zero(randdata)) {
06252          if (!reliable) {
06253             /* Resend message if this was NOT a reliable delivery.   Otherwise the
06254                retransmission should get it */
06255             transmit_response_with_auth(p, response, req, randdata, reliable, respheader, 0);
06256             /* Schedule auto destroy in 15 seconds */
06257             sip_scheddestroy(p, 15000);
06258          }
06259          res = 1;
06260       }
06261    } else if (ast_strlen_zero(randdata) || ast_strlen_zero(authtoken)) {
06262       snprintf(randdata, randlen, "%08x", thread_safe_rand());
06263       transmit_response_with_auth(p, response, req, randdata, reliable, respheader, 0);
06264       /* Schedule auto destroy in 15 seconds */
06265       sip_scheddestroy(p, 15000);
06266       res = 1;
06267    } else {
06268       /* Whoever came up with the authentication section of SIP can suck my %&#$&* for not putting
06269          an example in the spec of just what it is you're doing a hash on. */
06270       char a1[256];
06271       char a2[256];
06272       char a1_hash[256];
06273       char a2_hash[256];
06274       char resp[256];
06275       char resp_hash[256]="";
06276       char tmp[256];
06277       char *c;
06278       char *z;
06279       char *ua_hash ="";
06280       char *resp_uri ="";
06281       char *nonce = "";
06282       char *digestusername = "";
06283       int  wrongnonce = 0;
06284       char *usednonce = randdata;
06285 
06286       /* Find their response among the mess that we'r sent for comparison */
06287       ast_copy_string(tmp, authtoken, sizeof(tmp));
06288       c = tmp;
06289 
06290       while(c) {
06291          c = ast_skip_blanks(c);
06292          if (!*c)
06293             break;
06294          if (!strncasecmp(c, "response=", strlen("response="))) {
06295             c+= strlen("response=");
06296             if ((*c == '\"')) {
06297                ua_hash=++c;
06298                if ((c = strchr(c,'\"')))
06299                   *c = '\0';
06300 
06301             } else {
06302                ua_hash=c;
06303                if ((c = strchr(c,',')))
06304                   *c = '\0';
06305             }
06306 
06307          } else if (!strncasecmp(c, "uri=", strlen("uri="))) {
06308             c+= strlen("uri=");
06309             if ((*c == '\"')) {
06310                resp_uri=++c;
06311                if ((c = strchr(c,'\"')))
06312                   *c = '\0';
06313             } else {
06314                resp_uri=c;
06315                if ((c = strchr(c,',')))
06316                   *c = '\0';
06317             }
06318 
06319          } else if (!strncasecmp(c, "username=", strlen("username="))) {
06320             c+= strlen("username=");
06321             if ((*c == '\"')) {
06322                digestusername=++c;
06323                if((c = strchr(c,'\"')))
06324                   *c = '\0';
06325             } else {
06326                digestusername=c;
06327                if((c = strchr(c,',')))
06328                   *c = '\0';
06329             }
06330          } else if (!strncasecmp(c, "nonce=", strlen("nonce="))) {
06331             c+= strlen("nonce=");
06332             if ((*c == '\"')) {
06333                nonce=++c;
06334                if ((c = strchr(c,'\"')))
06335                   *c = '\0';
06336             } else {
06337                nonce=c;
06338                if ((c = strchr(c,',')))
06339                   *c = '\0';
06340             }
06341 
06342          } else
06343             if ((z = strchr(c,' ')) || (z = strchr(c,','))) c=z;
06344          if (c)
06345             c++;
06346       }
06347       /* Verify that digest username matches  the username we auth as */
06348       if (strcmp(username, digestusername)) {
06349          /* Oops, we're trying something here */
06350          return -2;
06351       }
06352 
06353       /* Verify nonce from request matches our nonce.  If not, send 401 with new nonce */
06354       if (strncasecmp(randdata, nonce, randlen)) {
06355          wrongnonce = 1;
06356          usednonce = nonce;
06357       }
06358 
06359       snprintf(a1, sizeof(a1), "%s:%s:%s", username, global_realm, secret);
06360 
06361       if (!ast_strlen_zero(resp_uri))
06362          snprintf(a2, sizeof(a2), "%s:%s", sip_methods[sipmethod].text, resp_uri);
06363       else
06364          snprintf(a2, sizeof(a2), "%s:%s", sip_methods[sipmethod].text, uri);
06365 
06366       if (!ast_strlen_zero(md5secret))
06367          snprintf(a1_hash, sizeof(a1_hash), "%s", md5secret);
06368       else
06369          ast_md5_hash(a1_hash, a1);
06370 
06371       ast_md5_hash(a2_hash, a2);
06372 
06373       snprintf(resp, sizeof(resp), "%s:%s:%s", a1_hash, usednonce, a2_hash);
06374       ast_md5_hash(resp_hash, resp);
06375 
06376       if (wrongnonce) {
06377 
06378          snprintf(randdata, randlen, "%08x", thread_safe_rand());
06379          if (ua_hash && !strncasecmp(ua_hash, resp_hash, strlen(resp_hash))) {
06380             if (sipdebug)
06381                ast_log(LOG_NOTICE, "stale nonce received from '%s'\n", get_header(req, "To"));
06382             /* We got working auth token, based on stale nonce . */
06383             transmit_response_with_auth(p, response, req, randdata, reliable, respheader, 1);
06384          } else {
06385             /* Everything was wrong, so give the device one more try with a new challenge */
06386             if (sipdebug)
06387                ast_log(LOG_NOTICE, "Bad authentication received from '%s'\n", get_header(req, "To"));
06388             transmit_response_with_auth(p, response, req, randdata, reliable, respheader, 0);
06389          }
06390 
06391          /* Schedule auto destroy in 15 seconds */
06392          sip_scheddestroy(p, 15000);
06393          return 1;
06394       } 
06395       /* resp_hash now has the expected response, compare the two */
06396       if (ua_hash && !strncasecmp(ua_hash, resp_hash, strlen(resp_hash))) {
06397          /* Auth is OK */
06398          res = 0;
06399       }
06400    }
06401    /* Failure */
06402    return res;
06403 }

static int check_osptoken struct sip_pvt p,
char *  token
[static]
 

check_osptoken: Validate OSP token for user authrroization ---

Definition at line 6166 of file chan_sip.c.

References ast_osp_validate(), sip_pvt::cid_num, sip_pvt::exten, sip_pvt::owner, pbx_builtin_setvar_helper(), and sip_pvt::sa.

Referenced by check_auth().

06167 {
06168    char tmp[80];
06169 
06170    if (ast_osp_validate (NULL, token, &p->osphandle, &p->osptimelimit, p->cid_num, p->sa.sin_addr, p->exten) < 1) {
06171       return (-1);
06172    } else {
06173       snprintf (tmp, sizeof (tmp), "%d", p->osphandle);
06174       pbx_builtin_setvar_helper (p->owner, "_OSPHANDLE", tmp);
06175       return (0);
06176    }
06177 }

static void check_pendings struct sip_pvt p  )  [static]
 

check_pendings: Check pending actions on SIP call ---

Definition at line 9546 of file chan_sip.c.

References ast_clear_flag, ast_log(), ast_set_flag, ast_test_flag, sip_pvt::callid, LOG_DEBUG, SIP_BYE, SIP_CAN_BYE, SIP_CANCEL, SIP_NEEDDESTROY, SIP_NEEDREINVITE, SIP_PENDINGBYE, sip_scheddestroy(), transmit_reinvite_with_sdp(), and transmit_request_with_auth().

Referenced by handle_request(), and handle_response_invite().

09547 {
09548    if (ast_test_flag(p, SIP_PENDINGBYE)) {
09549       /* if we can't BYE, then this is really a pending CANCEL */
09550       if (!ast_test_flag(p, SIP_CAN_BYE)) {
09551          transmit_request_with_auth(p, SIP_CANCEL, p->ocseq, 1, 0);
09552          /* Actually don't destroy us yet, wait for the 487 on our original 
09553             INVITE, but do set an autodestruct just in case we never get it. */
09554          sip_scheddestroy(p, 32000);
09555       } else {
09556          transmit_request_with_auth(p, SIP_BYE, 0, 1, 1);
09557          ast_set_flag(p, SIP_NEEDDESTROY);   
09558          ast_clear_flag(p, SIP_NEEDREINVITE);   
09559       }
09560    } else if (ast_test_flag(p, SIP_NEEDREINVITE)) {
09561       ast_log(LOG_DEBUG, "Sending pending reinvite on '%s'\n", p->callid);
09562       /* Didn't get to reinvite yet, so do it now */
09563       transmit_reinvite_with_sdp(p);
09564       ast_clear_flag(p, SIP_NEEDREINVITE);   
09565    }
09566 }

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 11933 of file chan_sip.c.

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

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

11934 {
11935    struct domain *d;
11936    int result = 0;
11937 
11938    AST_LIST_LOCK(&domain_list);
11939    AST_LIST_TRAVERSE(&domain_list, d, list) {
11940       if (strcasecmp(d->domain, domain))
11941          continue;
11942 
11943       if (len && !ast_strlen_zero(d->context))
11944          ast_copy_string(context, d->context, len);
11945       
11946       result = 1;
11947       break;
11948    }
11949    AST_LIST_UNLOCK(&domain_list);
11950 
11951    return result;
11952 }

static int check_user struct sip_pvt p,
struct sip_request req,
int  sipmethod,
char *  uri,
int  reliable,
struct sockaddr_in *  sin,
int  ignore
[static]
 

check_user: Find user ---

Definition at line 7330 of file chan_sip.c.

References check_user_full().

Referenced by handle_request_invite().

07331 {
07332    return check_user_full(p, req, sipmethod, uri, reliable, sin, ignore, NULL, 0);
07333 }

static int check_user_full struct sip_pvt p,
struct sip_request req,
int  sipmethod,
char *  uri,
int  reliable,
struct sockaddr_in *  sin,
int  ignore,
char *  mailbox,
int  mailboxlen
[static]
 

check_user_full: Check if matching user or peer is defined ---

Definition at line 7063 of file chan_sip.c.

References sip_peer::accountcode, sip_user::accountcode, sip_peer::amaflags, sip_user::amaflags, ast_apply_ha(), ast_copy_flags, ast_inet_ntoa(), ast_log(), AST_RTP_DTMF, ast_rtp_setnat(), ast_set_flag, ast_shrink_phone_number(), ast_strlen_zero(), ast_test_flag, ast_uri_decode(), ast_variable_new(), ast_verbose(), ASTOBJ_UNREF, build_contact(), sip_peer::call_limit, sip_user::call_limit, sip_peer::callgroup, sip_user::callgroup, sip_peer::callingpres, sip_user::callingpres, sip_pvt::callingpres, sip_peer::capability, sip_user::capability, sip_peer::chanvars, sip_user::chanvars, check_auth(), sip_peer::cid_name, sip_user::cid_name, sip_pvt::cid_name, sip_peer::cid_num, sip_user::cid_num, sip_pvt::cid_num, sip_peer::context, sip_user::context, debug, sip_pvt::exten, find_peer(), find_user(), sip_pvt::from, sip_peer::fullcontact, get_calleridname(), get_header(), get_in_brackets(), get_rpid_num(), global_allowguest, global_alwaysauthreject, sip_user::ha, sip_peer::language, sip_user::language, sip_peer::lastms, LOG_DEBUG, LOG_NOTICE, sip_peer::mailbox, sip_peer::maxms, sip_peer::md5secret, sip_user::md5secret, sip_user::musicclass, ast_variable::next, sip_pvt::our_contact, pedanticsipchecking, sip_pvt::peermd5secret, sip_pvt::peersecret, sip_peer::pickupgroup, sip_user::pickupgroup, sip_peer::prefs, sip_user::prefs, sip_pvt::randdata, sip_pvt::recv, sip_pvt::rtp, sip_peer::secret, sip_user::secret, SIP_CALL_LIMIT, sip_cancel_destroy(), sip_debug_test_addr(), sip_destroy_peer(), sip_destroy_user(), SIP_DTMF, SIP_DTMF_AUTO, SIP_DTMF_RFC2833, SIP_FLAGS_TO_COPY, SIP_INSECURE_INVITE, SIP_NAT, SIP_NAT_ROUTE, SIP_OSPAUTH, SIP_SUBSCRIBE, SIP_TRUSTRPID, sip_peer::sipoptions, sip_pvt::sipoptions, sip_user::sipoptions, sip_peer::subscribecontext, sip_pvt::subscribecontext, sip_user::subscribecontext, t, sip_pvt::timer_t1, user, sip_peer::username, and sip_pvt::vrtp.

Referenced by check_user(), and handle_request_subscribe().

07064 {
07065    struct sip_user *user = NULL;
07066    struct sip_peer *peer;
07067    char *of, from[256], *c;
07068    char *rpid,rpid_num[50];
07069    char iabuf[INET_ADDRSTRLEN];
07070    int res = 0;
07071    char *t;
07072    char calleridname[50];
07073    int debug=sip_debug_test_addr(sin);
07074    struct ast_variable *tmpvar = NULL, *v = NULL;
07075 
07076    /* Terminate URI */
07077    t = uri;
07078    while(*t && (*t > 32) && (*t != ';'))
07079       t++;
07080    *t = '\0';
07081    of = get_header(req, "From");
07082    if (pedanticsipchecking)
07083       ast_uri_decode(of);
07084 
07085    ast_copy_string(from, of, sizeof(from));
07086    
07087    memset(calleridname,0,sizeof(calleridname));
07088    get_calleridname(from, calleridname, sizeof(calleridname));
07089    if (calleridname[0])
07090       ast_copy_string(p->cid_name, calleridname, sizeof(p->cid_name));
07091 
07092    rpid = get_header(req, "Remote-Party-ID");
07093    memset(rpid_num,0,sizeof(rpid_num));
07094    if (!ast_strlen_zero(rpid)) 
07095       p->callingpres = get_rpid_num(rpid,rpid_num, sizeof(rpid_num));
07096 
07097    of = get_in_brackets(from);
07098    if (ast_strlen_zero(p->exten)) {
07099       t = uri;
07100       if (!strncmp(t, "sip:", 4))
07101          t+= 4;
07102       ast_copy_string(p->exten, t, sizeof(p->exten));
07103       t = strchr(p->exten, '@');
07104       if (t)
07105          *t = '\0';
07106       if (ast_strlen_zero(p->our_contact))
07107          build_contact(p);
07108    }
07109    /* save the URI part of the From header */
07110    ast_copy_string(p->from, of, sizeof(p->from));
07111    if (strncmp(of, "sip:", 4)) {
07112       ast_log(LOG_NOTICE, "From address missing 'sip:', using it anyway\n");
07113    } else
07114       of += 4;
07115    /* Get just the username part */
07116    if ((c = strchr(of, '@'))) {
07117       *c = '\0';
07118       if ((c = strchr(of, ':')))
07119          *c = '\0';
07120       ast_copy_string(p->cid_num, of, sizeof(p->cid_num));
07121       ast_shrink_phone_number(p->cid_num);
07122    }
07123    if (ast_strlen_zero(of))
07124       return 0;
07125 
07126    if (!mailbox)  /* If it's a mailbox SUBSCRIBE, don't check users */
07127       user = find_user(of, 1);
07128 
07129    /* Find user based on user name in the from header */
07130    if (user && ast_apply_ha(user->ha, sin)) {
07131       ast_copy_flags(p, user, SIP_FLAGS_TO_COPY);
07132       /* copy channel vars */
07133       for (v = user->chanvars ; v ; v = v->next) {
07134          if ((tmpvar = ast_variable_new(v->name, v->value))) {
07135             tmpvar->next = p->chanvars; 
07136             p->chanvars = tmpvar;
07137          }
07138       }
07139       p->prefs = user->prefs;
07140       /* replace callerid if rpid found, and not restricted */
07141       if (!ast_strlen_zero(rpid_num) && ast_test_flag(p, SIP_TRUSTRPID)) {
07142          if (*calleridname)
07143             ast_copy_string(p->cid_name, calleridname, sizeof(p->cid_name));
07144          ast_copy_string(p->cid_num, rpid_num, sizeof(p->cid_num));
07145          ast_shrink_phone_number(p->cid_num);
07146       }
07147 
07148       if (p->rtp) {
07149          ast_log(LOG_DEBUG, "Setting NAT on RTP to %d\n", (ast_test_flag(p, SIP_NAT) & SIP_NAT_ROUTE));
07150          ast_rtp_setnat(p->rtp, (ast_test_flag(p, SIP_NAT) & SIP_NAT_ROUTE));
07151       }
07152       if (p->vrtp) {
07153          ast_log(LOG_DEBUG, "Setting NAT on VRTP to %d\n", (ast_test_flag(p, SIP_NAT) & SIP_NAT_ROUTE));
07154          ast_rtp_setnat(p->vrtp, (ast_test_flag(p, SIP_NAT) & SIP_NAT_ROUTE));
07155       }
07156       if (!(res = check_auth(p, req, p->randdata, sizeof(p->randdata), user->name, user->secret, user->md5secret, sipmethod, uri, reliable, ignore))) {
07157          sip_cancel_destroy(p);
07158          ast_copy_flags(p, user, SIP_FLAGS_TO_COPY);
07159          /* Copy SIP extensions profile from INVITE */
07160          if (p->sipoptions)
07161             user->sipoptions = p->sipoptions;
07162 
07163          /* If we have a call limit, set flag */
07164          if (user->call_limit)
07165             ast_set_flag(p, SIP_CALL_LIMIT);
07166          if (!ast_strlen_zero(user->context))
07167             ast_copy_string(p->context, user->context, sizeof(p->context));
07168          if (!ast_strlen_zero(user->cid_num) && !ast_strlen_zero(p->cid_num))  {
07169             ast_copy_string(p->cid_num, user->cid_num, sizeof(p->cid_num));
07170             ast_shrink_phone_number(p->cid_num);
07171          }
07172          if (!ast_strlen_zero(user->cid_name) && !ast_strlen_zero(p->cid_num)) 
07173             ast_copy_string(p->cid_name, user->cid_name, sizeof(p->cid_name));
07174          ast_copy_string(p->peername, user->name, sizeof(p->peername));
07175          ast_copy_string(p->username, user->name, sizeof(p->username));
07176          ast_copy_string(p->peersecret, user->secret, sizeof(p->peersecret));
07177          ast_copy_string(p->subscribecontext, user->subscribecontext, sizeof(p->subscribecontext));
07178          ast_copy_string(p->peermd5secret, user->md5secret, sizeof(p->peermd5secret));
07179          ast_copy_string(p->accountcode, user->accountcode, sizeof(p->accountcode));
07180          ast_copy_string(p->language, user->language, sizeof(p->language));
07181          ast_copy_string(p->musicclass, user->musicclass, sizeof(p->musicclass));
07182          p->amaflags = user->amaflags;
07183          p->callgroup = user->callgroup;
07184          p->pickupgroup = user->pickupgroup;
07185          p->callingpres = user->callingpres;
07186          p->capability = user->capability;
07187          p->jointcapability = user->capability;
07188          if (p->peercapability)
07189             p->jointcapability &= p->peercapability;
07190          if ((ast_test_flag(p, SIP_DTMF) == SIP_DTMF_RFC2833) || (ast_test_flag(p, SIP_DTMF) == SIP_DTMF_AUTO))
07191             p->noncodeccapability |= AST_RTP_DTMF;
07192          else
07193             p->noncodeccapability &= ~AST_RTP_DTMF;
07194       }
07195       if (user && debug)
07196          ast_verbose("Found user '%s'\n", user->name);
07197    } else {
07198       if (user) {
07199          if (!mailbox && debug)
07200             ast_verbose("Found user '%s', but fails host access\n", user->name);
07201          ASTOBJ_UNREF(user,sip_destroy_user);
07202       }
07203       user = NULL;
07204    }
07205 
07206    if (!user) {
07207       /* If we didn't find a user match, check for peers */
07208       if (sipmethod == SIP_SUBSCRIBE)
07209          /* For subscribes, match on peer name only */
07210          peer = find_peer(of, NULL, 1);
07211       else
07212          /* Look for peer based on the IP address we received data from */
07213          /* If peer is registered from this IP address or have this as a default
07214             IP address, this call is from the peer 
07215          */
07216          peer = find_peer(NULL, &p->recv, 1);
07217 
07218       if (peer) {
07219          if (debug)
07220             ast_verbose("Found peer '%s'\n", peer->name);
07221          /* Take the peer */
07222          ast_copy_flags(p, peer, SIP_FLAGS_TO_COPY);
07223 
07224          /* Copy SIP extensions profile to peer */
07225          if (p->sipoptions)
07226             peer->sipoptions = p->sipoptions;
07227 
07228          /* replace callerid if rpid found, and not restricted */
07229          if (!ast_strlen_zero(rpid_num) && ast_test_flag(p, SIP_TRUSTRPID)) {
07230             if (*calleridname)
07231                ast_copy_string(p->cid_name, calleridname, sizeof(p->cid_name));
07232             ast_copy_string(p->cid_num, rpid_num, sizeof(p->cid_num));
07233             ast_shrink_phone_number(p->cid_num);
07234          }
07235          if (p->rtp) {
07236             ast_log(LOG_DEBUG, "Setting NAT on RTP to %d\n", (ast_test_flag(p, SIP_NAT) & SIP_NAT_ROUTE));
07237             ast_rtp_setnat(p->rtp, (ast_test_flag(p, SIP_NAT) & SIP_NAT_ROUTE));
07238          }
07239          if (p->vrtp) {
07240             ast_log(LOG_DEBUG, "Setting NAT on VRTP to %d\n", (ast_test_flag(p, SIP_NAT) & SIP_NAT_ROUTE));
07241             ast_rtp_setnat(p->vrtp, (ast_test_flag(p, SIP_NAT) & SIP_NAT_ROUTE));
07242          }
07243          ast_copy_string(p->peersecret, peer->secret, sizeof(p->peersecret));
07244          p->peersecret[sizeof(p->peersecret)-1] = '\0';
07245          ast_copy_string(p->subscribecontext, peer->subscribecontext, sizeof(p->subscribecontext));
07246          ast_copy_string(p->peermd5secret, peer->md5secret, sizeof(p->peermd5secret));
07247          p->peermd5secret[sizeof(p->peermd5secret)-1] = '\0';
07248          p->callingpres = peer->callingpres;
07249          if (peer->maxms && peer->lastms)
07250             p->timer_t1 = peer->lastms;
07251          if (ast_test_flag(peer, SIP_INSECURE_INVITE)) {
07252             /* Pretend there is no required authentication */
07253             p->peersecret[0] = '\0';
07254             p->peermd5secret[0] = '\0';
07255          }
07256          if (!(res = check_auth(p, req, p->randdata, sizeof(p->randdata), peer->name, p->peersecret, p->peermd5secret, sipmethod, uri, reliable, ignore))) {
07257             ast_copy_flags(p, peer, SIP_FLAGS_TO_COPY);
07258             /* If we have a call limit, set flag */
07259             if (peer->call_limit)
07260                ast_set_flag(p, SIP_CALL_LIMIT);
07261             ast_copy_string(p->peername, peer->name, sizeof(p->peername));
07262             ast_copy_string(p->authname, peer->name, sizeof(p->authname));
07263             /* copy channel vars */
07264             for (v = peer->chanvars ; v ; v = v->next) {
07265                if ((tmpvar = ast_variable_new(v->name, v->value))) {
07266                   tmpvar->next = p->chanvars; 
07267                   p->chanvars = tmpvar;
07268                }
07269             }
07270             if (mailbox)
07271                snprintf(mailbox, mailboxlen, ",%s,", peer->mailbox);
07272             if (!ast_strlen_zero(peer->username)) {
07273                ast_copy_string(p->username, peer->username, sizeof(p->username));
07274                /* Use the default username for authentication on outbound calls */
07275                ast_copy_string(p->authname, peer->username, sizeof(p->authname));
07276             }
07277             if (!ast_strlen_zero(peer->cid_num) && !ast_strlen_zero(p->cid_num))  {
07278                ast_copy_string(p->cid_num, peer->cid_num, sizeof(p->cid_num));
07279                ast_shrink_phone_number(p->cid_num);
07280             }
07281             if (!ast_strlen_zero(peer->cid_name) && !ast_strlen_zero(p->cid_name)) 
07282                ast_copy_string(p->cid_name, peer->cid_name, sizeof(p->cid_name));
07283             ast_copy_string(p->fullcontact, peer->fullcontact, sizeof(p->fullcontact));
07284             if (!ast_strlen_zero(peer->context))
07285                ast_copy_string(p->context, peer->context, sizeof(p->context));
07286             ast_copy_string(p->peersecret, peer->secret, sizeof(p->peersecret));
07287             ast_copy_string(p->peermd5secret, peer->md5secret, sizeof(p->peermd5secret));
07288             ast_copy_string(p->language, peer->language, sizeof(p->language));
07289             ast_copy_string(p->accountcode, peer->accountcode, sizeof(p->accountcode));
07290             p->amaflags = peer->amaflags;
07291             p->callgroup = peer->callgroup;
07292             p->pickupgroup = peer->pickupgroup;
07293             p->capability = peer->capability;
07294             p->prefs = peer->prefs;
07295             p->jointcapability = peer->capability;
07296             if (p->peercapability)
07297                p->jointcapability &= p->peercapability;
07298             if ((ast_test_flag(p, SIP_DTMF) == SIP_DTMF_RFC2833) || (ast_test_flag(p, SIP_DTMF) == SIP_DTMF_AUTO))
07299                p->noncodeccapability |= AST_RTP_DTMF;
07300             else
07301                p->noncodeccapability &= ~AST_RTP_DTMF;
07302          }
07303          ASTOBJ_UNREF(peer,sip_destroy_peer);
07304       } else { 
07305          if (debug)
07306             ast_verbose("Found no matching peer or user for '%s:%d'\n", ast_inet_ntoa(iabuf, sizeof(iabuf), p->recv.sin_addr), ntohs(p->recv.sin_port));
07307 
07308          /* do we allow guests? */
07309          if (!global_allowguest) {
07310             if (global_alwaysauthreject)
07311                res = -4; /* reject with fake authorization request */
07312             else
07313                res = -1; /* we don't want any guests, authentication will fail */
07314 #ifdef OSP_SUPPORT         
07315          } else if (global_allowguest == 2) {
07316             ast_copy_flags(p, &global_flags, SIP_OSPAUTH);
07317             res = check_auth(p, req, p->randdata, sizeof(p->randdata), "", "", "", sipmethod, uri, reliable, ignore); 
07318 #endif
07319          }
07320       }
07321 
07322    }
07323 
07324    if (user)
07325       ASTOBJ_UNREF(user,sip_destroy_user);
07326    return res;
07327 }

static int check_via struct sip_pvt p,
struct sip_request req
[static]
 

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

Definition at line 6939 of file chan_sip.c.

References ast_gethostbyname(), ast_inet_ntoa(), ast_log(), ast_set_flag, ast_test_flag, ast_verbose(), DEFAULT_SIP_PORT, get_header(), hp, LOG_WARNING, sip_debug_test_pvt(), SIP_NAT, and SIP_NAT_ROUTE.

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

06940 {
06941    char via[256];
06942    char iabuf[INET_ADDRSTRLEN];
06943    char *c, *pt;
06944    struct hostent *hp;
06945    struct ast_hostent ahp;
06946 
06947    ast_copy_string(via, get_header(req, "Via"), sizeof(via));
06948 
06949    /* Check for rport */
06950    c = strstr(via, ";rport");
06951    if (c && (c[6] != '=')) /* rport query, not answer */
06952       ast_set_flag(p, SIP_NAT_ROUTE);
06953 
06954    c = strchr(via, ';');
06955    if (c) 
06956       *c = '\0';
06957 
06958    c = strchr(via, ' ');
06959    if (c) {
06960       *c = '\0';
06961       c = ast_skip_blanks(c+1);
06962       if (strcasecmp(via, "SIP/2.0/UDP")) {
06963          ast_log(LOG_WARNING, "Don't know how to respond via '%s'\n", via);
06964          return -1;
06965       }
06966       pt = strchr(c, ':');
06967       if (pt)
06968          *pt++ = '\0';  /* remember port pointer */
06969       hp = ast_gethostbyname(c, &ahp);
06970       if (!hp) {
06971          ast_log(LOG_WARNING, "'%s' is not a valid host\n", c);
06972          return -1;
06973       }
06974       memset(&p->sa, 0, sizeof(p->sa));
06975       p->sa.sin_family = AF_INET;
06976       memcpy(&p->sa.sin_addr, hp->h_addr, sizeof(p->sa.sin_addr));
06977       p->sa.sin_port = htons(pt ? atoi(pt) : DEFAULT_SIP_PORT);
06978 
06979       if (sip_debug_test_pvt(p)) {
06980          c = (ast_test_flag(p, SIP_NAT) & SIP_NAT_ROUTE) ? "NAT" : "non-NAT";
06981          ast_verbose("Sending to %s : %d (%s)\n", ast_inet_ntoa(iabuf, sizeof(iabuf), p->sa.sin_addr), ntohs(p->sa.sin_port), c);
06982       }
06983    }
06984    return 0;
06985 }

static int clear_realm_authentication struct sip_auth authlist  )  [static]
 

clear_realm_authentication: Clear realm authentication list (at reload) ---

Definition at line 12034 of file chan_sip.c.

References free, and sip_auth::next.

Referenced by sip_destroy_peer(), sip_do_reload(), and unload_module().

12035 {
12036    struct sip_auth *a = authlist;
12037    struct sip_auth *b;
12038 
12039    while (a) {
12040       b = a;
12041       a = a->next;
12042       free(b);
12043    }
12044 
12045    return 1;
12046 }

static void clear_sip_domains void   )  [static]
 

clear_sip_domains: Clear our domain list (at reload)

Definition at line 11955 of file chan_sip.c.

References AST_LIST_LOCK, AST_LIST_REMOVE_HEAD, AST_LIST_UNLOCK, free, and list.

Referenced by sip_do_reload(), and unload_module().

11956 {
11957    struct domain *d;
11958 
11959    AST_LIST_LOCK(&domain_list);
11960    while ((d = AST_LIST_REMOVE_HEAD(&domain_list, list)))
11961       free(d);
11962    AST_LIST_UNLOCK(&domain_list);
11963 }

static char* complete_sip_debug_peer char *  line,
char *  word,
int  pos,
int  state
[static]
 

complete_sip_debug_peer: Support routine for 'sip debug peer' CLI ---

Definition at line 8490 of file chan_sip.c.

References complete_sip_peer().

08491 {
08492    if (pos == 3)
08493       return complete_sip_peer(word, state, 0);
08494 
08495    return NULL;
08496 }

static char* complete_sip_peer char *  word,
int  state,
int  flags2
[static]
 

complete_sip_peer: Do completion on peer name ---

Definition at line 8461 of file chan_sip.c.

References ast_test_flag, ASTOBJ_CONTAINER_TRAVERSE, peerl, result, and strdup.

Referenced by complete_sip_debug_peer(), complete_sip_prune_realtime_peer(), complete_sip_show_peer(), and complete_sipnotify().

08462 {
08463    char *result = NULL;
08464    int wordlen = strlen(word);
08465    int which = 0;
08466 
08467    ASTOBJ_CONTAINER_TRAVERSE(&peerl, !result, do {
08468       /* locking of the object is not required because only the name and flags are being compared */
08469       if (!strncasecmp(word, iterator->name, wordlen)) {
08470          if (flags2 && !ast_test_flag((&iterator->flags_page2), flags2))
08471             continue;
08472          if (++which > state) {
08473             result = strdup(iterator->name);
08474          }
08475       }
08476    } while(0) );
08477    return result;
08478 }

static char* complete_sip_prune_realtime_peer char *  line,
char *  word,
int  pos,
int  state
[static]
 

complete_sip_prune_realtime_peer: Support routine for 'sip prune realtime peer' CLI ---

Definition at line 8561 of file chan_sip.c.

References complete_sip_peer(), and SIP_PAGE2_RTCACHEFRIENDS.

08562 {
08563    if (pos == 4)
08564       return complete_sip_peer(word, state, SIP_PAGE2_RTCACHEFRIENDS);
08565    return NULL;
08566 }

static char* complete_sip_prune_realtime_user char *  line,
char *  word,
int  pos,
int  state
[static]
 

complete_sip_prune_realtime_user: Support routine for 'sip prune realtime user' CLI ---

Definition at line 8569 of file chan_sip.c.

References complete_sip_user(), and SIP_PAGE2_RTCACHEFRIENDS.

08570 {
08571    if (pos == 4)
08572       return complete_sip_user(word, state, SIP_PAGE2_RTCACHEFRIENDS);
08573 
08574    return NULL;
08575 }

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

complete_sip_show_peer: Support routine for 'sip show peer' CLI ---

Definition at line 8481 of file chan_sip.c.

References complete_sip_peer().

08482 {
08483    if (pos == 3)
08484       return complete_sip_peer(word, state, 0);
08485 
08486    return NULL;
08487 }

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

complete_sip_show_user: Support routine for 'sip show user' CLI ---

Definition at line 8519 of file chan_sip.c.

References complete_sip_user().

08520 {
08521    if (pos == 3)
08522       return complete_sip_user(word, state, 0);
08523 
08524    return NULL;
08525 }

static char* complete_sip_user char *  word,
int  state,
int  flags2
[static]
 

complete_sip_user: Do completion on user name ---

Definition at line 8499 of file chan_sip.c.

References ast_test_flag, ASTOBJ_CONTAINER_TRAVERSE, result, strdup, and userl.

Referenced by complete_sip_prune_realtime_user(), and complete_sip_show_user().

08500 {
08501    char *result = NULL;
08502    int wordlen = strlen(word);
08503    int which = 0;
08504 
08505    ASTOBJ_CONTAINER_TRAVERSE(&userl, !result, do {
08506       /* locking of the object is not required because only the name and flags are being compared */
08507       if (!strncasecmp(word, iterator->name, wordlen)) {
08508          if (flags2 && !ast_test_flag(&(iterator->flags_page2), flags2))
08509             continue;
08510          if (++which > state) {
08511             result = strdup(iterator->name);
08512          }
08513       }
08514    } while(0) );
08515    return result;
08516 }

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

complete_sipch: Support routine for 'sip show channel' CLI ---

Definition at line 8439 of file chan_sip.c.

References ast_mutex_lock(), ast_mutex_unlock(), sip_pvt::callid, iflist, sip_pvt::next, and strdup.

08440 {
08441    int which=0;
08442    struct sip_pvt *cur;
08443    char *c = NULL;
08444 
08445    ast_mutex_lock(&iflock);
08446    cur = iflist;
08447    while(cur) {
08448       if (!strncasecmp(word, cur->callid, strlen(word))) {
08449          if (++which > state) {
08450             c = strdup(cur->callid);
08451             break;
08452          }
08453       }
08454       cur = cur->next;
08455    }
08456    ast_mutex_unlock(&iflock);
08457    return c;
08458 }

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

complete_sipnotify: Support routine for 'sip notify' CLI ---

Definition at line 8528 of file chan_sip.c.

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

08529 {
08530    char *c = NULL;
08531 
08532    if (pos == 2) {
08533       int which = 0;
08534       char *cat;
08535 
08536       /* do completion for notify type */
08537 
08538       if (!notify_types)
08539          return NULL;
08540       
08541       cat = ast_category_browse(notify_types, NULL);
08542       while(cat) {
08543          if (!strncasecmp(word, cat, strlen(word))) {
08544             if (++which > state) {
08545                c = strdup(cat);
08546                break;
08547             }
08548          }
08549          cat = ast_category_browse(notify_types, cat);
08550       }
08551       return c;
08552    }
08553 
08554    if (pos > 2)
08555       return complete_sip_peer(word, state, 0);
08556 
08557    return NULL;
08558 }

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

copy_all_header: Copy all headers from one request to another ---

Definition at line 3855 of file chan_sip.c.

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

Referenced by respprep().

03856 {
03857    char *tmp;
03858    int start = 0;
03859    int copied = 0;
03860    for (;;) {
03861       tmp = __get_header(orig, field, &start);
03862       if (!ast_strlen_zero(tmp)) {
03863          /* Add what we're responding to */
03864          add_header(req, field, tmp);
03865          copied++;
03866       } else
03867          break;
03868    }
03869    return copied ? 0 : -1;
03870 }

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

copy_header: Copy one header field from one request to another

Definition at line 3842 of file chan_sip.c.

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

Referenced by reqprep(), and respprep().

03843 {
03844    char *tmp;
03845    tmp = get_header(orig, field);
03846    if (!ast_strlen_zero(tmp)) {
03847       /* Add what we're responding to */
03848       return add_header(req, field, tmp);
03849    }
03850    ast_log(LOG_NOTICE, "No field '%s' present to copy\n", field);
03851    return -1;
03852 }

static void copy_request struct sip_request dst,
struct sip_request src
[static]
 

copy_request: copy SIP request (mostly used to save request for responses) ---

Definition at line 4580 of file chan_sip.c.

References offset.

Referenced by handle_request_bye(), handle_request_invite(), handle_request_register(), handle_request_subscribe(), sip_park(), sip_park_thread(), transmit_invite(), transmit_notify_with_mwi(), transmit_notify_with_sipfrag(), transmit_register(), transmit_reinvite_with_sdp(), and transmit_sip_request().

04581 {
04582    long offset;
04583    int x;
04584    offset = ((void *)dst) - ((void *)src);
04585    /* First copy stuff */
04586    memcpy(dst, src, sizeof(*dst));
04587    /* Now fix pointer arithmetic */
04588    for (x=0; x < src->headers; x++)
04589       dst->header[x] += offset;
04590    for (x=0; x < src->lines; x++)
04591       dst->line[x] += offset;
04592 }

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

copy_via_headers: Copy SIP VIA Headers from the request to the response ---

Definition at line 3878 of file chan_sip.c.

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

Referenced by respprep().

03879 {
03880    char tmp[256], *oh, *end;
03881    int start = 0;
03882    int copied = 0;
03883    char iabuf[INET_ADDRSTRLEN];
03884 
03885    for (;;) {
03886       oh = __get_header(orig, field, &start);
03887       if (!ast_strlen_zero(oh)) {
03888          if (!copied) { /* Only check for empty rport in topmost via header */
03889             char *rport;
03890             char new[256];
03891 
03892             /* Find ;rport;  (empty request) */
03893             rport = strstr(oh, ";rport");
03894             if (rport && *(rport+6) == '=') 
03895                rport = NULL;     /* We already have a parameter to rport */
03896 
03897             if (rport && (ast_test_flag(p, SIP_NAT) == SIP_NAT_ALWAYS)) {
03898                /* We need to add received port - rport */
03899                ast_copy_string(tmp, oh, sizeof(tmp));
03900 
03901                rport = strstr(tmp, ";rport");
03902 
03903                if (rport) {
03904                   end = strchr(rport + 1, ';');
03905                   if (end)
03906                      memmove(rport, end, strlen(end) + 1);
03907                   else
03908                      *rport = '\0';
03909                }
03910 
03911                /* Add rport to first VIA header if requested */
03912                /* Whoo hoo!  Now we can indicate port address translation too!  Just
03913                      another RFC (RFC3581). I'll leave the original comments in for
03914                      posterity.  */
03915                snprintf(new, sizeof(new), "%s;received=%s;rport=%d", tmp, ast_inet_ntoa(iabuf, sizeof(iabuf), p->recv.sin_addr), ntohs(p->recv.sin_port));
03916             } else {
03917                /* We should *always* add a received to the topmost via */
03918                snprintf(new, sizeof(new), "%s;received=%s", oh, ast_inet_ntoa(iabuf, sizeof(iabuf), p->recv.sin_addr));
03919             }
03920             add_header(req, field, new);
03921          } else {
03922             /* Add the following via headers untouched */
03923             add_header(req, field, oh);
03924          }
03925          copied++;
03926       } else
03927          break;
03928    }
03929    if (!copied) {
03930       ast_log(LOG_NOTICE, "No header field '%s' present to copy\n", field);
03931       return -1;
03932    }
03933    return 0;
03934 }

static int create_addr struct sip_pvt dialog,
char *  opeer
[static]
 

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

Definition at line 1926 of file chan_sip.c.

References ast_get_srv(), ast_gethostbyname(), ast_log(), ASTOBJ_UNREF, create_addr_from_peer(), DEFAULT_SIP_PORT, find_peer(), host, hp, LOG_WARNING, portno, sip_pvt::recv, sip_pvt::sa, sip_destroy_peer(), srvlookup, sip_pvt::timer_t1, and sip_pvt::tohost.

01927 {
01928    struct hostent *hp;
01929    struct ast_hostent ahp;
01930    struct sip_peer *p;
01931    int found=0;
01932    char *port;
01933    int portno;
01934    char host[MAXHOSTNAMELEN], *hostn;
01935    char peer[256];
01936 
01937    ast_copy_string(peer, opeer, sizeof(peer));
01938    port = strchr(peer, ':');
01939    if (port) {
01940       *port = '\0';
01941       port++;
01942    }
01943    dialog->sa.sin_family = AF_INET;
01944    dialog->timer_t1 = 500; /* Default SIP retransmission timer T1 (RFC 3261) */
01945    p = find_peer(peer, NULL, 1);
01946 
01947    if (p) {
01948       found++;
01949       if (create_addr_from_peer(dialog, p))
01950          ASTOBJ_UNREF(p, sip_destroy_peer);
01951    }
01952    if (!p) {
01953       if (found)
01954          return -1;
01955 
01956       hostn = peer;
01957       if (port)
01958          portno = atoi(port);
01959       else
01960          portno = DEFAULT_SIP_PORT;
01961       if (srvlookup) {
01962          char service[MAXHOSTNAMELEN];
01963          int tportno;
01964          int ret;
01965          snprintf(service, sizeof(service), "_sip._udp.%s", peer);
01966          ret = ast_get_srv(NULL, host, sizeof(host), &tportno, service);
01967          if (ret > 0) {
01968             hostn = host;
01969             portno = tportno;
01970          }
01971       }
01972       hp = ast_gethostbyname(hostn, &ahp);
01973       if (hp) {
01974          ast_copy_string(dialog->tohost, peer, sizeof(dialog->tohost));
01975          memcpy(&dialog->sa.sin_addr, hp->h_addr, sizeof(dialog->sa.sin_addr));
01976          dialog->sa.sin_port = htons(portno);
01977          memcpy(&dialog->recv, &dialog->sa, sizeof(dialog->recv));
01978          return 0;
01979       } else {
01980          ast_log(LOG_WARNING, "No such host: %s\n", peer);
01981          return -1;
01982       }
01983    } else {
01984       ASTOBJ_UNREF(p, sip_destroy_peer);
01985       return 0;
01986    }
01987 }

static int create_addr_from_peer struct sip_pvt r,
struct sip_peer peer
[static]
 

create_addr_from_peer: create address structure from peer reference ---

Definition at line 1850 of file chan_sip.c.

References sip_peer::addr, ast_copy_flags, ast_inet_ntoa(), ast_log(), AST_RTP_DTMF, ast_rtp_setnat(), ast_set_flag, ast_strlen_zero(), ast_test_flag, sip_pvt::authname, sip_peer::call_limit, sip_peer::callgroup, sip_pvt::callgroup, sip_pvt::callid, sip_peer::capability, sip_pvt::capability, sip_peer::context, sip_pvt::context, sip_peer::defaddr, sip_pvt::fromdomain, sip_peer::fromdomain, sip_pvt::fromuser, sip_peer::fromuser, sip_peer::fullcontact, sip_pvt::fullcontact, sip_request::headers, sip_pvt::initreq, sip_peer::lastms, LOG_DEBUG, sip_peer::maxms, sip_pvt::maxtime, sip_peer::md5secret, sip_pvt::noncodeccapability, sip_pvt::peermd5secret, sip_pvt::peername, sip_pvt::peersecret, sip_peer::pickupgroup, sip_pvt::pickupgroup, sip_peer::prefs, sip_pvt::prefs, sip_pvt::recv, sip_pvt::rtp, sip_peer::rtpholdtimeout, sip_pvt::rtpholdtimeout, sip_peer::rtpkeepalive, sip_pvt::rtpkeepalive, sip_peer::rtptimeout, sip_pvt::rtptimeout, sip_pvt::sa, sip_peer::secret, SIP_CALL_LIMIT, SIP_DTMF, SIP_DTMF_AUTO, SIP_DTMF_RFC2833, SIP_FLAGS_TO_COPY, SIP_NAT, SIP_NAT_ROUTE, sip_pvt::timer_t1, sip_peer::tohost, sip_pvt::tohost, sip_pvt::username, sip_peer::username, and sip_pvt::vrtp.

Referenced by create_addr(), and sip_send_mwi_to_peer().

01851 {
01852    char *callhost;
01853 
01854    if ((peer->addr.sin_addr.s_addr || peer->defaddr.sin_addr.s_addr) &&
01855        (!peer->maxms || ((peer->lastms >= 0)  && (peer->lastms <= peer->maxms)))) {
01856       if (peer->addr.sin_addr.s_addr) {
01857          r->sa.sin_family = peer->addr.sin_family;
01858          r->sa.sin_addr = peer->addr.sin_addr;
01859          r->sa.sin_port = peer->addr.sin_port;
01860       } else {
01861          r->sa.sin_family = peer->defaddr.sin_family;
01862          r->sa.sin_addr = peer->defaddr.sin_addr;
01863          r->sa.sin_port = peer->defaddr.sin_port;
01864       }
01865       memcpy(&r->recv, &r->sa, sizeof(r->recv));
01866    } else {
01867       return -1;
01868    }
01869 
01870    ast_copy_flags(r, peer, SIP_FLAGS_TO_COPY);
01871    r->capability = peer->capability;
01872    r->prefs = peer->prefs;
01873    if (r->rtp) {
01874       ast_log(LOG_DEBUG, "Setting NAT on RTP to %d\n", (ast_test_flag(r, SIP_NAT) & SIP_NAT_ROUTE));
01875       ast_rtp_setnat(r->rtp, (ast_test_flag(r, SIP_NAT) & SIP_NAT_ROUTE));
01876    }
01877    if (r->vrtp) {
01878       ast_log(LOG_DEBUG, "Setting NAT on VRTP to %d\n", (ast_test_flag(r, SIP_NAT) & SIP_NAT_ROUTE));
01879       ast_rtp_setnat(r->vrtp, (ast_test_flag(r, SIP_NAT) & SIP_NAT_ROUTE));
01880    }
01881    ast_copy_string(r->peername, peer->username, sizeof(r->peername));
01882    ast_copy_string(r->authname, peer->username, sizeof(r->authname));
01883    ast_copy_string(r->username, peer->username, sizeof(r->username));
01884    ast_copy_string(r->peersecret, peer->secret, sizeof(r->peersecret));
01885    ast_copy_string(r->peermd5secret, peer->md5secret, sizeof(r->peermd5secret));
01886    ast_copy_string(r->tohost, peer->tohost, sizeof(r->tohost));
01887    ast_copy_string(r->fullcontact, peer->fullcontact, sizeof(r->fullcontact));
01888    if (!r->initreq.headers && !ast_strlen_zero(peer->fromdomain)) {
01889       if ((callhost = strchr(r->callid, '@'))) {
01890          strncpy(callhost + 1, peer->fromdomain, sizeof(r->callid) - (callhost - r->callid) - 2);
01891       }
01892    }
01893    if (ast_strlen_zero(r->tohost)) {
01894       if (peer->addr.sin_addr.s_addr)
01895          ast_inet_ntoa(r->tohost, sizeof(r->tohost), peer->addr.sin_addr);
01896       else
01897          ast_inet_ntoa(r->tohost, sizeof(r->tohost), peer->defaddr.sin_addr);
01898    }
01899    if (!ast_strlen_zero(peer->fromdomain))
01900       ast_copy_string(r->fromdomain, peer->fromdomain, sizeof(r->fromdomain));
01901    if (!ast_strlen_zero(peer->fromuser))
01902       ast_copy_string(r->fromuser, peer->fromuser, sizeof(r->fromuser));
01903    r->maxtime = peer->maxms;
01904    r->callgroup = peer->callgroup;
01905    r->pickupgroup = peer->pickupgroup;
01906    /* Set timer T1 to RTT for this peer (if known by qualify=) */
01907    if (peer->maxms && peer->lastms)
01908       r->timer_t1 = peer->lastms;
01909    if ((ast_test_flag(r, SIP_DTMF) == SIP_DTMF_RFC2833) || (ast_test_flag(r, SIP_DTMF) == SIP_DTMF_AUTO))
01910       r->noncodeccapability |= AST_RTP_DTMF;
01911    else
01912       r->noncodeccapability &= ~AST_RTP_DTMF;
01913    ast_copy_string(r->context, peer->context,sizeof(r->context));
01914    r->rtptimeout = peer->rtptimeout;
01915    r->rtpholdtimeout = peer->rtpholdtimeout;
01916    r->rtpkeepalive = peer->rtpkeepalive;
01917    if (peer->call_limit)
01918       ast_set_flag(r, SIP_CALL_LIMIT);
01919 
01920    return 0;
01921 }

char* description void   ) 
 

Provides a description of the module.

Returns:
a short description of your module

Definition at line 13473 of file chan_sip.c.

References desc.

13474 {
13475    return (char *) desc;
13476 }

static void destroy_association struct sip_peer peer  )  [static]
 

Definition at line 5702 of file chan_sip.c.

References ast_db_del(), ast_test_flag, ast_update_realtime(), sip_peer::flags_page2, SIP_PAGE2_IGNOREREGEXPIRE, and SIP_PAGE2_RT_FROMCONTACT.

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

05703 {
05704    if (!ast_test_flag((&global_flags_page2), SIP_PAGE2_IGNOREREGEXPIRE)) {
05705       if (ast_test_flag(&(peer->flags_page2), SIP_PAGE2_RT_FROMCONTACT)) {
05706          ast_update_realtime("sippeers", "name", peer->name, "fullcontact", "", "ipaddr", "", "port", "", "regseconds", "0", "username", "", NULL);
05707       } else {
05708          ast_db_del("SIP/Registry", peer->name);
05709       }
05710    }
05711 }

static int determine_firstline_parts struct sip_request req  )  [static]
 

determine_firstline_parts: parse first line of incoming SIP request

Definition at line 4615 of file chan_sip.c.

References sip_request::header, sip_request::len, sip_request::rlPart1, and sip_request::rlPart2.

Referenced by parse_request(), transmit_notify_with_mwi(), transmit_notify_with_sipfrag(), transmit_register(), and transmit_sip_request().

04616 {
04617    char *e, *cmd;
04618    int len;
04619   
04620    cmd = ast_skip_blanks(req->header[0]);
04621    if (!*cmd)
04622       return -1;
04623    req->rlPart1 = cmd;
04624    e = ast_skip_nonblanks(cmd);
04625    /* Get the command */
04626    if (*e)
04627       *e++ = '\0';
04628    e = ast_skip_blanks(e);
04629    if ( !*e )
04630       return -1;
04631 
04632    if ( !strcasecmp(cmd, "SIP/2.0") ) {
04633       /* We have a response */
04634       req->rlPart2 = e;
04635       len = strlen( req->rlPart2 );
04636       if ( len < 2 ) { 
04637          return -1;
04638       }
04639       ast_trim_blanks(e);
04640    } else {
04641       /* We have a request */
04642       if ( *e == '<' ) { 
04643          e++;
04644          if ( !*e ) { 
04645             return -1; 
04646          }  
04647       }
04648       req->rlPart2 = e; /* URI */
04649       if ( ( e= strrchr( req->rlPart2, 'S' ) ) == NULL ) {
04650          return -1;
04651       }
04652       /* XXX maybe trim_blanks() ? */
04653       while( isspace( *(--e) ) ) {}
04654       if ( *e == '>' ) {
04655          *e = '\0';
04656       } else {
04657          *(++e)= '\0';
04658       }
04659    }
04660    return 1;
04661 }

static void* do_monitor void *  data  )  [static]
 

do_monitor: The SIP monitoring thread ---

Definition at line 11395 of file chan_sip.c.

References __sip_destroy(), ast_channel::_state, ast_io_add(), AST_IO_IN, ast_io_wait(), ast_log(), ast_mutex_lock(), ast_mutex_trylock(), ast_mutex_unlock(), ast_rtp_get_peer(), ast_rtp_sendcng(), ast_sched_runq(), ast_sched_wait(), ast_softhangup(), AST_SOFTHANGUP_DEV, AST_STATE_UP, ast_strlen_zero(), ast_test_flag, ast_verbose(), ASTOBJ_CONTAINER_TRAVERSE, ASTOBJ_REF, ASTOBJ_UNLOCK, ASTOBJ_UNREF, ASTOBJ_WRLOCK, global_mwitime, iflist, sip_pvt::lastrtprx, sip_pvt::lastrtptx, ast_channel::lock, sip_pvt::lock, LOG_DEBUG, LOG_NOTICE, ast_channel::name, sip_pvt::next, option_verbose, sip_pvt::owner, sip_pvt::packets, peerl, sip_pvt::redirip, sip_pvt::rtp, sip_pvt::rtpholdtimeout, sip_pvt::rtpkeepalive, sip_pvt::rtptimeout, sip_destroy_peer(), sip_do_reload(), SIP_NEEDDESTROY, sip_reloading, sip_send_mwi_to_peer(), sipsock, sipsock_read(), t, and VERBOSE_PREFIX_1.

11396 {
11397    int res;
11398    struct sip_pvt *sip;
11399    struct sip_peer *peer = NULL;
11400    time_t t;
11401    int fastrestart =0;
11402    int lastpeernum = -1;
11403    int curpeernum;
11404    int reloading;
11405 
11406    /* Add an I/O event to our UDP socket */
11407    if (sipsock > -1) 
11408       ast_io_add(io, sipsock, sipsock_read, AST_IO_IN, NULL);
11409    
11410    /* This thread monitors all the frame relay interfaces which are not yet in use
11411       (and thus do not have a separate thread) indefinitely */
11412    /* From here on out, we die whenever asked */
11413    for(;;) {
11414       /* Check for a reload request */
11415       ast_mutex_lock(&sip_reload_lock);
11416       reloading = sip_reloading;
11417       sip_reloading = 0;
11418       ast_mutex_unlock(&sip_reload_lock);
11419       if (reloading) {
11420          if (option_verbose > 0)
11421             ast_verbose(VERBOSE_PREFIX_1 "Reloading SIP\n");
11422          sip_do_reload();
11423       }
11424       /* Check for interfaces needing to be killed */
11425       ast_mutex_lock(&iflock);
11426 restartsearch:    
11427       time(&t);
11428       sip = iflist;
11429       while(sip) {
11430          ast_mutex_lock(&sip->lock);
11431          if (sip->rtp && sip->owner && (sip->owner->_state == AST_STATE_UP) && !sip->redirip.sin_addr.s_addr) {
11432             if (sip->lastrtptx && sip->rtpkeepalive && t > sip->lastrtptx + sip->rtpkeepalive) {
11433                /* Need to send an empty RTP packet */
11434                time(&sip->lastrtptx);
11435                ast_rtp_sendcng(sip->rtp, 0);
11436             }
11437             if (sip->lastrtprx && (sip->rtptimeout || sip->rtpholdtimeout) && t > sip->lastrtprx + sip->rtptimeout) {
11438                /* Might be a timeout now -- see if we're on hold */
11439                struct sockaddr_in sin;
11440                ast_rtp_get_peer(sip->rtp, &sin);
11441                if (sin.sin_addr.s_addr || 
11442                      (sip->rtpholdtimeout && 
11443                        (t > sip->lastrtprx + sip->rtpholdtimeout))) {
11444                   /* Needs a hangup */
11445                   if (sip->rtptimeout) {
11446                      while(sip->owner && ast_mutex_trylock(&sip->owner->lock)) {
11447                         ast_mutex_unlock(&sip->lock);
11448                         usleep(1);
11449                         ast_mutex_lock(&sip->lock);
11450                      }
11451                      if (sip->owner) {
11452                         ast_log(LOG_NOTICE, "Disconnecting call '%s' for lack of RTP activity in %ld seconds\n", sip->owner->name, (long)(t - sip->lastrtprx));
11453                         /* Issue a softhangup */
11454                         ast_softhangup(sip->owner, AST_SOFTHANGUP_DEV);
11455                         ast_mutex_unlock(&sip->owner->lock);
11456                      }
11457                   }
11458                }
11459             }
11460          }
11461          if (ast_test_flag(sip, SIP_NEEDDESTROY) && !sip->packets && !sip->owner) {
11462             ast_mutex_unlock(&sip->lock);
11463             __sip_destroy(sip, 1);
11464             goto restartsearch;
11465          }
11466          ast_mutex_unlock(&sip->lock);
11467          sip = sip->next;
11468       }
11469       ast_mutex_unlock(&iflock);
11470       /* Don't let anybody kill us right away.  Nobody should lock the interface list
11471          and wait for the monitor list, but the other way around is okay. */
11472       ast_mutex_lock(&monlock);
11473       /* Lock the network interface */
11474       ast_mutex_lock(&netlock);
11475       /* Okay, now that we know what to do, release the network lock */
11476       ast_mutex_unlock(&netlock);
11477       /* And from now on, we're okay to be killed, so release the monitor lock as well */
11478       ast_mutex_unlock(&monlock);
11479       pthread_testcancel();
11480       /* Wait for sched or io */
11481       res = ast_sched_wait(sched);
11482       if ((res < 0) || (res > 1000))
11483          res = 1000;
11484       /* If we might need to send more mailboxes, don't wait long at all.*/
11485       if (fastrestart)
11486          res = 1;
11487       res = ast_io_wait(io, res);
11488       if (res > 20)
11489          ast_log(LOG_DEBUG, "chan_sip: ast_io_wait ran %d all at once\n", res);
11490       ast_mutex_lock(&monlock);
11491       if (res >= 0)  {
11492          res = ast_sched_runq(sched);
11493          if (res >= 20)
11494             ast_log(LOG_DEBUG, "chan_sip: ast_sched_runq ran %d all at once\n", res);
11495       }
11496 
11497       /* needs work to send mwi to realtime peers */
11498       time(&t);
11499       fastrestart = 0;
11500       curpeernum = 0;
11501       peer = NULL;
11502       ASTOBJ_CONTAINER_TRAVERSE(&peerl, !peer, do {
11503          if ((curpeernum > lastpeernum) && !ast_strlen_zero(iterator->mailbox) && ((t - iterator->lastmsgcheck) > global_mwitime)) {
11504             fastrestart = 1;
11505             lastpeernum = curpeernum;
11506             peer = ASTOBJ_REF(iterator);
11507          };
11508          curpeernum++;
11509       } while (0)
11510       );
11511       if (peer) {
11512          ASTOBJ_WRLOCK(peer);
11513          sip_send_mwi_to_peer(peer);
11514          ASTOBJ_UNLOCK(peer);
11515          ASTOBJ_UNREF(peer,sip_destroy_peer);
11516       } else {
11517          /* Reset where we come from */
11518          lastpeernum = -1;
11519       }
11520       ast_mutex_unlock(&monlock);
11521    }
11522    /* Never reached */
11523    return NULL;
11524    
11525 }

static int do_proxy_auth struct sip_pvt p,
struct sip_request req,
char *  header,
char *  respheader,
int  sipmethod,
int  init
[static]
 

do_proxy_auth: Add authentication on outbound SIP packet ---

Definition at line 9001 of file chan_sip.c.

References ast_log(), sip_invite_param::auth, sip_invite_param::authheader, sip_pvt::authtries, calloc, LOG_DEBUG, LOG_ERROR, option_debug, sip_pvt::options, reply_digest(), SIP_INVITE, sip_methods, cfsip_methods::text, and transmit_invite().

Referenced by handle_response(), and handle_response_invite().

09002 {
09003    char digest[1024];
09004 
09005    if (!p->options) {
09006       p->options = calloc(1, sizeof(*p->options));
09007       if (!p->options) {
09008          ast_log(LOG_ERROR, "Out of memory\n");
09009          return -2;
09010       }
09011    }
09012 
09013    p->authtries++;
09014    if (option_debug > 1)
09015       ast_log(LOG_DEBUG, "Auth attempt %d on %s\n", p->authtries, sip_methods[sipmethod].text);
09016    memset(digest, 0, sizeof(digest));
09017    if (reply_digest(p, req, header, sipmethod, digest, sizeof(digest) )) {
09018       /* No way to authenticate */
09019       return -1;
09020    }
09021    /* Now we have a reply digest */
09022    p->options->auth = digest;
09023    p->options->authheader = respheader;
09024    return transmit_invite(p, sipmethod, sipmethod == SIP_INVITE, init); 
09025 }

static int do_register_auth struct sip_pvt p,
struct sip_request req,
char *  header,
char *  respheader
[static]
 

do_register_auth: Authenticate for outbound registration ---

Definition at line 8977 of file chan_sip.c.

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

Referenced by handle_response_register().

08978 {
08979    char digest[1024];
08980    p->authtries++;
08981    memset(digest,0,sizeof(digest));
08982    if (reply_digest(p, req, header, SIP_REGISTER, digest, sizeof(digest))) {
08983       /* There's nothing to use for authentication */
08984       /* No digest challenge in request */
08985       if (sip_debug_test_pvt(p) && p->registry)
08986          ast_verbose("No authentication challenge, sending blank registration to domain/host name %s\n", p->registry->hostname);
08987          /* No old challenge */
08988       return -1;
08989    }
08990    if (recordhistory) {
08991       char tmp[80];
08992       snprintf(tmp, sizeof(tmp), "Try: %d", p->authtries);
08993       append_history(p, "RegistryAuth", tmp);
08994    }
08995    if (sip_debug_test_pvt(p) && p->registry)
08996       ast_verbose("Responding to challenge, registration to domain/host name %s\n", p->registry->hostname);
08997    return transmit_register(p->registry, SIP_REGISTER, digest, respheader); 
08998 }

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

Definition at line 7920 of file chan_sip.c.

References SIP_DOMAIN_AUTO, and SIP_DOMAIN_CONFIG.

Referenced by sip_show_domains().

07921 {
07922    switch (mode) {
07923    case SIP_DOMAIN_AUTO:
07924       return "[Automatic]";
07925    case SIP_DOMAIN_CONFIG:
07926       return "[Configured]";
07927    }
07928 
07929    return "";
07930 }

static const char* dtmfmode2str int  mode  )  [static]
 

dtmfmode2str: Convert DTMF mode to printable string ---

Definition at line 7728 of file chan_sip.c.

References SIP_DTMF_AUTO, SIP_DTMF_INBAND, SIP_DTMF_INFO, and SIP_DTMF_RFC2833.

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

07729 {
07730    switch (mode) {
07731    case SIP_DTMF_RFC2833:
07732       return "rfc2833";
07733    case SIP_DTMF_INFO:
07734       return "info";
07735    case SIP_DTMF_INBAND:
07736       return "inband";
07737    case SIP_DTMF_AUTO:
07738       return "auto";
07739    }
07740    return "<error>";
07741 }

static int expire_register void *  data  )  [static]
 

expire_register: Expire registration of SIP peer ---

Definition at line 5714 of file chan_sip.c.

References sip_peer::addr, ast_device_state_changed(), ast_test_flag, ASTOBJ_CONTAINER_UNLINK, ASTOBJ_UNREF, destroy_association(), EVENT_FLAG_SYSTEM, sip_peer::expire, sip_peer::flags_page2, manager_event(), peerl, register_peer_exten(), sip_destroy_peer(), SIP_PAGE2_RTAUTOCLEAR, and SIP_SELFDESTRUCT.

Referenced by parse_register_contact(), realtime_peer(), and reg_source_db().

05715 {
05716    struct sip_peer *peer = data;
05717    
05718    if (!peer)     /* Hmmm. We have no peer. Weird. */
05719       return 0;
05720 
05721    memset(&peer->addr, 0, sizeof(peer->addr));
05722 
05723    destroy_association(peer);
05724    
05725    manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: SIP/%s\r\nPeerStatus: Unregistered\r\nCause: Expired\r\n", peer->name);
05726    register_peer_exten(peer, 0); /* Remove regexten */
05727    peer->expire = -1;
05728    ast_device_state_changed("SIP/%s", peer->name);
05729 
05730    /* Do we need to release this peer from memory? 
05731       Only for realtime peers and autocreated peers
05732    */
05733    if (ast_test_flag(peer, SIP_SELFDESTRUCT) || ast_test_flag((&peer->flags_page2), SIP_PAGE2_RTAUTOCLEAR)) {
05734       peer = ASTOBJ_CONTAINER_UNLINK(&peerl, peer);   /* Remove from peer list */
05735       ASTOBJ_UNREF(peer, sip_destroy_peer);
05736    }
05737 
05738    return 0;
05739 }

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

extract_uri: Check Contact: URI of SIP message ---

Definition at line 4693 of file chan_sip.c.

References ast_strlen_zero(), get_header(), get_in_brackets(), n, and sip_pvt::uri.

Referenced by handle_request(), and handle_request_invite().

04694 {
04695    char stripped[256];
04696    char *c, *n;
04697    ast_copy_string(stripped, get_header(req, "Contact"), sizeof(stripped));
04698    c = get_in_brackets(stripped);
04699    n = strchr(c, ';');
04700    if (n)
04701       *n = '\0';
04702    if (!ast_strlen_zero(c))
04703       ast_copy_string(p->uri, c, sizeof(p->uri));
04704 }

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

Definition at line 2915 of file chan_sip.c.

References aliases.

02916 {
02917    int x;
02918    for (x=0;x<sizeof(aliases) / sizeof(aliases[0]); x++) 
02919       if (!strcasecmp(aliases[x].fullname, name))
02920          return aliases[x].shortname;
02921    return _default;
02922 }

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

find_call: Connect incoming SIP message to current dialog or create new dialog structure

Definition at line 3147 of file chan_sip.c.

References ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_set_flag, ast_strlen_zero(), sip_pvt::callid, get_header(), gettag(), iflist, sip_pvt::lock, LOG_DEBUG, sip_request::method, sip_pvt::next, option_debug, pedanticsipchecking, sip_alloc(), sip_methods, SIP_PKT_WITH_TOTAG, SIP_REGISTER, SIP_RESPONSE, sip_pvt::tag, and sip_pvt::theirtag.

Referenced by sipsock_read().

03148 {
03149    struct sip_pvt *p;
03150    char *callid;
03151    char *tag = "";
03152    char totag[128];
03153    char fromtag[128];
03154 
03155    callid = get_header(req, "Call-ID");
03156 
03157    if (pedanticsipchecking) {
03158       /* In principle Call-ID's uniquely identify a call, but with a forking SIP proxy
03159          we need more to identify a branch - so we have to check branch, from
03160          and to tags to identify a call leg.
03161          For Asterisk to behave correctly, you need to turn on pedanticsipchecking
03162          in sip.conf
03163          */
03164       if (gettag(req, "To", totag, sizeof(totag)))
03165          ast_set_flag(req, SIP_PKT_WITH_TOTAG); /* Used in handle_request/response */
03166       gettag(req, "From", fromtag, sizeof(fromtag));
03167 
03168       if (req->method == SIP_RESPONSE)
03169          tag = totag;
03170       else
03171          tag = fromtag;
03172          
03173 
03174       if (option_debug > 4 )
03175          ast_log(LOG_DEBUG, "= Looking for  Call ID: %s (Checking %s) --From tag %s --To-tag %s  \n", callid, req->method==SIP_RESPONSE ? "To" : "From", fromtag, totag);
03176    }
03177 
03178    ast_mutex_lock(&iflock);
03179    p = iflist;
03180    while(p) {  /* In pedantic, we do not want packets with bad syntax to be connected to a PVT */
03181       int found = 0;
03182       if (req->method == SIP_REGISTER)
03183          found = (!strcmp(p->callid, callid));
03184       else 
03185          found = (!strcmp(p->callid, callid) && 
03186          (!pedanticsipchecking || !tag || ast_strlen_zero(p->theirtag) || !strcmp(p->theirtag, tag))) ;
03187 
03188       if (option_debug > 4)
03189          ast_log(LOG_DEBUG, "= %s Their Call ID: %s Their Tag %s Our tag: %s\n", found ? "Found" : "No match", p->callid, p->theirtag, p->tag);
03190 
03191       /* If we get a new request within an existing to-tag - check the to tag as well */
03192       if (pedanticsipchecking && found  && req->method != SIP_RESPONSE) {  /* SIP Request */
03193          if (p->tag[0] == '\0' && totag[0]) {
03194             /* We have no to tag, but they have. Wrong dialog */
03195             found = 0;
03196          } else if (totag[0]) {        /* Both have tags, compare them */
03197             if (strcmp(totag, p->tag)) {
03198                found = 0;     /* This is not our packet */
03199             }
03200          }
03201          if (!found && option_debug > 4)
03202             ast_log(LOG_DEBUG, "= Being pedantic: This is not our match on request: Call ID: %s Ourtag <null> Totag %s Method %s\n", p->callid, totag, sip_methods[req->method].text);
03203       }
03204 
03205 
03206       if (found) {
03207          /* Found the call */
03208          ast_mutex_lock(&p->lock);
03209          ast_mutex_unlock(&iflock);
03210          return p;
03211       }
03212       p = p->next;
03213    }
03214    ast_mutex_unlock(&iflock);
03215    p = sip_alloc(callid, sin, 1, intended_method);
03216    if (p)
03217       ast_mutex_lock(&p->lock);
03218    return p;
03219 }

static struct sip_peer* find_peer const char *  peer,
struct sockaddr_in *  sin,
int  realtime
[static]
 

find_peer: Locate peer by name or ip address This is used on incoming SIP message to find matching peer on ip or outgoing message to find matching peer on name

Definition at line 1757 of file chan_sip.c.

References ASTOBJ_CONTAINER_FIND, ASTOBJ_CONTAINER_FIND_FULL, name, peerl, realtime_peer(), and sip_addrcmp().

01758 {
01759    struct sip_peer *p = NULL;
01760 
01761    if (peer)
01762       p = ASTOBJ_CONTAINER_FIND(&peerl,peer);
01763    else
01764       p = ASTOBJ_CONTAINER_FIND_FULL(&peerl,sin,name,sip_addr_hashfunc,1,sip_addrcmp);
01765 
01766    if (!p && realtime) {
01767       p = realtime_peer(peer, sin);
01768    }
01769 
01770    return p;
01771 }

static struct sip_auth * find_realm_authentication struct sip_auth authlist,
char *  realm
[static]
 

find_realm_authentication: Find authentication for a specific realm ---

Definition at line 12049 of file chan_sip.c.

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

Referenced by build_reply_digest().

12050 {
12051    struct sip_auth *a = authlist;   /* First entry in auth list */
12052 
12053    while (a) {
12054       if (!strcasecmp(a->realm, realm)){
12055          break;
12056       }
12057       a = a->next;
12058    }
12059    
12060    return a;
12061 }

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_end to indicate where the SDP lives in the message body.

Definition at line 3419 of file chan_sip.c.

References ast_strdupa, ast_strlen_zero(), get_header(), sip_request::line, sip_request::lines, sip_request::sdp_end, sip_request::sdp_start, and strcasestr().

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

03420 {
03421    char *content_type;
03422    char *search;
03423    char *boundary;
03424    unsigned int x;
03425 
03426    content_type = get_header(req, "Content-Type");
03427 
03428    /* if the body contains only SDP, this is easy */
03429    if (!strcasecmp(content_type, "application/sdp")) {
03430       req->sdp_start = 0;
03431       req->sdp_end = req->lines;
03432       return 1;
03433    }
03434 
03435    /* if it's not multipart/mixed, there cannot be an SDP */
03436    if (strncasecmp(content_type, "multipart/mixed", 15))
03437       return 0;
03438 
03439    /* if there is no boundary marker, it's invalid */
03440    if (!(search = strcasestr(content_type, ";boundary=")))
03441       return 0;
03442 
03443    search += 10;
03444 
03445    if (ast_strlen_zero(search))
03446       return 0;
03447 
03448    /* make a duplicate of the string, with two extra characters
03449       at the beginning */
03450    boundary = ast_strdupa(search - 2);
03451    boundary[0] = boundary[1] = '-';
03452 
03453    /* search for the boundary marker, but stop when there are not enough
03454       lines left for it, the Content-Type header and at least one line of
03455       body */
03456    for (x = 0; x < (req->lines - 2); x++) {
03457       if (!strncasecmp(req->line[x], boundary, strlen(boundary)) &&
03458           !strcasecmp(req->line[x + 1], "Content-Type: application/sdp")) {
03459          req->sdp_start = x + 2;
03460          /* search for the end of the body part */
03461          for ( ; x < req->lines; x++) {
03462             if (!strncasecmp(req->line[x], boundary, strlen(boundary)))
03463                break;
03464          }
03465          req->sdp_end = x;
03466          return 1;
03467       }
03468    }
03469 
03470    return 0;
03471 }

int find_sip_method char *  msg  ) 
 

find_sip_method: Find SIP method from header Strictly speaking, SIP methods are case SENSITIVE, but we don't check following Jon Postel's rule: Be gentle in what you accept, strict with what you send

Definition at line 977 of file chan_sip.c.

References ast_strlen_zero(), sip_methods, and text.

Referenced by __sip_pretend_ack(), handle_response(), and sipsock_read().

00978 {
00979    int i, res = 0;
00980    
00981    if (ast_strlen_zero(msg))
00982       return 0;
00983 
00984    for (i = 1; (i < (sizeof(sip_methods) / sizeof(sip_methods[0]))) && !res; i++) {
00985       if (!strcasecmp(sip_methods[i].text, msg)) 
00986          res = sip_methods[i].id;
00987    }
00988    return res;
00989 }

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

find_subscription_type: Find subscription type in array

Definition at line 8364 of file chan_sip.c.

References subscription_types, and type.

Referenced by transmit_state_notify().

08364                                                                                                 {
08365    int i;
08366 
08367    for (i = 1; (i < (sizeof(subscription_types) / sizeof(subscription_types[0]))); i++) {
08368       if (subscription_types[i].type == subtype) {
08369          return &subscription_types[i];
08370       }
08371    }
08372    return &subscription_types[0];
08373 }

static struct sip_user* find_user const char *  name,
int  realtime
[static]
 

find_user: Locate user by name Locates user by name (From: sip uri user name part) first from in-memory list (static configuration) then from realtime storage (defined in extconfig.conf)

Definition at line 1839 of file chan_sip.c.

References ASTOBJ_CONTAINER_FIND, realtime_user(), and userl.

01840 {
01841    struct sip_user *u = NULL;
01842    u = ASTOBJ_CONTAINER_FIND(&userl,name);
01843    if (!u && realtime) {
01844       u = realtime_user(name);
01845    }
01846    return u;
01847 }

static void free_old_route struct sip_route route  )  [static]
 

free_old_route: Remove route from route list ---

Definition at line 6041 of file chan_sip.c.

References free, and sip_route::next.

Referenced by __sip_destroy(), and build_route().

06042 {
06043    struct sip_route *next;
06044    while (route) {
06045       next = route->next;
06046       free(route);
06047       route = next;
06048    }
06049 }

static char* func_check_sipdomain struct ast_channel chan,
char *  cmd,
char *  data,
char *  buf,
size_t  len
[static]
 

function_check_sipdomain: Dial plan function to check if domain is local

Definition at line 9318 of file chan_sip.c.

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

09319 {
09320    if (ast_strlen_zero(data)) {
09321       ast_log(LOG_WARNING, "CHECKSIPDOMAIN requires an argument - A domain name\n");
09322       return buf;
09323    }
09324    if (check_sip_domain(data, NULL, 0))
09325       ast_copy_string(buf, data, len);
09326    else
09327       buf[0] = '\0';
09328    return buf;
09329 }

static char* func_header_read struct ast_channel chan,
char *  cmd,
char *  data,
char *  buf,
size_t  len
[static]
 

func_header_read: Read SIP header (dialplan function)

Definition at line 9271 of file chan_sip.c.

References ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_strlen_zero(), channeltype, get_header(), sip_pvt::initreq, ast_channel::lock, LOG_WARNING, ast_channel::tech_pvt, and ast_channel::type.

09272 {
09273    struct sip_pvt *p;
09274    char *content;
09275    
09276    if (!data) {
09277       ast_log(LOG_WARNING, "This function requires a header name.\n");
09278       return NULL;
09279    }
09280 
09281    ast_mutex_lock(&chan->lock);
09282    if (chan->type != channeltype) {
09283       ast_log(LOG_WARNING, "This function can only be used on SIP channels.\n");
09284       ast_mutex_unlock(&chan->lock);
09285       return NULL;
09286    }
09287 
09288    p = chan->tech_pvt;
09289 
09290    /* If there is no private structure, this channel is no longer alive */
09291    if (!p) {
09292       ast_mutex_unlock(&chan->lock);
09293       return NULL;
09294    }
09295 
09296    content = get_header(&p->initreq, data);
09297 
09298    if (ast_strlen_zero(content)) {
09299       ast_mutex_unlock(&chan->lock);
09300       return NULL;
09301    }
09302 
09303    ast_copy_string(buf, content, len);
09304    ast_mutex_unlock(&chan->lock);
09305 
09306    return buf;
09307 }

static char* function_sipchaninfo_read struct ast_channel chan,
char *  cmd,
char *  data,
char *  buf,
size_t  len
[static]
 

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

Definition at line 9445 of file chan_sip.c.

References ast_inet_ntoa(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), channeltype, sip_pvt::from, ast_channel::lock, LOG_WARNING, sip_pvt::peername, sip_pvt::recv, sip_pvt::sa, ast_channel::tech_pvt, ast_channel::type, sip_pvt::uri, and sip_pvt::useragent.

09446 {
09447    struct sip_pvt *p;
09448    char iabuf[INET_ADDRSTRLEN];
09449 
09450    *buf = 0;
09451    
09452    if (!data) {
09453       ast_log(LOG_WARNING, "This function requires a parameter name.\n");
09454       return NULL;
09455    }
09456 
09457    ast_mutex_lock(&chan->lock);
09458    if (chan->type != channeltype) {
09459       ast_log(LOG_WARNING, "This function can only be used on SIP channels.\n");
09460       ast_mutex_unlock(&chan->lock);
09461       return NULL;
09462    }
09463 
09464 /*    ast_verbose("function_sipchaninfo_read: %s\n", data); */
09465    p = chan->tech_pvt;
09466 
09467    /* If there is no private structure, this channel is no longer alive */
09468    if (!p) {
09469       ast_mutex_unlock(&chan->lock);
09470       return NULL;
09471    }
09472 
09473    if (!strcasecmp(data, "peerip")) {
09474       ast_copy_string(buf, p->sa.sin_addr.s_addr ? ast_inet_ntoa(iabuf, sizeof(iabuf), p->sa.sin_addr) : "", len);
09475    } else  if (!strcasecmp(data, "recvip")) {
09476       ast_copy_string(buf, p->recv.sin_addr.s_addr ? ast_inet_ntoa(iabuf, sizeof(iabuf), p->recv.sin_addr) : "", len);
09477    } else  if (!strcasecmp(data, "from")) {
09478       ast_copy_string(buf, p->from, len);
09479    } else  if (!strcasecmp(data, "uri")) {
09480       ast_copy_string(buf, p->uri, len);
09481    } else  if (!strcasecmp(data, "useragent")) {
09482       ast_copy_string(buf, p->useragent, len);
09483    } else  if (!strcasecmp(data, "peername")) {
09484       ast_copy_string(buf, p->peername, len);
09485    } else {
09486       ast_mutex_unlock(&chan->lock);
09487       return NULL;
09488    }
09489    ast_mutex_unlock(&chan->lock);
09490 
09491    return buf;
09492 }

static char* function_sippeer struct ast_channel chan,
char *  cmd,
char *  data,
char *  buf,
size_t  len
[static]
 

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

Definition at line 9344 of file chan_sip.c.

References sip_peer::accountcode, sip_peer::addr, ast_codec_pref_index(), ast_getformatname(), ast_getformatname_multiple(), ast_inet_ntoa(), ast_log(), ast_strdupa, ast_test_flag, ASTOBJ_UNREF, sip_peer::call_limit, sip_peer::capability, sip_peer::cid_name, sip_peer::cid_num, sip_peer::context, sip_peer::expire, find_peer(), sip_peer::flags_page2, sip_peer::inUse, sip_peer::language, LOG_ERROR, sip_peer::mailbox, peer_status(), sip_peer::prefs, sip_peer::regexten, sip_destroy_peer(), SIP_PAGE2_DYNAMIC, and sip_peer::useragent.

09345 {
09346    char *ret = NULL;
09347    struct sip_peer *peer;
09348    char *peername, *colname;
09349    char iabuf[INET_ADDRSTRLEN];
09350 
09351    if (!(peername = ast_strdupa(data))) {
09352       ast_log(LOG_ERROR, "Memory Error!\n");
09353       return ret;
09354    }
09355 
09356    if ((colname = strchr(peername, ':'))) {
09357       *colname = '\0';
09358       colname++;
09359    } else {
09360       colname = "ip";
09361    }
09362    if (!(peer = find_peer(peername, NULL, 1)))
09363       return ret;
09364 
09365    if (!strcasecmp(colname, "ip")) {
09366       ast_copy_string(buf, peer->addr.sin_addr.s_addr ? ast_inet_ntoa(iabuf, sizeof(iabuf), peer->addr.sin_addr) : "", len);
09367    } else  if (!strcasecmp(colname, "status")) {
09368       peer_status(peer, buf, len);
09369    } else  if (!strcasecmp(colname, "language")) {
09370       ast_copy_string(buf, peer->language, len);
09371    } else  if (!strcasecmp(colname, "regexten")) {
09372       ast_copy_string(buf, peer->regexten, len);
09373    } else  if (!strcasecmp(colname, "limit")) {
09374       snprintf(buf, len, "%d", peer->call_limit);
09375    } else  if (!strcasecmp(colname, "curcalls")) {
09376       snprintf(buf, len, "%d", peer->inUse);
09377    } else  if (!strcasecmp(colname, "accountcode")) {
09378       ast_copy_string(buf, peer->accountcode, len);
09379    } else  if (!strcasecmp(colname, "useragent")) {
09380       ast_copy_string(buf, peer->useragent, len);
09381    } else  if (!strcasecmp(colname, "mailbox")) {
09382       ast_copy_string(buf, peer->mailbox, len);
09383    } else  if (!strcasecmp(colname, "context")) {
09384       ast_copy_string(buf, peer->context, len);
09385    } else  if (!strcasecmp(colname, "expire")) {
09386       snprintf(buf, len, "%d", peer->expire);
09387    } else  if (!strcasecmp(colname, "dynamic")) {
09388       ast_copy_string(buf, (ast_test_flag(&peer->flags_page2, SIP_PAGE2_DYNAMIC) ? "yes" : "no"), len);
09389    } else  if (!strcasecmp(colname, "callerid_name")) {
09390       ast_copy_string(buf, peer->cid_name, len);
09391    } else  if (!strcasecmp(colname, "callerid_num")) {
09392       ast_copy_string(buf, peer->cid_num, len);
09393    } else  if (!strcasecmp(colname, "codecs")) {
09394       ast_getformatname_multiple(buf, len -1, peer->capability);
09395    } else  if (!strncasecmp(colname, "codec[", 6)) {
09396       char *codecnum, *ptr;
09397       int index = 0, codec = 0;
09398       
09399       codecnum = strchr(colname, '[');
09400       *codecnum = '\0';
09401       codecnum++;
09402       if ((ptr = strchr(codecnum, ']'))) {
09403          *ptr = '\0';
09404       }
09405       index = atoi(codecnum);
09406       if((codec = ast_codec_pref_index(&peer->prefs, index))) {
09407          ast_copy_string(buf, ast_getformatname(codec), len);
09408       }
09409    }
09410    ret = buf;
09411 
09412    ASTOBJ_UNREF(peer, sip_destroy_peer);
09413 
09414    return ret;
09415 }

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

get_also_info: Call transfer support (old way, depreciated)--

Definition at line 6897 of file chan_sip.c.

References ast_canmatch_extension(), ast_exists_extension(), ast_log(), ast_verbose(), get_header(), get_in_brackets(), LOG_DEBUG, LOG_WARNING, and sip_debug_test_pvt().

Referenced by handle_request_bye().

06898 {
06899    char tmp[256], *c, *a;
06900    struct sip_request *req;
06901    
06902    req = oreq;
06903    if (!req)
06904       req = &p->initreq;
06905    ast_copy_string(tmp, get_header(req, "Also"), sizeof(tmp));
06906    
06907    c = get_in_brackets(tmp);
06908    
06909       
06910    if (strncmp(c, "sip:", 4)) {
06911       ast_log(LOG_WARNING, "Huh?  Not a SIP header (%s)?\n", c);
06912       return -1;
06913    }
06914    c += 4;
06915    if ((a = strchr(c, '@')))
06916       *a = '\0';
06917    if ((a = strchr(c, ';'))) 
06918       *a = '\0';
06919    
06920    if (sip_debug_test_pvt(p)) {
06921       ast_verbose("Looking for %s in %s\n", c, p->context);
06922    }
06923    if (ast_exists_extension(NULL, p->context, c, 1, NULL)) {
06924       /* This is an unsupervised transfer */
06925       ast_log(LOG_DEBUG,"Assigning Extension %s to REFER-TO\n", c);
06926       ast_copy_string(p->refer_to, c, sizeof(p->refer_to));
06927       ast_copy_string(p->referred_by, "", sizeof(p->referred_by));
06928       ast_copy_string(p->refer_contact, "", sizeof(p->refer_contact));
06929       p->refer_call = NULL;
06930       return 0;
06931    } else if (ast_canmatch_extension(NULL, p->context, c, 1, NULL)) {
06932       return 1;
06933    }
06934 
06935    return -1;
06936 }

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

get_body: get a specific line from the message body

Definition at line 2901 of file chan_sip.c.

References get_body_by_line(), and sip_request::line.

Referenced by handle_request_info().

02902 {
02903    int x;
02904    int len = strlen(name);
02905    char *r;
02906 
02907    for (x = 0; x < req->lines; x++) {
02908       r = get_body_by_line(req->line[x], name, len);
02909       if (r[0] != '\0')
02910          return r;
02911    }
02912    return "";
02913 }

static char* get_body_by_line char *  line,
char *  name,
int  nameLen
[static]
 

get_body_by_line: Reads one line of message body

Definition at line 2858 of file chan_sip.c.

Referenced by get_body(), get_sdp(), and get_sdp_iterate().

02859 {
02860    if (strncasecmp(line, name, nameLen) == 0 && line[nameLen] == '=') {
02861       return ast_skip_blanks(line + nameLen + 1);
02862    }
02863    return "";
02864 }

static char* get_calleridname char *  input,
char *  output,
size_t  outputsize
[static]
 

get_calleridname: Get caller id name from SIP headers ---

Definition at line 6988 of file chan_sip.c.

Referenced by check_user_full().

06989 {
06990    char *end = strchr(input,'<');
06991    char *tmp = strchr(input,'\"');
06992    int bytes = 0;
06993    int maxbytes = outputsize - 1;
06994 
06995    if (!end || (end == input)) return NULL;
06996    /* move away from "<" */
06997    end--;
06998    /* we found "name" */
06999    if (tmp && tmp < end) {
07000       end = strchr(tmp+1, '\"');
07001       if (!end) return NULL;
07002       bytes = (int) (end - tmp);
07003       /* protect the output buffer */
07004       if (bytes > maxbytes)
07005          bytes = maxbytes;
07006       ast_copy_string(output, tmp + 1, bytes);
07007    } else {
07008       /* we didn't find "name" */
07009       /* clear the empty characters in the begining*/
07010       input = ast_skip_blanks(input);
07011       /* clear the empty characters in the end */
07012       while(*end && (*end < 33) && end > input)
07013          end--;
07014       if (end >= input) {
07015          bytes = (int) (end - input) + 2;
07016          /* protect the output buffer */
07017          if (bytes > maxbytes) {
07018             bytes = maxbytes;
07019          }
07020          ast_copy_string(output, input, bytes);
07021       }
07022       else
07023          return NULL;
07024    }
07025    return output;
07026 }

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

get_destination: Find out who the call is for --

Definition at line 6625 of file chan_sip.c.

References allow_external_domains, ast_canmatch_extension(), ast_exists_extension(), AST_LIST_EMPTY, ast_log(), AST_MAX_EXTENSION, ast_pickup_ext(), ast_strlen_zero(), ast_uri_decode(), ast_verbose(), check_sip_domain(), sip_pvt::context, sip_pvt::domain, sip_pvt::exten, sip_pvt::fromdomain, get_header(), get_in_brackets(), sip_pvt::initreq, LOG_DEBUG, LOG_WARNING, sip_request::method, pedanticsipchecking, sip_request::rlPart2, sip_debug_test_pvt(), SIP_INVITE, sip_methods, and SIP_REFER.

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

06626 {
06627    char tmp[256] = "", *uri, *a;
06628    char tmpf[256], *from;
06629    struct sip_request *req;
06630    char *colon;
06631    
06632    req = oreq;
06633    if (!req)
06634       req = &p->initreq;
06635    if (req->rlPart2)
06636       ast_copy_string(tmp, req->rlPart2, sizeof(tmp));
06637    uri = get_in_brackets(tmp);
06638    
06639    ast_copy_string(tmpf, get_header(req, "From"), sizeof(tmpf));
06640 
06641    from = get_in_brackets(tmpf);
06642    
06643    if (strncmp(uri, "sip:", 4)) {
06644       ast_log(LOG_WARNING, "Huh?  Not a SIP header (%s)?\n", uri);
06645       return -1;
06646    }
06647    uri += 4;
06648    if (!ast_strlen_zero(from)) {
06649       if (strncmp(from, "sip:", 4)) {
06650          ast_log(LOG_WARNING, "Huh?  Not a SIP header (%s)?\n", from);
06651          return -1;
06652       }
06653       from += 4;
06654    } else
06655       from = NULL;
06656 
06657    if (pedanticsipchecking) {
06658       ast_uri_decode(uri);
06659       ast_uri_decode(from);
06660    }
06661 
06662    /* Skip any options */
06663    if ((a = strchr(uri, ';'))) {
06664       *a = '\0';
06665    }
06666 
06667    /* Get the target domain */
06668    if ((a = strchr(uri, '@'))) {
06669       *a = '\0';
06670       a++;
06671    } else { /* No username part */
06672       a = uri;
06673       uri = "s";  /* Set extension to "s" */
06674    }
06675    colon = strchr(a, ':'); /* Remove :port */
06676    if (colon)
06677       *colon = '\0';
06678 
06679    ast_copy_string(p->domain, a, sizeof(p->domain));
06680 
06681    if (!AST_LIST_EMPTY(&domain_list)) {
06682       char domain_context[AST_MAX_EXTENSION];
06683 
06684       domain_context[0] = '\0';
06685       if (!check_sip_domain(p->domain, domain_context, sizeof(domain_context))) {
06686          if (!allow_external_domains && (req->method == SIP_INVITE || req->method == SIP_REFER)) {
06687             ast_log(LOG_DEBUG, "Got SIP %s to non-local domain '%s'; refusing request.\n", sip_methods[req->method].text, p->domain);
06688             return -2;
06689          }
06690       }
06691       /* If we have a context defined, overwrite the original context */
06692       if (!ast_strlen_zero(domain_context))
06693          ast_copy_string(p->context, domain_context, sizeof(p->context));
06694    }
06695 
06696    if (from) {
06697       if ((a = strchr(from, ';')))
06698          *a = '\0';
06699       if ((a = strchr(from, '@'))) {
06700          *a = '\0';
06701          ast_copy_string(p->fromdomain, a + 1, sizeof(p->fromdomain));
06702       } else
06703          ast_copy_string(p->fromdomain, from, sizeof(p->fromdomain));
06704    }
06705    if (sip_debug_test_pvt(p))
06706       ast_verbose("Looking for %s in %s (domain %s)\n", uri, p->context, p->domain);
06707 
06708    /* Return 0 if we have a matching extension */
06709    if (ast_exists_extension(NULL, p->context, uri, 1, from) ||
06710       !strcmp(uri, ast_pickup_ext())) {
06711       if (!oreq)
06712          ast_copy_string(p->exten, uri, sizeof(p->exten));
06713       return 0;
06714    }
06715 
06716    /* Return 1 for overlap dialling support */
06717    if (ast_canmatch_extension(NULL, p->context, uri, 1, from) ||
06718        !strncmp(uri, ast_pickup_ext(),strlen(uri))) {
06719       return 1;
06720    }
06721    
06722    return -1;
06723 }

static char * get_header struct sip_request req,
char *  name
[static]
 

get_header: Get header from SIP request ---

Definition at line 2960 of file chan_sip.c.

References __get_header().

02961 {
02962    int start = 0;
02963    return __get_header(req, name, &start);
02964 }

static char* get_in_brackets char *  tmp  )  [static]
 

get_in_brackets: Pick out text in brackets from character string ---

Definition at line 1539 of file chan_sip.c.

References ast_log(), 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().

01540 {
01541    char *parse;
01542    char *first_quote;
01543    char *first_bracket;
01544    char *second_bracket;
01545    char last_char;
01546 
01547    parse = tmp;
01548    while (1) {
01549       first_quote = strchr(parse, '"');
01550       first_bracket = strchr(parse, '<');
01551       if (first_quote && first_bracket && (first_quote < first_bracket)) {
01552          last_char = '\0';
01553          for (parse = first_quote + 1; *parse; parse++) {
01554             if ((*parse == '"') && (last_char != '\\'))
01555                break;
01556             last_char = *parse;
01557          }
01558          if (!*parse) {
01559             ast_log(LOG_WARNING, "No closing quote found in '%s'\n", tmp);
01560             return tmp;
01561          }
01562          parse++;
01563          continue;
01564       }
01565       if (first_bracket) {
01566          second_bracket = strchr(first_bracket + 1, '>');
01567          if (second_bracket) {
01568             *second_bracket = '\0';
01569             return first_bracket + 1;
01570          } else {
01571             ast_log(LOG_WARNING, "No closing bracket found in '%s'\n", tmp);
01572             return tmp;
01573          }
01574       }
01575       return tmp;
01576    }
01577 }

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

get_msg_text: Get text out of a SIP MESSAGE packet ---

Definition at line 7336 of file chan_sip.c.

References sip_request::line.

Referenced by receive_message().

07337 {
07338    int x;
07339    int y;
07340 
07341    buf[0] = '\0';
07342    y = len - strlen(buf) - 5;
07343    if (y < 0)
07344       y = 0;
07345    for (x=0;x<req->lines;x++) {
07346       strncat(buf, req->line[x], y); /* safe */
07347       y -= strlen(req->line[x]) + 1;
07348       if (y < 0)
07349          y = 0;
07350       if (y != 0)
07351          strcat(buf, "\n"); /* safe */
07352    }
07353    return 0;
07354 }

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

get_rdnis: get referring dnis ---

Definition at line 6597 of file chan_sip.c.

References ast_log(), ast_strlen_zero(), ast_verbose(), get_header(), get_in_brackets(), sip_pvt::initreq, LOG_WARNING, sip_pvt::rdnis, and sip_debug_test_pvt().

Referenced by handle_request_invite().

06598 {
06599    char tmp[256], *c, *a;
06600    struct sip_request *req;
06601    
06602    req = oreq;
06603    if (!req)
06604       req = &p->initreq;
06605    ast_copy_string(tmp, get_header(req, "Diversion"), sizeof(tmp));
06606    if (ast_strlen_zero(tmp))
06607       return 0;
06608    c = get_in_brackets(tmp);
06609    if (strncmp(c, "sip:", 4)) {
06610       ast_log(LOG_WARNING, "Huh?  Not an RDNIS SIP header (%s)?\n", c);
06611       return -1;
06612    }
06613    c += 4;
06614    if ((a = strchr(c, '@')) || (a = strchr(c, ';'))) {
06615       *a = '\0';
06616    }
06617    if (sip_debug_test_pvt(p))
06618       ast_verbose("RDNIS is %s\n", c);
06619    ast_copy_string(p->rdnis, c, sizeof(p->rdnis));
06620 
06621    return 0;
06622 }

static int get_refer_info struct sip_pvt sip_pvt,
struct sip_request outgoing_req
[static]
 

get_refer_info: Call transfer support (the REFER method) ---

Definition at line 6755 of file chan_sip.c.

References ast_bridged_channel(), ast_canmatch_extension(), ast_exists_extension(), ast_log(), ast_parking_ext(), ast_strdupa, ast_strlen_zero(), ast_uri_decode(), ast_verbose(), sip_pvt::context, get_header(), get_in_brackets(), get_sip_pvt_byid_locked(), sip_pvt::initreq, LOG_DEBUG, LOG_NOTICE, LOG_WARNING, ast_channel::name, sip_pvt::owner, pbx_builtin_getvar_helper(), pbx_builtin_setvar_helper(), pedanticsipchecking, sip_pvt::refer_to, sip_pvt::referred_by, and sip_debug_test_pvt().

Referenced by handle_request_refer().

06756 {
06757 
06758    char *p_refer_to = NULL, *p_referred_by = NULL, *h_refer_to = NULL, *h_referred_by = NULL, *h_contact = NULL;
06759    char *replace_callid = "", *refer_to = NULL, *referred_by = NULL, *ptr = NULL;
06760    struct sip_request *req = NULL;
06761    struct sip_pvt *sip_pvt_ptr = NULL;
06762    struct ast_channel *chan = NULL, *peer = NULL;
06763    const char *transfercontext;
06764 
06765    req = outgoing_req;
06766 
06767    if (!req) {
06768       req = &sip_pvt->initreq;
06769    }
06770    
06771    if (!( (p_refer_to = get_header(req, "Refer-To")) && (h_refer_to = ast_strdupa(p_refer_to)) )) {
06772       ast_log(LOG_WARNING, "No Refer-To Header That's illegal\n");
06773       return -1;
06774    }
06775 
06776    refer_to = get_in_brackets(h_refer_to);
06777 
06778    if (!( (p_referred_by = get_header(req, "Referred-By")) && (h_referred_by = ast_strdupa(p_referred_by)) )) {
06779       ast_log(LOG_WARNING, "No Referrred-By Header That's not illegal\n");
06780       return -1;
06781    } else {
06782       if (pedanticsipchecking) {
06783          ast_uri_decode(h_referred_by);
06784       }
06785       referred_by = get_in_brackets(h_referred_by);
06786    }
06787    h_contact = get_header(req, "Contact");
06788    
06789    if (strncmp(refer_to, "sip:", 4)) {
06790       ast_log(LOG_WARNING, "Refer-to: Huh?  Not a SIP header (%s)?\n", refer_to);
06791       return -1;
06792    }
06793 
06794    if (strncmp(referred_by, "sip:", 4)) {
06795       ast_log(LOG_WARNING, "Referred-by: Huh?  Not a SIP header (%s) Ignoring?\n", referred_by);
06796       referred_by = NULL;
06797    }
06798 
06799    if (refer_to)
06800       refer_to += 4;
06801 
06802    if (referred_by)
06803       referred_by += 4;
06804    
06805    if ((ptr = strchr(refer_to, '?'))) {
06806       /* Search for arguments */
06807       *ptr = '\0';
06808       ptr++;
06809       if (!strncasecmp(ptr, "REPLACES=", 9)) {
06810          char *p;
06811          replace_callid = ast_strdupa(ptr + 9);
06812          /* someday soon to support invite/replaces properly!
06813             replaces_header = ast_strdupa(replace_callid); 
06814             -anthm
06815          */
06816          ast_uri_decode(replace_callid);
06817          if ((ptr = strchr(replace_callid, '%'))) 
06818             *ptr = '\0';
06819          if ((ptr = strchr(replace_callid, ';'))) 
06820             *ptr = '\0';
06821          /* Skip leading whitespace XXX memmove behaviour with overlaps ? */
06822          p = ast_skip_blanks(replace_callid);
06823          if (p != replace_callid)
06824             memmove(replace_callid, p, strlen(p));
06825       }
06826    }
06827    
06828    if ((ptr = strchr(refer_to, '@')))  /* Skip domain (should be saved in SIPDOMAIN) */
06829       *ptr = '\0';
06830    if ((ptr = strchr(refer_to, ';'))) 
06831       *ptr = '\0';
06832    
06833    if (referred_by) {
06834       if ((ptr = strchr(referred_by, '@')))
06835          *ptr = '\0';
06836       if ((ptr = strchr(referred_by, ';'))) 
06837          *ptr = '\0';
06838    }
06839    
06840    transfercontext = pbx_builtin_getvar_helper(sip_pvt->owner, "TRANSFER_CONTEXT");
06841    if (ast_strlen_zero(transfercontext))
06842       transfercontext = sip_pvt->context;
06843 
06844    if (sip_debug_test_pvt(sip_pvt)) {
06845       ast_verbose("Transfer to %s in %s\n", refer_to, transfercontext);
06846       if (referred_by)
06847          ast_verbose("Transfer from %s in %s\n", referred_by, sip_pvt->context);
06848    }
06849    if (!ast_strlen_zero(replace_callid)) {   
06850       /* This is a supervised transfer */
06851       ast_log(LOG_DEBUG,"Assigning Replace-Call-ID Info %s to REPLACE_CALL_ID\n",replace_callid);
06852       
06853       ast_copy_string(sip_pvt->refer_to, "", sizeof(sip_pvt->refer_to));
06854       ast_copy_string(sip_pvt->referred_by, "", sizeof(sip_pvt->referred_by));
06855       ast_copy_string(sip_pvt->refer_contact, "", sizeof(sip_pvt->refer_contact));
06856       sip_pvt->refer_call = NULL;
06857       if ((sip_pvt_ptr = get_sip_pvt_byid_locked(replace_callid))) {
06858          sip_pvt->refer_call = sip_pvt_ptr;
06859          if (sip_pvt->refer_call == sip_pvt) {
06860             ast_log(LOG_NOTICE, "Supervised transfer attempted to transfer into same call id (%s == %s)!\n", replace_callid, sip_pvt->callid);
06861             sip_pvt->refer_call = NULL;
06862          } else
06863             return 0;
06864       } else {
06865          ast_log(LOG_NOTICE, "Supervised transfer requested, but unable to find callid '%s'.  Both legs must reside on Asterisk box to transfer at this time.\n", replace_callid);
06866          /* XXX The refer_to could contain a call on an entirely different machine, requiring an 
06867               INVITE with a replaces header -anthm XXX */
06868          /* The only way to find out is to use the dialplan - oej */
06869       }
06870    } else if (ast_exists_extension(NULL, transfercontext, refer_to, 1, NULL) || !strcmp(refer_to, ast_parking_ext())) {
06871       /* This is an unsupervised transfer (blind transfer) */
06872       
06873       ast_log(LOG_DEBUG,"Unsupervised transfer to (Refer-To): %s\n", refer_to);
06874       if (referred_by)
06875          ast_log(LOG_DEBUG,"Transferred by  (Referred-by: ) %s \n", referred_by);
06876       ast_log(LOG_DEBUG,"Transfer Contact Info %s (REFER_CONTACT)\n", h_contact);
06877       ast_copy_string(sip_pvt->refer_to, refer_to, sizeof(sip_pvt->refer_to));
06878       if (referred_by)
06879          ast_copy_string(sip_pvt->referred_by, referred_by, sizeof(sip_pvt->referred_by));
06880       if (h_contact) {
06881          ast_copy_string(sip_pvt->refer_contact, h_contact, sizeof(sip_pvt->refer_contact));
06882       }
06883       sip_pvt->refer_call = NULL;
06884       if ((chan = sip_pvt->owner) && (peer = ast_bridged_channel(sip_pvt->owner))) {
06885          pbx_builtin_setvar_helper(chan, "BLINDTRANSFER", peer->name);
06886          pbx_builtin_setvar_helper(peer, "BLINDTRANSFER", chan->name);
06887       }
06888       return 0;
06889    } else if (ast_canmatch_extension(NULL, transfercontext, refer_to, 1, NULL)) {
06890       return 1;
06891    }
06892 
06893    return -1;
06894 }

static int get_rpid_num char *  input,
char *  output,
int  maxlen
[static]
 

get_rpid_num: 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 7032 of file chan_sip.c.

References AST_PRES_PROHIB_USER_NUMBER_NOT_SCREENED.

Referenced by check_user_full().

07033 {
07034    char *start;
07035    char *end;
07036 
07037    start = strchr(input,':');
07038    if (!start) {
07039       output[0] = '\0';
07040       return 0;
07041    }
07042    start++;
07043 
07044    /* we found "number" */
07045    ast_copy_string(output,start,maxlen);
07046    output[maxlen-1] = '\0';
07047 
07048    end = strchr(output,'@');
07049    if (end)
07050       *end = '\0';
07051    else
07052       output[0] = '\0';
07053    if (strstr(input,"privacy=full") || strstr(input,"privacy=uri"))
07054       return AST_PRES_PROHIB_USER_NUMBER_NOT_SCREENED;
07055 
07056    return 0;
07057 }

static char* get_sdp struct sip_request req,
char *  name
[static]
 

get_sdp: get a specific line from the SDP

Definition at line 2867 of file chan_sip.c.

References get_body_by_line(), sip_request::line, and sip_request::sdp_start.

02868 {
02869    int x;
02870    int len = strlen(name);
02871    char *r;
02872 
02873    for (x = req->sdp_start; x < req->sdp_end; x++) {
02874       r = get_body_by_line(req->line[x], name, len);
02875       if (r[0] != '\0')
02876          return r;
02877    }
02878    return "";
02879 }

static char* get_sdp_iterate int *  iterator,
struct sip_request req,
char *  name
[static]
 

Definition at line 2886 of file chan_sip.c.

References get_body_by_line(), and sip_request::line.

02888 {
02889    int len = strlen(name);
02890    char *r;
02891 
02892    while (*iterator < req->sdp_end) {
02893       r = get_body_by_line(req->line[(*iterator)++], name, len);
02894       if (r[0] != '\0')
02895          return r;
02896    }
02897    return "";
02898 }

static struct sip_pvt* get_sip_pvt_byid_locked char *  callid  )  [static]
 

get_sip_pvt_byid_locked: Lock interface lock and find matching pvt lock ---

Definition at line 6726 of file chan_sip.c.

References ast_mutex_lock(), ast_mutex_trylock(), ast_mutex_unlock(), sip_pvt::callid, iflist, ast_channel::lock, sip_pvt::lock, sip_pvt::next, and sip_pvt::owner.

Referenced by get_refer_info().

06727 {
06728    struct sip_pvt *sip_pvt_ptr = NULL;
06729    
06730    /* Search interfaces and find the match */
06731    ast_mutex_lock(&iflock);
06732    sip_pvt_ptr = iflist;
06733    while(sip_pvt_ptr) {
06734       if (!strcmp(sip_pvt_ptr->callid, callid)) {
06735          /* Go ahead and lock it (and its owner) before returning */
06736          ast_mutex_lock(&sip_pvt_ptr->lock);
06737          if (sip_pvt_ptr->owner) {
06738             while(ast_mutex_trylock(&sip_pvt_ptr->owner->lock)) {
06739                ast_mutex_unlock(&sip_pvt_ptr->lock);
06740                usleep(1);
06741                ast_mutex_lock(&sip_pvt_ptr->lock);
06742                if (!sip_pvt_ptr->owner)
06743                   break;
06744             }
06745          }
06746          break;
06747       }
06748       sip_pvt_ptr = sip_pvt_ptr->next;
06749    }
06750    ast_mutex_unlock(&iflock);
06751    return sip_pvt_ptr;
06752 }

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

gettag: Get tag from packet

Definition at line 10344 of file chan_sip.c.

References get_header(), and strcasestr().

Referenced by find_call(), handle_request(), and handle_response().

10345 {
10346 
10347    char *thetag, *sep;
10348    
10349 
10350    if (!tagbuf)
10351       return NULL;
10352    tagbuf[0] = '\0';    /* reset the buffer */
10353    thetag = get_header(req, header);
10354    thetag = strcasestr(thetag, ";tag=");
10355    if (thetag) {
10356       thetag += 5;
10357       ast_copy_string(tagbuf, thetag, tagbufsize);
10358       sep = strchr(tagbuf, ';');
10359       if (sep)
10360          *sep = '\0';
10361    }
10362    return thetag;
10363 }

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

handle_common_options: Handle flag-type options common to users and peers ---

Definition at line 11791 of file chan_sip.c.

References ast_clear_flag, ast_false(), ast_log(), ast_set2_flag, ast_set_flag, ast_true(), global_allowguest, ast_variable::lineno, LOG_WARNING, ast_variable::name, ast_channel::next, SIP_CAN_REINVITE, SIP_DTMF, SIP_DTMF_AUTO, SIP_DTMF_INBAND, SIP_DTMF_INFO, SIP_DTMF_RFC2833, SIP_INSECURE_INVITE, SIP_INSECURE_PORT, SIP_NAT, SIP_NAT_ALWAYS, SIP_NAT_NEVER, SIP_NAT_RFC3581, SIP_OSPAUTH, SIP_OSPAUTH_EXCLUSIVE, SIP_OSPAUTH_GATEWAY, SIP_OSPAUTH_PROXY, 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(), build_user(), and reload_config().

11792 {
11793    int res = 0;
11794 
11795    if (!strcasecmp(v->name, "trustrpid")) {
11796       ast_set_flag(mask, SIP_TRUSTRPID);
11797       ast_set2_flag(flags, ast_true(v->value), SIP_TRUSTRPID);
11798       res = 1;
11799    } else if (!strcasecmp(v->name, "sendrpid")) {
11800       ast_set_flag(mask, SIP_SENDRPID);
11801       ast_set2_flag(flags, ast_true(v->value), SIP_SENDRPID);
11802       res = 1;
11803    } else if (!strcasecmp(v->name, "useclientcode")) {
11804       ast_set_flag(mask, SIP_USECLIENTCODE);
11805       ast_set2_flag(flags, ast_true(v->value), SIP_USECLIENTCODE);
11806       res = 1;
11807    } else if (!strcasecmp(v->name, "dtmfmode")) {
11808       ast_set_flag(mask, SIP_DTMF);
11809       ast_clear_flag(flags, SIP_DTMF);
11810       if (!strcasecmp(v->value, "inband"))
11811          ast_set_flag(flags, SIP_DTMF_INBAND);
11812       else if (!strcasecmp(v->value, "rfc2833"))
11813          ast_set_flag(flags, SIP_DTMF_RFC2833);
11814       else if (!strcasecmp(v->value, "info"))
11815          ast_set_flag(flags, SIP_DTMF_INFO);
11816       else if (!strcasecmp(v->value, "auto"))
11817          ast_set_flag(flags, SIP_DTMF_AUTO);
11818       else {
11819          ast_log(LOG_WARNING, "Unknown dtmf mode '%s' on line %d, using rfc2833\n", v->value, v->lineno);
11820          ast_set_flag(flags, SIP_DTMF_RFC2833);
11821       }
11822    } else if (!strcasecmp(v->name, "nat")) {
11823       ast_set_flag(mask, SIP_NAT);
11824       ast_clear_flag(flags, SIP_NAT);
11825       if (!strcasecmp(v->value, "never"))
11826          ast_set_flag(flags, SIP_NAT_NEVER);
11827       else if (!strcasecmp(v->value, "route"))
11828          ast_set_flag(flags, SIP_NAT_ROUTE);
11829       else if (ast_true(v->value))
11830          ast_set_flag(flags, SIP_NAT_ALWAYS);
11831       else
11832          ast_set_flag(flags, SIP_NAT_RFC3581);
11833    } else if (!strcasecmp(v->name, "canreinvite")) {
11834       ast_set_flag(mask, SIP_REINVITE);
11835       ast_clear_flag(flags, SIP_REINVITE);
11836       if (!strcasecmp(v->value, "update"))
11837          ast_set_flag(flags, SIP_REINVITE_UPDATE | SIP_CAN_REINVITE);
11838       else
11839          ast_set2_flag(flags, ast_true(v->value), SIP_CAN_REINVITE);
11840    } else if (!strcasecmp(v->name, "insecure")) {
11841       ast_set_flag(mask, SIP_INSECURE_PORT | SIP_INSECURE_INVITE);
11842       ast_clear_flag(flags, SIP_INSECURE_PORT | SIP_INSECURE_INVITE);
11843       if (!strcasecmp(v->value, "very"))
11844          ast_set_flag(flags, SIP_INSECURE_PORT | SIP_INSECURE_INVITE);
11845       else if (ast_true(v->value))
11846          ast_set_flag(flags, SIP_INSECURE_PORT);
11847       else if (!ast_false(v->value)) {
11848          char buf[64];
11849          char *word, *next;
11850 
11851          ast_copy_string(buf, v->value, sizeof(buf));
11852          next = buf;
11853          while ((word = strsep(&next, ","))) {
11854             if (!strcasecmp(word, "port"))
11855                ast_set_flag(flags, SIP_INSECURE_PORT);
11856             else if (!strcasecmp(word, "invite"))
11857                ast_set_flag(flags, SIP_INSECURE_INVITE);
11858             else
11859                ast_log(LOG_WARNING, "Unknown insecure mode '%s' on line %d\n", v->value, v->lineno);
11860          }
11861       }
11862    } else if (!strcasecmp(v->name, "progressinband")) {
11863       ast_set_flag(mask, SIP_PROG_INBAND);
11864       ast_clear_flag(flags, SIP_PROG_INBAND);
11865       if (ast_true(v->value))
11866          ast_set_flag(flags, SIP_PROG_INBAND_YES);
11867       else if (strcasecmp(v->value, "never"))
11868          ast_set_flag(flags, SIP_PROG_INBAND_NO);
11869    } else if (!strcasecmp(v->name, "allowguest")) {
11870 #ifdef OSP_SUPPORT
11871       if (!strcasecmp(v->value, "osp"))
11872          global_allowguest = 2;
11873       else 
11874 #endif
11875          if (ast_true(v->value)) 
11876             global_allowguest = 1;
11877          else
11878             global_allowguest = 0;
11879 #ifdef OSP_SUPPORT
11880    } else if (!strcasecmp(v->name, "ospauth")) {
11881       ast_set_flag(mask, SIP_OSPAUTH);
11882       ast_clear_flag(flags, SIP_OSPAUTH);
11883       if (!strcasecmp(v->value, "proxy"))
11884          ast_set_flag(flags, SIP_OSPAUTH_PROXY);
11885       else if (!strcasecmp(v->value, "gateway"))
11886          ast_set_flag(flags, SIP_OSPAUTH_GATEWAY);
11887       else if(!strcasecmp (v->value, "exclusive"))
11888          ast_set_flag(flags, SIP_OSPAUTH_EXCLUSIVE);
11889 #endif
11890    } else if (!strcasecmp(v->name, "promiscredir")) {
11891       ast_set_flag(mask, SIP_PROMISCREDIR);
11892       ast_set2_flag(flags, ast_true(v->value), SIP_PROMISCREDIR);
11893       res = 1;
11894    }
11895 
11896    return res;
11897 }

static int handle_request struct sip_pvt p,
struct sip_request req,
struct sockaddr_in *  sin,
int *  recount,
int *  nounlock
[static]
 

handle_request: Handle SIP requests (methods) ---

Definition at line 11056 of file chan_sip.c.

References __sip_ack(), ast_inet_ntoa(), ast_log(), ast_set_flag, ast_strlen_zero(), ast_test_flag, ast_verbose(), check_pendings(), debug, error(), extract_uri(), find_sdp(), FLAG_RESPONSE, get_header(), gettag(), handle_request_bye(), handle_request_cancel(), handle_request_info(), handle_request_invite(), handle_request_message(), handle_request_options(), handle_request_refer(), handle_request_register(), handle_request_subscribe(), handle_response(), sip_request::header, sip_request::headers, sip_pvt::icseq, sip_pvt::initreq, sip_pvt::lastinvite, sip_pvt::lastmsg, sip_request::len, LOG_DEBUG, LOG_ERROR, LOG_NOTICE, LOG_WARNING, sip_pvt::method, sip_request::method, sip_pvt::ocseq, option_debug, pedanticsipchecking, sip_pvt::pendinginvite, process_sdp(), sip_pvt::randdata, sip_request::rlPart1, sip_request::rlPart2, sip_pvt::sa, SIP_ACK, SIP_ALREADYGONE, SIP_BYE, SIP_CANCEL, sip_debug_test_pvt(), SIP_INFO, SIP_INVITE, SIP_MESSAGE, sip_methods, SIP_NEEDDESTROY, SIP_NOTIFY, SIP_OPTIONS, SIP_PKT_WITH_TOTAG, SIP_REFER, SIP_REGISTER, SIP_RESPONSE, SIP_SUBSCRIBE, sip_pvt::theirtag, transmit_response(), transmit_response_reliable(), transmit_response_with_allow(), and sip_pvt::useragent.

11057 {
11058    /* Called with p->lock held, as well as p->owner->lock if appropriate, keeping things
11059       relatively static */
11060    struct sip_request resp;
11061    char *cmd;
11062    char *cseq;
11063    char *useragent;
11064    int seqno;
11065    int len;
11066    int ignore=0;
11067    int respid;
11068    int res = 0;
11069    char iabuf[INET_ADDRSTRLEN];
11070    int debug = sip_debug_test_pvt(p);
11071    char *e;
11072    int error = 0;
11073 
11074    /* Clear out potential response */
11075    memset(&resp, 0, sizeof(resp));
11076 
11077    /* Get Method and Cseq */
11078    cseq = get_header(req, "Cseq");
11079    cmd = req->header[0];
11080 
11081    /* Must have Cseq */
11082    if (ast_strlen_zero(cmd) || ast_strlen_zero(cseq)) {
11083       ast_log(LOG_ERROR, "Missing Cseq. Dropping this SIP message, it's incomplete.\n");
11084       error = 1;
11085    }
11086    if (!error && sscanf(cseq, "%d%n", &seqno, &len) != 1) {
11087       ast_log(LOG_ERROR, "No seqno in '%s'. Dropping incomplete message.\n", cmd);
11088       error = 1;
11089    }
11090    if (error) {
11091       if (!p->initreq.header) /* New call */
11092          ast_set_flag(p, SIP_NEEDDESTROY);   /* Make sure we destroy this dialog */
11093       return -1;
11094    }
11095    /* Get the command XXX */
11096 
11097    cmd = req->rlPart1;
11098    e = req->rlPart2;
11099 
11100    /* Save useragent of the client */
11101    useragent = get_header(req, "User-Agent");
11102    if (!ast_strlen_zero(useragent))
11103       ast_copy_string(p->useragent, useragent, sizeof(p->useragent));
11104 
11105    /* Find out SIP method for incoming request */
11106    if (req->method == SIP_RESPONSE) {  /* Response to our request */
11107       /* Response to our request -- Do some sanity checks */   
11108       if (!p->initreq.headers) {
11109          ast_log(LOG_DEBUG, "That's odd...  Got a response on a call we dont know about. Cseq %d Cmd %s\n", seqno, cmd);
11110          ast_set_flag(p, SIP_NEEDDESTROY);   
11111          return 0;
11112       } else if (p->ocseq && (p->ocseq < seqno)) {
11113          ast_log(LOG_DEBUG, "Ignoring out of order response %d (expecting %d)\n", seqno, p->ocseq);
11114          return -1;
11115       } else if (p->ocseq && (p->ocseq != seqno)) {
11116          /* ignore means "don't do anything with it" but still have to 
11117             respond appropriately  */
11118          ignore=1;
11119       }
11120    
11121       e = ast_skip_blanks(e);
11122       if (sscanf(e, "%d %n", &respid, &len) != 1) {
11123          ast_log(LOG_WARNING, "Invalid response: '%s'\n", e);
11124       } else {
11125          /* More SIP ridiculousness, we have to ignore bogus contacts in 100 etc responses */
11126          if ((respid == 200) || ((respid >= 300) && (respid <= 399)))
11127             extract_uri(p, req);
11128          handle_response(p, respid, e + len, req, ignore, seqno);
11129       }
11130       return 0;
11131    }
11132 
11133    /* New SIP request coming in 
11134       (could be new request in existing SIP dialog as well...) 
11135     */         
11136    
11137    p->method = req->method;   /* Find out which SIP method they are using */
11138    if (option_debug > 2)
11139       ast_log(LOG_DEBUG, "**** Received %s (%d) - Command in SIP %s\n", sip_methods[p->method].text, sip_methods[p->method].id, cmd); 
11140 
11141    if (p->icseq && (p->icseq > seqno)) {
11142       if (option_debug)
11143          ast_log(LOG_DEBUG, "Ignoring too old SIP packet packet %d (expecting >= %d)\n", seqno, p->icseq);
11144       if (req->method != SIP_ACK)
11145          transmit_response(p, "503 Server error", req);  /* We must respond according to RFC 3261 sec 12.2 */
11146       return -1;
11147    } else if (p->icseq && (p->icseq == seqno) && req->method != SIP_ACK &&(p->method != SIP_CANCEL|| ast_test_flag(p, SIP_ALREADYGONE))) {
11148       /* ignore means "don't do anything with it" but still have to 
11149          respond appropriately.  We do this if we receive a repeat of
11150          the last sequence number  */
11151       ignore=2;
11152       if (option_debug > 2)
11153          ast_log(LOG_DEBUG, "Ignoring SIP message because of retransmit (%s Seqno %d, ours %d)\n", sip_methods[p->method].text, p->icseq, seqno);
11154    }
11155       
11156    if (seqno >= p->icseq)
11157       /* Next should follow monotonically (but not necessarily 
11158          incrementally -- thanks again to the genius authors of SIP --
11159          increasing */
11160       p->icseq = seqno;
11161 
11162    /* Find their tag if we haven't got it */
11163    if (ast_strlen_zero(p->theirtag)) {
11164       gettag(req, "From", p->theirtag, sizeof(p->theirtag));
11165    }
11166    snprintf(p->lastmsg, sizeof(p->lastmsg), "Rx: %s", cmd);
11167 
11168    if (pedanticsipchecking) {
11169       /* If this is a request packet without a from tag, it's not
11170          correct according to RFC 3261  */
11171       /* Check if this a new request in a new dialog with a totag already attached to it,
11172          RFC 3261 - section 12.2 - and we don't want to mess with recovery  */
11173       if (!p->initreq.headers && ast_test_flag(req, SIP_PKT_WITH_TOTAG)) {
11174          /* If this is a first request and it got a to-tag, it is not for us */
11175          if (!ignore && req->method == SIP_INVITE) {
11176             transmit_response_reliable(p, "481 Call/Transaction Does Not Exist", req, 1);
11177             /* Will cease to exist after ACK */
11178          } else if (req->method != SIP_ACK) {
11179             transmit_response(p, "481 Call/Transaction Does Not Exist", req);
11180             ast_set_flag(p, SIP_NEEDDESTROY);
11181          }
11182          return res;
11183       }
11184    }
11185 
11186    /* Handle various incoming SIP methods in requests */
11187    switch (p->method) {
11188    case SIP_OPTIONS:
11189       res = handle_request_options(p, req, debug);
11190       break;
11191    case SIP_INVITE:
11192       res = handle_request_invite(p, req, debug, ignore, seqno, sin, recount, e);
11193       break;
11194    case SIP_REFER:
11195       res = handle_request_refer(p, req, debug, ignore, seqno, nounlock);
11196       break;
11197    case SIP_CANCEL:
11198       res = handle_request_cancel(p, req, debug, ignore);
11199       break;
11200    case SIP_BYE:
11201       res = handle_request_bye(p, req, debug, ignore);
11202       break;
11203    case SIP_MESSAGE:
11204       res = handle_request_message(p, req, debug, ignore);
11205       break;
11206    case SIP_SUBSCRIBE:
11207       res = handle_request_subscribe(p, req, debug, ignore, sin, seqno, e);
11208       break;
11209    case SIP_REGISTER:
11210       res = handle_request_register(p, req, debug, ignore, sin, e);
11211       break;
11212    case SIP_INFO:
11213       if (!ignore) {
11214          if (debug)
11215             ast_verbose("Receiving INFO!\n");
11216          handle_request_info(p, req);
11217       } else { /* if ignoring, transmit response */
11218          transmit_response(p, "200 OK", req);
11219       }
11220       break;
11221    case SIP_NOTIFY:
11222       /* XXX we get NOTIFY's from some servers. WHY?? Maybe we should
11223          look into this someday XXX */
11224       transmit_response(p, "200 OK", req);
11225       if (!p->lastinvite) 
11226          ast_set_flag(p, SIP_NEEDDESTROY);   
11227       break;
11228    case SIP_ACK:
11229       /* Make sure we don't ignore this */
11230       if (seqno == p->pendinginvite) {
11231          p->pendinginvite = 0;
11232          __sip_ack(p, seqno, FLAG_RESPONSE, 0);
11233          if (find_sdp(req)) {
11234             if (process_sdp(p, req))
11235                return -1;
11236          } 
11237          check_pendings(p);
11238       }
11239       if (!p->lastinvite && ast_strlen_zero(p->randdata))
11240          ast_set_flag(p, SIP_NEEDDESTROY);   
11241       break;
11242    default:
11243       transmit_response_with_allow(p, "501 Method Not Implemented", req, 0);
11244       ast_log(LOG_NOTICE, "Unknown SIP command '%s' from '%s'\n", 
11245          cmd, ast_inet_ntoa(iabuf, sizeof(iabuf), p->sa.sin_addr));
11246       /* If this is some new method, and we don't have a call, destroy it now */
11247       if (!p->initreq.headers)
11248          ast_set_flag(p, SIP_NEEDDESTROY);   
11249       break;
11250    }
11251    return res;
11252 }

static int handle_request_bye struct sip_pvt p,
struct sip_request req,
int  debug,
int  ignore
[static]
 

handle_request_bye: Handle incoming BYE request ---

Definition at line 10752 of file chan_sip.c.

References ast_async_goto(), ast_bridged_channel(), ast_inet_ntoa(), ast_log(), ast_moh_stop(), ast_queue_hangup(), ast_rtp_stop(), ast_set_flag, ast_strlen_zero(), ast_test_flag, check_via(), copy_request(), default_context, get_also_info(), get_header(), sip_pvt::initreq, LOG_NOTICE, LOG_WARNING, sip_pvt::pendinginvite, SIP_ALREADYGONE, SIP_NEEDDESTROY, SIP_OUTGOING, transmit_response(), and transmit_response_reliable().

Referenced by handle_request().

10753 {
10754    struct ast_channel *c=NULL;
10755    int res;
10756    struct ast_channel *bridged_to;
10757    char iabuf[INET_ADDRSTRLEN];
10758    
10759    if (p->pendinginvite && !ast_test_flag(p, SIP_OUTGOING) && !ignore)
10760       transmit_response_reliable(p, "487 Request Terminated", &p->initreq, 1);
10761 
10762    copy_request(&p->initreq, req);
10763    check_via(p, req);
10764    ast_set_flag(p, SIP_ALREADYGONE);   
10765    if (p->rtp) {
10766       /* Immediately stop RTP */
10767       ast_rtp_stop(p->rtp);
10768    }
10769    if (p->vrtp) {
10770       /* Immediately stop VRTP */
10771       ast_rtp_stop(p->vrtp);
10772    }
10773    if (!ast_strlen_zero(get_header(req, "Also"))) {
10774       ast_log(LOG_NOTICE, "Client '%s' using deprecated BYE/Also transfer method.  Ask vendor to support REFER instead\n",
10775          ast_inet_ntoa(iabuf, sizeof(iabuf), p->recv.sin_addr));
10776       if (ast_strlen_zero(p->context))
10777          strcpy(p->context, default_context);
10778       res = get_also_info(p, req);
10779       if (!res) {
10780          c = p->owner;
10781          if (c) {
10782             bridged_to = ast_bridged_channel(c);
10783             if (bridged_to) {
10784                /* Don't actually hangup here... */
10785                ast_moh_stop(bridged_to);
10786                ast_async_goto(bridged_to, p->context, p->refer_to,1);
10787             } else
10788                ast_queue_hangup(p->owner);
10789          }
10790       } else {
10791          ast_log(LOG_WARNING, "Invalid transfer information from '%s'\n", ast_inet_ntoa(iabuf, sizeof(iabuf), p->recv.sin_addr));
10792          if (p->owner)
10793             ast_queue_hangup(p->owner);
10794       }
10795    } else if (p->owner)
10796       ast_queue_hangup(p->owner);
10797    else
10798       ast_set_flag(p, SIP_NEEDDESTROY);   
10799    transmit_response(p, "200 OK", req);
10800 
10801    return 1;
10802 }

static int handle_request_cancel struct sip_pvt p,
struct sip_request req,
int  debug,
int  ignore
[static]
 

handle_request_cancel: Handle incoming CANCEL request ---

Definition at line 10723 of file chan_sip.c.

References ast_queue_hangup(), ast_rtp_stop(), ast_set_flag, check_via(), sip_pvt::initreq, sip_request::len, sip_pvt::owner, sip_pvt::rtp, SIP_ALREADYGONE, SIP_NEEDDESTROY, transmit_response(), transmit_response_reliable(), and sip_pvt::vrtp.

Referenced by handle_request().

10724 {
10725       
10726    check_via(p, req);
10727    ast_set_flag(p, SIP_ALREADYGONE);   
10728    if (p->rtp) {
10729       /* Immediately stop RTP */
10730       ast_rtp_stop(p->rtp);
10731    }
10732    if (p->vrtp) {
10733       /* Immediately stop VRTP */
10734       ast_rtp_stop(p->vrtp);
10735    }
10736    if (p->owner)
10737       ast_queue_hangup(p->owner);
10738    else
10739       ast_set_flag(p, SIP_NEEDDESTROY);   
10740    if (p->initreq.len > 0) {
10741       if (!ignore)
10742          transmit_response_reliable(p, "487 Request Terminated", &p->initreq, 1);
10743       transmit_response(p, "200 OK", req);
10744       return 1;
10745    } else {
10746       transmit_response(p, "481 Call Leg Does Not Exist", req);
10747       return 0;
10748    }
10749 }

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

handle_request_info: Receive SIP INFO Message ---

Definition at line 8717 of file chan_sip.c.

References ast_bridged_channel(), ast_cdr_setuserfield(), AST_CONTROL_FLASH, AST_CONTROL_VIDUPDATE, AST_FRAME_CONTROL, AST_FRAME_DTMF, ast_log(), ast_queue_control(), ast_queue_frame(), ast_set_flag, ast_strlen_zero(), ast_test_flag, ast_verbose(), sip_pvt::callid, ast_channel::cdr, sip_history::event, get_body(), get_header(), LOG_WARNING, sip_pvt::owner, SIP_NEEDDESTROY, SIP_USECLIENTCODE, sipdebug, ast_frame::subclass, and transmit_response().

Referenced by handle_request().

08718 {
08719    char buf[1024];
08720    unsigned int event;
08721    char *c;
08722    
08723    /* Need to check the media/type */
08724    if (!strcasecmp(get_header(req, "Content-Type"), "application/dtmf-relay") ||
08725        !strcasecmp(get_header(req, "Content-Type"), "application/vnd.nortelnetworks.digits")) {
08726 
08727       /* Try getting the "signal=" part */
08728       if (ast_strlen_zero(c = get_body(req, "Signal")) && ast_strlen_zero(c = get_body(req, "d"))) {
08729          ast_log(LOG_WARNING, "Unable to retrieve DTMF signal from INFO message from %s\n", p->callid);
08730          transmit_response(p, "200 OK", req); /* Should return error */
08731          return;
08732       } else {
08733          ast_copy_string(buf, c, sizeof(buf));
08734       }
08735    
08736       if (!p->owner) {  /* not a PBX call */
08737          transmit_response(p, "481 Call leg/transaction does not exist", req);
08738          ast_set_flag(p, SIP_NEEDDESTROY);
08739          return;
08740       }
08741 
08742       if (ast_strlen_zero(buf)) {
08743          transmit_response(p, "200 OK", req);
08744          return;
08745       }
08746 
08747       if (buf[0] == '*')
08748          event = 10;
08749       else if (buf[0] == '#')
08750          event = 11;
08751       else if ((buf[0] >= 'A') && (buf[0] <= 'D'))
08752          event = 12 + buf[0] - 'A';
08753       else
08754          event = atoi(buf);
08755       if (event == 16) {
08756          /* send a FLASH event */
08757          struct ast_frame f = { AST_FRAME_CONTROL, AST_CONTROL_FLASH, };
08758          ast_queue_frame(p->owner, &f);
08759          if (sipdebug)
08760             ast_verbose("* DTMF-relay event received: FLASH\n");
08761       } else {
08762          /* send a DTMF event */
08763          struct ast_frame f = { AST_FRAME_DTMF, };
08764          if (event < 10) {
08765             f.subclass = '0' + event;
08766          } else if (event < 11) {
08767             f.subclass = '*';
08768          } else if (event < 12) {
08769             f.subclass = '#';
08770          } else if (event < 16) {
08771             f.subclass = 'A' + (event - 12);
08772          }
08773          ast_queue_frame(p->owner, &f);
08774          if (sipdebug)
08775             ast_verbose("* DTMF-relay event received: %c\n", f.subclass);
08776       }
08777       transmit_response(p, "200 OK", req);
08778       return;
08779    } else if (!strcasecmp(get_header(req, "Content-Type"), "application/media_control+xml")) {
08780       /* Eh, we'll just assume it's a fast picture update for now */
08781       if (p->owner)
08782          ast_queue_control(p->owner, AST_CONTROL_VIDUPDATE);
08783       transmit_response(p, "200 OK", req);
08784       return;
08785    } else if ((c = get_header(req, "X-ClientCode"))) {
08786       /* Client code (from SNOM phone) */
08787       if (ast_test_flag(p, SIP_USECLIENTCODE)) {
08788          if (p->owner && p->owner->cdr)
08789             ast_cdr_setuserfield(p->owner, c);
08790          if (p->owner && ast_bridged_channel(p->owner) && ast_bridged_channel(p->owner)->cdr)
08791             ast_cdr_setuserfield(ast_bridged_channel(p->owner), c);
08792          transmit_response(p, "200 OK", req);
08793       } else {
08794          transmit_response(p, "403 Unauthorized", req);
08795       }
08796       return;
08797    }
08798    /* Other type of INFO message, not really understood by Asterisk */
08799    /* if (get_msg_text(buf, sizeof(buf), req)) { */
08800 
08801    ast_log(LOG_WARNING, "Unable to parse INFO message from %s. Content %s\n", p->callid, buf);
08802    transmit_response(p, "415 Unsupported media type", req);
08803    return;
08804 }

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

handle_request_invite: Handle incoming INVITE request

Definition at line 10390 of file chan_sip.c.

References ast_channel::_state, ast_channel_setwhentohangup(), ast_clear_flag, AST_FRAME_NULL, ast_hangup(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), AST_PBX_CALL_LIMIT, AST_PBX_FAILED, ast_pbx_start(), AST_PBX_SUCCESS, ast_pickup_call(), ast_pickup_ext(), ast_queue_frame(), ast_set_flag, ast_setstate(), AST_STATE_DOWN, AST_STATE_RING, AST_STATE_RINGING, AST_STATE_UP, ast_strlen_zero(), ast_test_flag, ast_verbose(), build_contact(), build_route(), sip_pvt::callid, sip_pvt::capability, check_user(), check_via(), sip_pvt::context, copy_request(), DEC_CALL_LIMIT, default_context, sip_pvt::exten, extract_uri(), find_sdp(), get_destination(), get_header(), get_rdnis(), INC_CALL_LIMIT, sip_pvt::initreq, sip_pvt::jointcapability, sip_pvt::lastinvite, sip_pvt::lock, ast_channel::lock, LOG_DEBUG, LOG_NOTICE, LOG_WARNING, make_our_tag(), option_debug, sip_pvt::owner, parse_sip_options(), sip_pvt::pendinginvite, process_sdp(), sip_pvt::randdata, SIP_ALREADYGONE, sip_cancel_destroy(), SIP_INVITE, SIP_NEEDDESTROY, sip_new(), SIP_OUTGOING, sipdebug, sip_pvt::sipoptions, sip_pvt::tag, sip_pvt::theirtag, transmit_fake_auth_response(), transmit_response(), transmit_response_reliable(), transmit_response_with_sdp(), transmit_response_with_unsupported(), update_call_counter(), and sip_pvt::username.

Referenced by handle_request().

10391 {
10392    int res = 1;
10393    struct ast_channel *c=NULL;
10394    int gotdest;
10395    struct ast_frame af = { AST_FRAME_NULL, };
10396    char *supported;
10397    char *required;
10398    unsigned int required_profile = 0;
10399 
10400    /* Find out what they support */
10401    if (!p->sipoptions) {
10402       supported = get_header(req, "Supported");
10403       if (supported)
10404          parse_sip_options(p, supported);
10405    }
10406    required = get_header(req, "Require");
10407    if (!ast_strlen_zero(required)) {
10408       required_profile = parse_sip_options(NULL, required);
10409       if (required_profile) {    /* They require something */
10410          /* At this point we support no extensions, so fail */
10411          transmit_response_with_unsupported(p, "420 Bad extension", req, required);
10412          if (!p->lastinvite)
10413             ast_set_flag(p, SIP_NEEDDESTROY);   
10414          return -1;
10415          
10416       }
10417    }
10418 
10419    /* Check if this is a loop */
10420    /* This happens since we do not properly support SIP domain
10421       handling yet... -oej */
10422    if (ast_test_flag(p, SIP_OUTGOING) && p->owner && (p->owner->_state != AST_STATE_UP)) {
10423       /* This is a call to ourself.  Send ourselves an error code and stop
10424          processing immediately, as SIP really has no good mechanism for
10425          being able to call yourself */
10426       transmit_response(p, "482 Loop Detected", req);
10427       /* We do NOT destroy p here, so that our response will be accepted */
10428       return 0;
10429    }
10430    if (!ignore) {
10431       /* Use this as the basis */
10432       if (debug)
10433          ast_verbose("Using INVITE request as basis request - %s\n", p->callid);
10434       sip_cancel_destroy(p);
10435       /* This call is no longer outgoing if it ever was */
10436       ast_clear_flag(p, SIP_OUTGOING);
10437       /* This also counts as a pending invite */
10438       p->pendinginvite = seqno;
10439       copy_request(&p->initreq, req);
10440       check_via(p, req);
10441       if (p->owner) {
10442          /* Handle SDP here if we already have an owner */
10443          if (find_sdp(req)) {
10444             if (process_sdp(p, req)) {
10445                transmit_response(p, "488 Not acceptable here", req);
10446                if (!p->lastinvite)
10447                   ast_set_flag(p, SIP_NEEDDESTROY);   
10448                return -1;
10449             }
10450          } else {
10451             p->jointcapability = p->capability;
10452             ast_log(LOG_DEBUG, "Hm....  No sdp for the moment\n");
10453          }
10454       }
10455    } else if (debug)
10456       ast_verbose("Ignoring this INVITE request\n");
10457    if (!p->lastinvite && !ignore && !p->owner) {
10458       /* Handle authentication if this is our first invite */
10459       res = check_user(p, req, SIP_INVITE, e, 1, sin, ignore);
10460       /* if an authentication challenge was sent, we are done here */
10461       if (res > 0)
10462          return 0;
10463       if (res < 0) {
10464          if (res == -4) {
10465             ast_log(LOG_NOTICE, "Sending fake auth rejection for user %s\n", get_header(req, "From"));
10466             transmit_fake_auth_response(p, req, p->randdata, sizeof(p->randdata), 1);
10467          } else {
10468             ast_log(LOG_NOTICE, "Failed to authenticate user %s\n", get_header(req, "From"));
10469             if (ignore)
10470                transmit_response(p, "403 Forbidden", req);
10471             else
10472                transmit_response_reliable(p, "403 Forbidden", req, 1);
10473          }
10474          ast_set_flag(p, SIP_NEEDDESTROY);   
10475          p->theirtag[0] = '\0'; /* Forget their to-tag, we'll get a new one */
10476          return 0;
10477       }
10478       /* Process the SDP portion */
10479       if (find_sdp(req)) {
10480          if (process_sdp(p, req)) {
10481             transmit_response(p, "488 Not acceptable here", req);
10482             ast_set_flag(p, SIP_NEEDDESTROY);   
10483             return -1;
10484          }
10485       } else {
10486          p->jointcapability = p->capability;
10487          ast_log(LOG_DEBUG, "Hm....  No sdp for the moment\n");
10488       }
10489       /* Queue NULL frame to prod ast_rtp_bridge if appropriate */
10490       if (p->owner)
10491          ast_queue_frame(p->owner, &af);
10492       /* Initialize the context if it hasn't been already */
10493       if (ast_strlen_zero(p->context))
10494          strcpy(p->context, default_context);
10495       /* Check number of concurrent calls -vs- incoming limit HERE */
10496       ast_log(LOG_DEBUG, "Checking SIP call limits for device %s\n", p->username);
10497       res = update_call_counter(p, INC_CALL_LIMIT);
10498       if (res) {
10499          if (res < 0) {
10500             ast_log(LOG_NOTICE, "Failed to place call for user %s, too many calls\n", p->username);
10501             if (ignore)
10502                transmit_response(p, "480 Temporarily Unavailable (Call limit)", req);
10503             else
10504                transmit_response_reliable(p, "480 Temporarily Unavailable (Call limit) ", req, 1);
10505             ast_set_flag(p, SIP_NEEDDESTROY);   
10506          }
10507          return 0;
10508       }
10509       /* Get destination right away */
10510       gotdest = get_destination(p, NULL);
10511 
10512       get_rdnis(p, NULL);
10513       extract_uri(p, req);
10514       build_contact(p);
10515 
10516       if (gotdest) {
10517          if (gotdest < 0) {
10518             if (ignore)
10519                transmit_response(p, "404 Not Found", req);
10520             else
10521                transmit_response_reliable(p, "404 Not Found", req, 1);
10522             update_call_counter(p, DEC_CALL_LIMIT);
10523          } else {
10524             if (ignore)
10525                transmit_response(p, "484 Address Incomplete", req);
10526             else
10527                transmit_response_reliable(p, "484 Address Incomplete", req, 1);
10528             update_call_counter(p, DEC_CALL_LIMIT);
10529          }
10530          ast_set_flag(p, SIP_NEEDDESTROY);      
10531       } else {
10532          /* If no extension was specified, use the s one */
10533          if (ast_strlen_zero(p->exten))
10534             ast_copy_string(p->exten, "s", sizeof(p->exten));
10535          /* Initialize tag */ 
10536          make_our_tag(p->tag, sizeof(p->tag));
10537          /* First invitation */
10538          c = sip_new(p, AST_STATE_DOWN, ast_strlen_zero(p->username) ? NULL : p->username );
10539          *recount = 1;
10540          /* Save Record-Route for any later requests we make on this dialogue */
10541          build_route(p, req, 0);
10542          if (c) {
10543             /* Pre-lock the call */
10544             ast_mutex_lock(&c->lock);
10545          }
10546       }
10547       
10548    } else {
10549       if (option_debug > 1 && sipdebug)
10550          ast_log(LOG_DEBUG, "Got a SIP re-invite for call %s\n", p->callid);
10551       c = p->owner;
10552    }
10553    if (!ignore && p)
10554       p->lastinvite = seqno;
10555    if (c) {
10556 #ifdef OSP_SUPPORT
10557       ast_channel_setwhentohangup (c, p->osptimelimit);
10558 #endif
10559       switch(c->_state) {
10560       case AST_STATE_DOWN:
10561          transmit_response(p, "100 Trying", req);
10562          ast_setstate(c, AST_STATE_RING);
10563          if (strcmp(p->exten, ast_pickup_ext())) {
10564             enum ast_pbx_result res;
10565 
10566             res = ast_pbx_start(c);
10567 
10568             switch (res) {
10569             case AST_PBX_FAILED:
10570                ast_log(LOG_WARNING, "Failed to start PBX :(\n");
10571                if (ignore)
10572                   transmit_response(p, "503 Unavailable", req);
10573                else
10574                   transmit_response_reliable(p, "503 Unavailable", req, 1);
10575                break;
10576             case AST_PBX_CALL_LIMIT:
10577                ast_log(LOG_WARNING, "Failed to start PBX (call limit reached) \n");
10578                if (ignore)
10579                   transmit_response(p, "480 Temporarily Unavailable", req);
10580                else
10581                   transmit_response_reliable(p, "480 Temporarily Unavailable", req, 1);
10582                break;
10583             case AST_PBX_SUCCESS:
10584                /* nothing to do */
10585                break;
10586             }
10587 
10588             if (res) {
10589                ast_log(LOG_WARNING, "Failed to start PBX :(\n");
10590                /* Unlock locks so ast_hangup can do its magic */
10591                ast_mutex_unlock(&c->lock);
10592                ast_mutex_unlock(&p->lock);
10593                ast_hangup(c);
10594                ast_mutex_lock(&p->lock);
10595                c = NULL;
10596             }
10597          } else {
10598             ast_mutex_unlock(&c->lock);
10599             if (ast_pickup_call(c)) {
10600                ast_log(LOG_NOTICE, "Nothing to pick up\n");
10601                if (ignore)
10602                   transmit_response(p, "503 Unavailable", req);
10603                else
10604                   transmit_response_reliable(p, "503 Unavailable", req, 1);
10605                ast_set_flag(p, SIP_ALREADYGONE);   
10606                /* Unlock locks so ast_hangup can do its magic */
10607                ast_mutex_unlock(&p->lock);
10608                ast_hangup(c);
10609                ast_mutex_lock(&p->lock);
10610                c = NULL;
10611             } else {
10612                ast_mutex_unlock(&p->lock);
10613                ast_setstate(c, AST_STATE_DOWN);
10614                ast_hangup(c);
10615                ast_mutex_lock(&p->lock);
10616                c = NULL;
10617             }
10618          }
10619          break;
10620       case AST_STATE_RING:
10621          transmit_response(p, "100 Trying", req);
10622          break;
10623       case AST_STATE_RINGING:
10624          transmit_response(p, "180 Ringing", req);
10625          break;
10626       case AST_STATE_UP:
10627          transmit_response_with_sdp(p, "200 OK", req, 1);
10628          break;
10629       default:
10630          ast_log(LOG_WARNING, "Don't know how to handle INVITE in state %d\n", c->_state);
10631          transmit_response(p, "100 Trying", req);
10632       }
10633    } else {
10634       if (p && !ast_test_flag(p, SIP_NEEDDESTROY) && !ignore) {
10635          if (!p->jointcapability) {
10636             if (ignore)
10637                transmit_response(p, "488 Not Acceptable Here (codec error)", req);
10638             else
10639                transmit_response_reliable(p, "488 Not Acceptable Here (codec error)", req, 1);
10640             ast_set_flag(p, SIP_NEEDDESTROY);   
10641          } else {
10642             ast_log(LOG_NOTICE, "Unable to create/find channel\n");
10643             if (ignore)
10644                transmit_response(p, "503 Unavailable", req);
10645             else
10646                transmit_response_reliable(p, "503 Unavailable", req, 1);
10647             ast_set_flag(p, SIP_NEEDDESTROY);   
10648          }
10649       }
10650    }
10651    return res;
10652 }

static int handle_request_message struct sip_pvt p,
struct sip_request req,
int  debug,
int  ignore
[static]
 

handle_request_message: Handle incoming MESSAGE request ---

Definition at line 10805 of file chan_sip.c.

References ast_verbose(), receive_message(), and transmit_response().

Referenced by handle_request().

10806 {
10807    if (!ignore) {
10808       if (debug)
10809          ast_verbose("Receiving message!\n");
10810       receive_message(p, req);
10811    } else {
10812       transmit_response(p, "202 Accepted", req);
10813    }
10814    return 1;
10815 }

static int handle_request_options struct sip_pvt p,
struct sip_request req,
int  debug
[static]
 

handle_request_options: Handle incoming OPTIONS request

Definition at line 10366 of file chan_sip.c.

References ast_set_flag, ast_strlen_zero(), build_contact(), default_context, get_destination(), SIP_NEEDDESTROY, and transmit_response_with_allow().

Referenced by handle_request().

10367 {
10368    int res;
10369 
10370    res = get_destination(p, req);
10371    build_contact(p);
10372    /* XXX Should we authenticate OPTIONS? XXX */
10373    if (ast_strlen_zero(p->context))
10374       strcpy(p->context, default_context);
10375    if (res < 0)
10376       transmit_response_with_allow(p, "404 Not Found", req, 0);
10377    else if (res > 0)
10378       transmit_response_with_allow(p, "484 Address Incomplete", req, 0);
10379    else 
10380       transmit_response_with_allow(p, "200 OK", req, 0);
10381    /* Destroy if this OPTIONS was the opening request, but not if
10382       it's in the middle of a normal call flow. */
10383    if (!p->lastinvite)
10384       ast_set_flag(p, SIP_NEEDDESTROY);   
10385 
10386    return res;
10387 }

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

handle_request_refer: Handle incoming REFER request ---

Definition at line 10655 of file chan_sip.c.

References ast_async_goto(), ast_bridged_channel(), ast_log(), ast_moh_stop(), ast_mutex_unlock(), ast_parking_ext(), ast_queue_hangup(), ast_set_flag, ast_strlen_zero(), attempt_transfer(), sip_pvt::callid, sip_pvt::context, default_context, get_refer_info(), sip_pvt::lock, ast_channel::lock, LOG_DEBUG, ast_channel::name, option_debug, sip_pvt::owner, sip_pvt::refer_call, sip_pvt::refer_to, SIP_ALREADYGONE, SIP_BYE, SIP_GOTREFER, sip_park(), transmit_notify_with_sipfrag(), transmit_request_with_auth(), and transmit_response().

Referenced by handle_request().

10656 {
10657    struct ast_channel *c=NULL;
10658    int res;
10659    struct ast_channel *transfer_to;
10660 
10661    if (option_debug > 2)
10662       ast_log(LOG_DEBUG, "SIP call transfer received for call %s (REFER)!\n", p->callid);
10663    if (ast_strlen_zero(p->context))
10664       strcpy(p->context, default_context);
10665    res = get_refer_info(p, req);
10666    if (res < 0)
10667       transmit_response(p, "603 Declined", req);
10668    else if (res > 0)
10669       transmit_response(p, "484 Address Incomplete", req);
10670    else {
10671       int nobye = 0;
10672       if (!ignore) {
10673          if (p->refer_call) {
10674             ast_log(LOG_DEBUG,"202 Accepted (supervised)\n");
10675             attempt_transfer(p, p->refer_call);
10676             if (p->refer_call->owner)
10677                ast_mutex_unlock(&p->refer_call->owner->lock);
10678             ast_mutex_unlock(&p->refer_call->lock);
10679             p->refer_call = NULL;
10680             ast_set_flag(p, SIP_GOTREFER);   
10681          } else {
10682             ast_log(LOG_DEBUG,"202 Accepted (blind)\n");
10683             c = p->owner;
10684             if (c) {
10685                transfer_to = ast_bridged_channel(c);
10686                if (transfer_to) {
10687                   ast_log(LOG_DEBUG, "Got SIP blind transfer, applying to '%s'\n", transfer_to->name);
10688                   ast_moh_stop(transfer_to);
10689                   if (!strcmp(p->refer_to, ast_parking_ext())) {
10690                      /* Must release c's lock now, because it will not longer
10691                          be accessible after the transfer! */
10692                      *nounlock = 1;
10693                      ast_mutex_unlock(&c->lock);
10694                      sip_park(transfer_to, c, req);
10695                      nobye = 1;
10696                   } else {
10697                      /* Must release c's lock now, because it will not longer
10698                          be accessible after the transfer! */
10699                      *nounlock = 1;
10700                      ast_mutex_unlock(&c->lock);
10701                      ast_async_goto(transfer_to,p->context, p->refer_to,1);
10702                   }
10703                } else {
10704                   ast_log(LOG_DEBUG, "Got SIP blind transfer but nothing to transfer to.\n");
10705                   ast_queue_hangup(p->owner);
10706                }
10707             }
10708             ast_set_flag(p, SIP_GOTREFER);   
10709          }
10710          transmit_response(p, "202 Accepted", req);
10711          transmit_notify_with_sipfrag(p, seqno);
10712          /* Always increment on a BYE */
10713          if (!nobye) {
10714             transmit_request_with_auth(p, SIP_BYE, 0, 1, 1);
10715             ast_set_flag(p, SIP_ALREADYGONE);   
10716          }
10717       }
10718    }
10719    return res;
10720 }

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

handle_request_register: Handle incoming REGISTER request ---

Definition at line 11034 of file chan_sip.c.

References ast_inet_ntoa(), ast_log(), ast_verbose(), check_via(), copy_request(), get_header(), sip_pvt::initreq, LOG_NOTICE, register_verify(), and sip_scheddestroy().

Referenced by handle_request().

11035 {
11036    int res = 0;
11037    char iabuf[INET_ADDRSTRLEN];
11038 
11039    /* Use this as the basis */
11040    if (debug)
11041       ast_verbose("Using latest REGISTER request as basis request\n");
11042    copy_request(&p->initreq, req);
11043    check_via(p, req);
11044    if ((res = register_verify(p, sin, req, e, ignore)) < 0) 
11045       ast_log(LOG_NOTICE, "Registration from '%s' failed for '%s' - %s\n", get_header(req, "To"), ast_inet_ntoa(iabuf, sizeof(iabuf), sin->sin_addr), (res == -1) ? "Wrong password" : (res == -2 ? "Username/auth name mismatch" : "Not a local SIP domain"));
11046    if (res < 1) {
11047       /* Destroy the session, but keep us around for just a bit in case they don't
11048          get our 200 OK */
11049       sip_scheddestroy(p, 15*1000);
11050    }
11051    return res;
11052 }

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

handle_request_subscribe: Handle incoming SUBSCRIBE request ---

Definition at line 10817 of file chan_sip.c.

References append_history(), ast_clear_flag, AST_EXTENSION_REMOVED, ast_extension_state(), ast_extension_state2str(), ast_extension_state_add(), ast_inet_ntoa(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_set_flag, ast_strlen_zero(), ast_test_flag, ast_verbose(), sip_pvt::autokillid, build_contact(), sip_pvt::callid, cb_extensionstate(), check_user_full(), check_via(), sip_pvt::context, copy_request(), CPIM_PIDF_XML, default_context, DIALOG_INFO_XML, sip_pvt::expiry, sip_pvt::exten, get_destination(), get_header(), sip_request::headers, iflist, sip_pvt::initreq, sip_pvt::lastinvite, sip_pvt::lock, LOG_DEBUG, LOG_ERROR, LOG_NOTICE, mailbox, make_our_tag(), max_expiry, sip_request::method, sip_pvt::next, NONE, option_debug, PIDF_XML, sip_pvt::randdata, sip_pvt::sa, sip_cancel_destroy(), sip_methods, SIP_NEEDDESTROY, SIP_OUTGOING, sip_scheddestroy(), SIP_SUBSCRIBE, sipdebug, sip_pvt::stateid, sip_pvt::subscribecontext, sip_pvt::subscribed, sip_pvt::tag, cfsip_methods::text, transmit_fake_auth_response(), transmit_response(), transmit_response_reliable(), transmit_state_notify(), sip_pvt::useragent, sip_pvt::username, and XPIDF_XML.

Referenced by handle_request().

10818 {
10819    int gotdest;
10820    int res = 0;
10821    int firststate = AST_EXTENSION_REMOVED;
10822 
10823    if (p->initreq.headers) {  
10824       /* We already have a dialog */
10825       if (p->initreq.method != SIP_SUBSCRIBE) {
10826          /* This is a SUBSCRIBE within another SIP dialog, which we do not support */
10827          /* For transfers, this could happen, but since we haven't seen it happening, let us just refuse this */
10828          transmit_response(p, "403 Forbidden (within dialog)", req);
10829          /* Do not destroy session, since we will break the call if we do */
10830          ast_log(LOG_DEBUG, "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);
10831          return 0;
10832       } else {
10833          if (debug)
10834             ast_log(LOG_DEBUG, "Got a re-subscribe on existing subscription %s\n", p->callid);
10835       }
10836    }
10837    if (!ignore && !p->initreq.headers) {
10838       /* Use this as the basis */
10839       if (debug)
10840          ast_verbose("Using latest SUBSCRIBE request as basis request\n");
10841       /* This call is no longer outgoing if it ever was */
10842       ast_clear_flag(p, SIP_OUTGOING);
10843       copy_request(&p->initreq, req);
10844       check_via(p, req);
10845    } else if (debug && ignore)
10846       ast_verbose("Ignoring this SUBSCRIBE request\n");
10847 
10848    if (!p->lastinvite) {
10849       char mailboxbuf[256]="";
10850       int found = 0;
10851       char *mailbox = NULL;
10852       int mailboxsize = 0;
10853       char *eventparam;
10854 
10855       char *event = get_header(req, "Event");   /* Get Event package name */
10856       char *accept = get_header(req, "Accept");
10857 
10858       /* Find parameters to Event: header value and remove them for now */
10859       eventparam = strchr(event, ';');
10860       if (eventparam) {
10861          *eventparam = '\0';
10862          eventparam++;
10863       }
10864 
10865       if (!strcmp(event, "message-summary") && !strcmp(accept, "application/simple-message-summary")) {
10866          mailbox = mailboxbuf;
10867          mailboxsize = sizeof(mailboxbuf);
10868       }
10869       /* Handle authentication if this is our first subscribe */
10870       res = check_user_full(p, req, SIP_SUBSCRIBE, e, 0, sin, ignore, mailbox, mailboxsize);
10871       /* if an authentication challenge was sent, we are done here */
10872       if (res > 0)
10873          return 0;
10874       if (res < 0) {
10875          if (res == -4) {
10876             ast_log(LOG_NOTICE, "Sending fake auth rejection for user %s\n", get_header(req, "From"));
10877             transmit_fake_auth_response(p, req, p->randdata, sizeof(p->randdata), 1);
10878          } else {
10879             ast_log(LOG_NOTICE, "Failed to authenticate user %s for SUBSCRIBE\n", get_header(req, "From"));
10880             if (ignore)
10881                transmit_response(p, "403 Forbidden", req);
10882             else
10883                transmit_response_reliable(p, "403 Forbidden", req, 1);
10884          }
10885          ast_set_flag(p, SIP_NEEDDESTROY);   
10886          return 0;
10887       }
10888       gotdest = get_destination(p, NULL);
10889       /* Initialize the context if it hasn't been already;
10890          note this is done _after_ handling any domain lookups,
10891          because the context specified there is for calls, not
10892          subscriptions
10893       */
10894       if (!ast_strlen_zero(p->subscribecontext))
10895          ast_copy_string(p->context, p->subscribecontext, sizeof(p->context));
10896       else if (ast_strlen_zero(p->context))
10897          strcpy(p->context, default_context);
10898       /* Get destination right away */
10899       build_contact(p);
10900       if (gotdest) {
10901          if (gotdest < 0)
10902             transmit_response(p, "404 Not Found", req);
10903          else
10904             transmit_response(p, "484 Address Incomplete", req);  /* Overlap dialing on SUBSCRIBE?? */
10905          ast_set_flag(p, SIP_NEEDDESTROY);   
10906       } else {
10907 
10908          /* Initialize tag for new subscriptions */   
10909          if (ast_strlen_zero(p->tag))
10910             make_our_tag(p->tag, sizeof(p->tag));
10911 
10912          if (!strcmp(event, "presence") || !strcmp(event, "dialog")) { /* Presence, RFC 3842 */
10913 
10914             /* Header from Xten Eye-beam Accept: multipart/related, application/rlmi+xml, application/pidf+xml, application/xpidf+xml */
10915             if (strstr(accept, "application/pidf+xml")) {
10916                p->subscribed = PIDF_XML;         /* RFC 3863 format */
10917             } else if (strstr(accept, "application/dialog-info+xml")) {
10918                p->subscribed = DIALOG_INFO_XML;
10919                /* IETF draft: draft-ietf-sipping-dialog-package-05.txt */
10920             } else if (strstr(accept, "application/cpim-pidf+xml")) {
10921                p->subscribed = CPIM_PIDF_XML;    /* RFC 3863 format */
10922             } else if (strstr(accept, "application/xpidf+xml")) {
10923                p->subscribed = XPIDF_XML;        /* Early pre-RFC 3863 format with MSN additions (Microsoft Messenger) */
10924             } else if (strstr(p->useragent, "Polycom")) {
10925                p->subscribed = XPIDF_XML;        /*  Polycoms subscribe for "event: dialog" but don't include an "accept:" header */
10926             } else {
10927                /* Can't find a format for events that we know about */
10928                transmit_response(p, "489 Bad Event", req);
10929                ast_set_flag(p, SIP_NEEDDESTROY);   
10930                return 0;
10931             }
10932          } else if (!strcmp(event, "message-summary") && !strcmp(accept, "application/simple-message-summary")) {
10933             /* Looks like they actually want a mailbox status */
10934 
10935             /* At this point, we should check if they subscribe to a mailbox that
10936               has the same extension as the peer or the mailbox id. If we configure
10937               the context to be the same as a SIP domain, we could check mailbox
10938               context as well. To be able to securely accept subscribes on mailbox
10939               IDs, not extensions, we need to check the digest auth user to make
10940               sure that the user has access to the mailbox.
10941              
10942               Since we do not act on this subscribe anyway, we might as well 
10943               accept any authenticated peer with a mailbox definition in their 
10944               config section.
10945             
10946             */
10947             if (!ast_strlen_zero(mailbox)) {
10948                found++;
10949             }
10950 
10951             if (found){
10952                transmit_response(p, "200 OK", req);
10953                ast_set_flag(p, SIP_NEEDDESTROY);   
10954             } else {
10955                transmit_response(p, "404 Not found", req);
10956                ast_set_flag(p, SIP_NEEDDESTROY);   
10957             }
10958             return 0;
10959          } else { /* At this point, Asterisk does not understand the specified event */
10960             transmit_response(p, "489 Bad Event", req);
10961             if (option_debug > 1)
10962                ast_log(LOG_DEBUG, "Received SIP subscribe for unknown event package: %s\n", event);
10963             ast_set_flag(p, SIP_NEEDDESTROY);   
10964             return 0;
10965          }
10966          if (p->subscribed != NONE)
10967             p->stateid = ast_extension_state_add(p->context, p->exten, cb_extensionstate, p);
10968       }
10969    }
10970 
10971    if (!ignore && p)
10972       p->lastinvite = seqno;
10973    if (p && !ast_test_flag(p, SIP_NEEDDESTROY)) {
10974       p->expiry = atoi(get_header(req, "Expires"));
10975 
10976       /* The next 4 lines can be removed if the SNOM Expires bug is fixed */
10977       if (p->subscribed == DIALOG_INFO_XML) {  
10978          if (p->expiry > max_expiry)
10979             p->expiry = max_expiry;
10980       }
10981       if (sipdebug || option_debug > 1)
10982          ast_log(LOG_DEBUG, "Adding subscription for extension %s context %s for peer %s\n", p->exten, p->context, p->username);
10983       if (p->autokillid > -1)
10984          sip_cancel_destroy(p);  /* Remove subscription expiry for renewals */
10985       sip_scheddestroy(p, (p->expiry + 10) * 1000);   /* Set timer for destruction of call at expiration */
10986 
10987       if ((firststate = ast_extension_state(NULL, p->context, p->exten)) < 0) {
10988          char iabuf[INET_ADDRSTRLEN];
10989 
10990          ast_log(LOG_ERROR, "Got SUBSCRIBE for extension %s@%s from %s, but there is no hint for that extension\n", p->exten, p->context, ast_inet_ntoa(iabuf, sizeof(iabuf), p->sa.sin_addr));
10991          transmit_response(p, "404 Not found", req);
10992          ast_set_flag(p, SIP_NEEDDESTROY);   
10993          return 0;
10994       } else {
10995          struct sip_pvt *p_old;
10996 
10997          transmit_response(p, "200 OK", req);
10998          transmit_state_notify(p, firststate, 1, 1);  /* Send first notification */
10999          append_history(p, "Subscribestatus", ast_extension_state2str(firststate));
11000 
11001          /* remove any old subscription from this peer for the same exten/context,
11002             as the peer has obviously forgotten about it and it's wasteful to wait
11003             for it to expire and send NOTIFY messages to the peer only to have them
11004             ignored (or generate errors)
11005          */
11006          ast_mutex_lock(&iflock);
11007          for (p_old = iflist; p_old; p_old = p_old->next) {
11008             if (p_old == p)
11009                continue;
11010             if (p_old->initreq.method != SIP_SUBSCRIBE)
11011                continue;
11012             if (p_old->subscribed == NONE)
11013                continue;
11014             ast_mutex_lock(&p_old->lock);
11015             if (!strcmp(p_old->username, p->username)) {
11016                if (!strcmp(p_old->exten, p->exten) &&
11017                    !strcmp(p_old->context, p->context)) {
11018                   ast_set_flag(p_old, SIP_NEEDDESTROY);
11019                   ast_mutex_unlock(&p_old->lock);
11020                   break;
11021                }
11022             }
11023             ast_mutex_unlock(&p_old->lock);
11024          }
11025          ast_mutex_unlock(&iflock);
11026       }
11027       if (!p->expiry)
11028          ast_set_flag(p, SIP_NEEDDESTROY);
11029    }
11030    return 1;
11031 }

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

handle_response: Handle SIP response in dialogue ---

Definition at line 9896 of file chan_sip.c.

References __sip_ack(), __sip_semi_ack(), AST_CONTROL_BUSY, AST_CONTROL_CONGESTION, AST_CONTROL_PROGRESS, ast_inet_ntoa(), ast_log(), ast_queue_control(), ast_queue_hangup(), ast_rtp_stop(), ast_sched_del(), ast_set_flag, ast_strlen_zero(), ast_test_flag, ast_verbose(), sip_request::debug, DEC_CALL_LIMIT, do_proxy_auth(), find_sdp(), find_sip_method(), get_header(), gettag(), handle_response_invite(), handle_response_peerpoke(), handle_response_register(), hangup_sip2cause(), ast_channel::hangupcause, sip_pvt::initid, LOG_DEBUG, LOG_NOTICE, LOG_WARNING, MAX_AUTHTRIES, NONE, option_verbose, sip_pvt::owner, parse_moved_contact(), sip_pvt::peerpoke, process_sdp(), SIP_ACK, SIP_ALREADYGONE, SIP_BYE, SIP_CANCEL, sip_cancel_destroy(), SIP_INVITE, SIP_MESSAGE, sip_methods, SIP_NEEDDESTROY, SIP_NOTIFY, SIP_OUTGOING, SIP_REFER, SIP_REGISTER, text, sip_pvt::theirtag, transmit_request(), update_call_counter(), and VERBOSE_PREFIX_3.

09897 {
09898    char *msg, *c;
09899    struct ast_channel *owner;
09900    char iabuf[INET_ADDRSTRLEN];
09901    int sipmethod;
09902    int res = 1;
09903 
09904    c = get_header(req, "Cseq");
09905    msg = strchr(c, ' ');
09906    if (!msg)
09907       msg = "";
09908    else
09909       msg++;
09910    sipmethod = find_sip_method(msg);
09911 
09912    owner = p->owner;
09913    if (owner) 
09914       owner->hangupcause = hangup_sip2cause(resp);
09915 
09916    /* Acknowledge whatever it is destined for */
09917    if ((resp >= 100) && (resp <= 199))
09918       __sip_semi_ack(p, seqno, 0, sipmethod);
09919    else
09920       __sip_ack(p, seqno, 0, sipmethod);
09921 
09922    /* Get their tag if we haven't already */
09923    if (ast_strlen_zero(p->theirtag) || (resp >= 200)) {
09924       gettag(req, "To", p->theirtag, sizeof(p->theirtag));
09925    }
09926    if (p->peerpoke) {
09927       /* We don't really care what the response is, just that it replied back. 
09928          Well, as long as it's not a 100 response...  since we might
09929          need to hang around for something more "definitive" */
09930 
09931       res = handle_response_peerpoke(p, resp, rest, req, ignore, seqno, sipmethod);
09932    } else if (ast_test_flag(p, SIP_OUTGOING)) {
09933       /* Acknowledge sequence number */
09934       if (p->initid > -1) {
09935          /* Don't auto congest anymore since we've gotten something useful back */
09936          ast_sched_del(sched, p->initid);
09937          p->initid = -1;
09938       }
09939       switch(resp) {
09940       case 100:   /* 100 Trying */
09941          if (sipmethod == SIP_INVITE) 
09942             handle_response_invite(p, resp, rest, req, ignore, seqno);
09943          break;
09944       case 183:   /* 183 Session Progress */
09945          if (sipmethod == SIP_INVITE) 
09946             handle_response_invite(p, resp, rest, req, ignore, seqno);
09947          break;
09948       case 180:   /* 180 Ringing */
09949          if (sipmethod == SIP_INVITE) 
09950             handle_response_invite(p, resp, rest, req, ignore, seqno);
09951          break;
09952       case 200:   /* 200 OK */
09953          p->authtries = 0; /* Reset authentication counter */
09954          if (sipmethod == SIP_MESSAGE) {
09955             /* We successfully transmitted a message */
09956             ast_set_flag(p, SIP_NEEDDESTROY);   
09957          } else if (sipmethod == SIP_NOTIFY) {
09958             /* They got the notify, this is the end */
09959             if (p->owner) {
09960                ast_log(LOG_WARNING, "Notify answer on an owned channel?\n");
09961                ast_queue_hangup(p->owner);
09962             } else {
09963                if (p->subscribed == NONE) {
09964                   ast_set_flag(p, SIP_NEEDDESTROY); 
09965                }
09966             }
09967          } else if (sipmethod == SIP_INVITE) {
09968             handle_response_invite(p, resp, rest, req, ignore, seqno);
09969          } else if (sipmethod == SIP_REGISTER) {
09970             res = handle_response_register(p, resp, rest, req, ignore, seqno);
09971          } 
09972          break;
09973       case 401: /* Not www-authorized on SIP method */
09974          if (sipmethod == SIP_INVITE) {
09975             handle_response_invite(p, resp, rest, req, ignore, seqno);
09976          } else if (p->registry && sipmethod == SIP_REGISTER) {
09977             res = handle_response_register(p, resp, rest, req, ignore, seqno);
09978          } else {
09979             ast_log(LOG_WARNING, "Got authentication request (401) on unknown %s to '%s'\n", sip_methods[sipmethod].text, get_header(req, "To"));
09980             ast_set_flag(p, SIP_NEEDDESTROY);   
09981          }
09982          break;
09983       case 403: /* Forbidden - we failed authentication */
09984          if (sipmethod == SIP_INVITE) {
09985             handle_response_invite(p, resp, rest, req, ignore, seqno);
09986          } else if (p->registry && sipmethod == SIP_REGISTER) {
09987             res = handle_response_register(p, resp, rest, req, ignore, seqno);
09988          } else {
09989             ast_log(LOG_WARNING, "Forbidden - wrong password on authentication for %s\n", msg);
09990          }
09991          break;
09992       case 404: /* Not found */
09993          if (p->registry && sipmethod == SIP_REGISTER) {
09994             res = handle_response_register(p, resp, rest, req, ignore, seqno);
09995          } else if (sipmethod == SIP_INVITE) {
09996             handle_response_invite(p, resp, rest, req, ignore, seqno);
09997          } else if (owner)
09998             ast_queue_control(p->owner, AST_CONTROL_CONGESTION);
09999          break;
10000       case 407: /* Proxy auth required */
10001          if (sipmethod == SIP_INVITE) {
10002             handle_response_invite(p, resp, rest, req, ignore, seqno);
10003          } else if (sipmethod == SIP_BYE || sipmethod == SIP_REFER) {
10004             if (ast_strlen_zero(p->authname))
10005                ast_log(LOG_WARNING, "Asked to authenticate %s, to %s:%d but we have no matching peer!\n",
10006                      msg, ast_inet_ntoa(iabuf, sizeof(iabuf), p->recv.sin_addr), ntohs(p->recv.sin_port));
10007                ast_set_flag(p, SIP_NEEDDESTROY);   
10008             if ((p->authtries == MAX_AUTHTRIES) || do_proxy_auth(p, req, "Proxy-Authenticate", "Proxy-Authorization", sipmethod, 0)) {
10009                ast_log(LOG_NOTICE, "Failed to authenticate on %s to '%s'\n", msg, get_header(&p->initreq, "From"));
10010                ast_set_flag(p, SIP_NEEDDESTROY);   
10011             }
10012          } else if (p->registry && sipmethod == SIP_REGISTER) {
10013             res = handle_response_register(p, resp, rest, req, ignore, seqno);
10014          } else   /* We can't handle this, giving up in a bad way */
10015             ast_set_flag(p, SIP_NEEDDESTROY);   
10016 
10017          break;
10018       case 491: /* Pending */
10019          if (sipmethod == SIP_INVITE) {
10020             handle_response_invite(p, resp, rest, req, ignore, seqno);
10021          }
10022       case 501: /* Not Implemented */
10023          if (sipmethod == SIP_INVITE) {
10024             handle_response_invite(p, resp, rest, req, ignore, seqno);
10025          } else
10026             ast_log(LOG_WARNING, "Host '%s' does not implement '%s'\n", ast_inet_ntoa(iabuf, sizeof(iabuf), p->sa.sin_addr), msg);
10027          break;
10028       default:
10029          if ((resp >= 300) && (resp < 700)) {
10030             if ((option_verbose > 2) && (resp != 487))
10031                ast_verbose(VERBOSE_PREFIX_3 "Got SIP response %d \"%s\" back from %s\n", resp, rest, ast_inet_ntoa(iabuf, sizeof(iabuf), p->sa.sin_addr));
10032             ast_set_flag(p, SIP_ALREADYGONE);   
10033             if (p->rtp) {
10034                /* Immediately stop RTP */
10035                ast_rtp_stop(p->rtp);
10036             }
10037             if (p->vrtp) {
10038                /* Immediately stop VRTP */
10039                ast_rtp_stop(p->vrtp);
10040             }
10041             /* XXX Locking issues?? XXX */
10042             switch(resp) {
10043             case 300: /* Multiple Choices */
10044             case 301: /* Moved permenantly */
10045             case 302: /* Moved temporarily */
10046             case 305: /* Use Proxy */
10047                parse_moved_contact(p, req);
10048                /* Fall through */
10049             case 486: /* Busy here */
10050             case 600: /* Busy everywhere */
10051             case 603: /* Decline */
10052                if (p->owner)
10053                   ast_queue_control(p->owner, AST_CONTROL_BUSY);
10054                break;
10055             case 487:
10056                /* channel now destroyed - dec the inUse counter */
10057                update_call_counter(p, DEC_CALL_LIMIT);
10058                break;
10059             case 482: /* SIP is incapable of performing a hairpin call, which
10060                          is yet another failure of not having a layer 2 (again, YAY
10061                       IETF for thinking ahead).  So we treat this as a call
10062                       forward and hope we end up at the right place... */
10063                ast_log(LOG_DEBUG, "Hairpin detected, setting up call forward for what it's worth\n");
10064                if (p->owner)
10065                   snprintf(p->owner->call_forward, sizeof(p->owner->call_forward), "Local/%s@%s", p->username, p->context);
10066                /* Fall through */
10067             case 488: /* Not acceptable here - codec error */
10068             case 480: /* Temporarily Unavailable */
10069             case 404: /* Not Found */
10070             case 410: /* Gone */
10071             case 400: /* Bad Request */
10072             case 500: /* Server error */
10073             case 503: /* Service Unavailable */
10074                if (owner)
10075                   ast_queue_control(p->owner, AST_CONTROL_CONGESTION);
10076                break;
10077             default:
10078                /* Send hangup */ 
10079                if (owner)
10080                   ast_queue_hangup(p->owner);
10081                break;
10082             }
10083             /* ACK on invite */
10084             if (sipmethod == SIP_INVITE) 
10085                transmit_request(p, SIP_ACK, seqno, 0, 0);
10086             ast_set_flag(p, SIP_ALREADYGONE);   
10087             if (!p->owner)
10088                ast_set_flag(p, SIP_NEEDDESTROY);   
10089          } else if ((resp >= 100) && (resp < 200)) {
10090             if (sipmethod == SIP_INVITE) {
10091                if (!ignore)
10092                   sip_cancel_destroy(p);
10093                if (find_sdp(req))
10094                   process_sdp(p, req);
10095                if (p->owner) {
10096                   /* Queue a progress frame */
10097                   ast_queue_control(p->owner, AST_CONTROL_PROGRESS);
10098                }
10099             }
10100          } else
10101             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(iabuf, sizeof(iabuf), p->sa.sin_addr));
10102       }
10103    } else { 
10104       /* Responses to OUTGOING SIP requests on INCOMING calls 
10105          get handled here. As well as out-of-call message responses */
10106       if (req->debug)
10107          ast_verbose("SIP Response message for INCOMING dialog %s arrived\n", msg);
10108       if (resp == 200) {
10109          /* Tags in early session is replaced by the tag in 200 OK, which is 
10110          the final reply to our INVITE */
10111          gettag(req, "To", p->theirtag, sizeof(p->theirtag));
10112       }
10113 
10114       switch(resp) {
10115       case 200:
10116          if (sipmethod == SIP_INVITE) {
10117             handle_response_invite(p, resp, rest, req, ignore, seqno);
10118          } else if (sipmethod == SIP_CANCEL) {
10119             ast_log(LOG_DEBUG, "Got 200 OK on CANCEL\n");
10120          } else if (sipmethod == SIP_MESSAGE)
10121             /* We successfully transmitted a message */
10122             ast_set_flag(p, SIP_NEEDDESTROY);   
10123          break;
10124       case 401:   /* www-auth */
10125       case 407:
10126          if (sipmethod == SIP_BYE || sipmethod == SIP_REFER) {
10127             char *auth, *auth2;
10128 
10129             if (resp == 407) {
10130                auth = "Proxy-Authenticate";
10131                auth2 = "Proxy-Authorization";
10132             } else {
10133                auth = "WWW-Authenticate";
10134                auth2 = "Authorization";
10135             }
10136             if ((p->authtries == MAX_AUTHTRIES) || do_proxy_auth(p, req, auth, auth2, sipmethod, 0)) {
10137                ast_log(LOG_NOTICE, "Failed to authenticate on %s to '%s'\n", msg, get_header(&p->initreq, "From"));
10138                ast_set_flag(p, SIP_NEEDDESTROY);   
10139             }
10140          } else if (sipmethod == SIP_INVITE) {
10141             handle_response_invite(p, resp, rest, req, ignore, seqno);
10142          }
10143          break;
10144       case 481:   /* Call leg does not exist */
10145          if (sipmethod == SIP_INVITE) {
10146             /* Re-invite failed */
10147             handle_response_invite(p, resp, rest, req, ignore, seqno);
10148          }
10149          break;
10150       default: /* Errors without handlers */
10151          if ((resp >= 100) && (resp < 200)) {
10152             if (sipmethod == SIP_INVITE && !ignore)   /* re-invite */
10153                sip_cancel_destroy(p);
10154             
10155          }
10156          if ((resp >= 300) && (resp < 700)) {
10157             if ((option_verbose > 2) && (resp != 487))
10158                ast_verbose(VERBOSE_PREFIX_3 "Incoming call: Got SIP response %d \"%s\" back from %s\n", resp, rest, ast_inet_ntoa(iabuf, sizeof(iabuf), p->sa.sin_addr));
10159             switch(resp) {
10160             case 488: /* Not acceptable here - codec error */
10161             case 603: /* Decline */
10162             case 500: /* Server error */
10163             case 503: /* Service Unavailable */
10164 
10165                if (sipmethod == SIP_INVITE && !ignore) { /* re-invite failed */
10166                   sip_cancel_destroy(p);
10167                }
10168                break;
10169             }
10170          }
10171          break;
10172       }
10173    }
10174 }

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

handle_response_invite: Handle SIP response in dialogue ---

Definition at line 9569 of file chan_sip.c.

References ast_channel::_state, AST_CONTROL_ANSWER, AST_CONTROL_CONGESTION, AST_CONTROL_PROGRESS, AST_CONTROL_RINGING, AST_FRAME_NULL, ast_log(), ast_queue_control(), ast_queue_frame(), ast_set_flag, ast_setstate(), AST_STATE_RINGING, AST_STATE_UP, ast_test_flag, authenticate(), build_route(), sip_pvt::callid, check_pendings(), do_proxy_auth(), find_sdp(), get_header(), LOG_DEBUG, LOG_NOTICE, LOG_WARNING, MAX_AUTHTRIES, option_debug, sip_pvt::owner, parse_ok_contact(), process_sdp(), PROXY_AUTH, SIP_ACK, SIP_ALREADYGONE, SIP_CAN_BYE, sip_cancel_destroy(), SIP_INVITE, SIP_NEEDDESTROY, SIP_OUTGOING, SIP_PENDINGBYE, transmit_request(), and WWW_AUTH.

Referenced by handle_response().

09570 {
09571    int outgoing = ast_test_flag(p, SIP_OUTGOING);
09572    
09573    if (option_debug > 3) {
09574       int reinvite = (p->owner && p->owner->_state == AST_STATE_UP);
09575       if (reinvite)
09576          ast_log(LOG_DEBUG, "SIP response %d to RE-invite on %s call %s\n", resp, outgoing ? "outgoing" : "incoming", p->callid);
09577       else
09578          ast_log(LOG_DEBUG, "SIP response %d to standard invite\n", resp);
09579    }
09580 
09581    if (ast_test_flag(p, SIP_ALREADYGONE)) { /* This call is already gone */
09582       ast_log(LOG_DEBUG, "Got response on call that is already terminated: %s (ignoring)\n", p->callid);
09583       return;
09584    }
09585 
09586    switch (resp) {
09587    case 100:   /* Trying */
09588       if (!ignore)
09589          sip_cancel_destroy(p);
09590       /* must call check_pendings before setting CAN_BYE, so that
09591          if PENDINGBYE is set it will know to send CANCEL instead */
09592       check_pendings(p);
09593       ast_set_flag(p, SIP_CAN_BYE);
09594       break;
09595    case 180:   /* 180 Ringing */
09596       if (!ignore)
09597          sip_cancel_destroy(p);
09598       if (!ignore && p->owner) {
09599          ast_queue_control(p->owner, AST_CONTROL_RINGING);
09600          if (p->owner->_state != AST_STATE_UP)
09601             ast_setstate(p->owner, AST_STATE_RINGING);
09602       }
09603       if (find_sdp(req)) {
09604          process_sdp(p, req);
09605          if (!ignore && p->owner) {
09606             /* Queue a progress frame only if we have SDP in 180 */
09607             ast_queue_control(p->owner, AST_CONTROL_PROGRESS);
09608          }
09609       }
09610       /* must call check_pendings before setting CAN_BYE, so that
09611          if PENDINGBYE is set it will know to send CANCEL instead */
09612       check_pendings(p);
09613       ast_set_flag(p, SIP_CAN_BYE);
09614       break;
09615    case 183:   /* Session progress */
09616       if (!ignore)
09617          sip_cancel_destroy(p);
09618       /* Ignore 183 Session progress without SDP */
09619       if (find_sdp(req)) {
09620          process_sdp(p, req);
09621          if (!ignore && p->owner) {
09622             /* Queue a progress frame */
09623             ast_queue_control(p->owner, AST_CONTROL_PROGRESS);
09624          }
09625       }
09626       /* must call check_pendings before setting CAN_BYE, so that
09627          if PENDINGBYE is set it will know to send CANCEL instead */
09628       check_pendings(p);
09629       ast_set_flag(p, SIP_CAN_BYE);
09630       break;
09631    case 200:   /* 200 OK on invite - someone's answering our call */
09632       if (!ignore)
09633          sip_cancel_destroy(p);
09634       p->authtries = 0;
09635       if (find_sdp(req)) {
09636          process_sdp(p, req);
09637       }
09638 
09639       /* Parse contact header for continued conversation */
09640       /* When we get 200 OK, we know which device (and IP) to contact for this call */
09641       /* This is important when we have a SIP proxy between us and the phone */
09642       if (outgoing) {
09643          parse_ok_contact(p, req);
09644 
09645          /* Save Record-Route for any later requests we make on this dialogue */
09646          build_route(p, req, 1);
09647       }
09648       
09649       if (!ignore && p->owner) {
09650          if (p->owner->_state != AST_STATE_UP) {
09651 #ifdef OSP_SUPPORT   
09652             time(&p->ospstart);
09653 #endif
09654             ast_queue_control(p->owner, AST_CONTROL_ANSWER);
09655          } else { /* RE-invite */
09656             struct ast_frame af = { AST_FRAME_NULL, };
09657             ast_queue_frame(p->owner, &af);
09658          }
09659       } else {
09660           /* It's possible we're getting an ACK after we've tried to disconnect
09661               by sending CANCEL */
09662          /* THIS NEEDS TO BE CHECKED: OEJ */
09663          if (!ignore)
09664             ast_set_flag(p, SIP_PENDINGBYE); 
09665       }
09666       /* If I understand this right, the branch is different for a non-200 ACK only */
09667       transmit_request(p, SIP_ACK, seqno, 0, 1);
09668       check_pendings(p);
09669       break;
09670    case 407: /* Proxy authentication */
09671    case 401: /* Www auth */
09672       /* First we ACK */
09673       transmit_request(p, SIP_ACK, seqno, 0, 0);
09674       if (p->options)
09675          p->options->auth_type = (resp == 401 ? WWW_AUTH : PROXY_AUTH);
09676 
09677       /* Then we AUTH */
09678       p->theirtag[0]='\0'; /* forget their old tag, so we don't match tags when getting response */
09679       if (!ignore) {
09680          char *authenticate = (resp == 401 ? "WWW-Authenticate" : "Proxy-Authenticate");
09681          char *authorization = (resp == 401 ? "Authorization" : "Proxy-Authorization");
09682          if ((p->authtries == MAX_AUTHTRIES) || do_proxy_auth(p, req, authenticate, authorization, SIP_INVITE, 1)) {
09683             ast_log(LOG_NOTICE, "Failed to authenticate on INVITE to '%s'\n", get_header(&p->initreq, "From"));
09684             ast_set_flag(p, SIP_NEEDDESTROY);   
09685             ast_set_flag(p, SIP_ALREADYGONE);   
09686             if (p->owner)
09687                ast_queue_control(p->owner, AST_CONTROL_CONGESTION);
09688          }
09689       }
09690       break;
09691    case 403: /* Forbidden */
09692       /* First we ACK */
09693       transmit_request(p, SIP_ACK, seqno, 0, 0);
09694       ast_log(LOG_WARNING, "Forbidden - wrong password on authentication for INVITE to '%s'\n", get_header(&p->initreq, "From"));
09695       if (!ignore && p->owner)
09696          ast_queue_control(p->owner, AST_CONTROL_CONGESTION);
09697       ast_set_flag(p, SIP_NEEDDESTROY);   
09698       ast_set_flag(p, SIP_ALREADYGONE);   
09699       break;
09700    case 404: /* Not found */
09701       transmit_request(p, SIP_ACK, seqno, 0, 0);
09702       if (p->owner && !ignore)
09703          ast_queue_control(p->owner, AST_CONTROL_CONGESTION);
09704       ast_set_flag(p, SIP_ALREADYGONE);   
09705       break;
09706    case 481: /* Call leg does not exist */
09707       /* Could be REFER or INVITE */
09708       ast_log(LOG_WARNING, "Re-invite to non-existing call leg on other UA. SIP dialog '%s'. Giving up.\n", p->callid);
09709       transmit_request(p, SIP_ACK, seqno, 0, 0);
09710       break;
09711    case 491: /* Pending */
09712       /* we have to wait a while, then retransmit */
09713       /* Transmission is rescheduled, so everything should be taken care of.
09714          We should support the retry-after at some point */
09715       break;
09716    case 501: /* Not implemented */
09717       if (p->owner)
09718          ast_queue_control(p->owner, AST_CONTROL_CONGESTION);
09719       break;
09720    }
09721 }

static int handle_response_peerpoke struct sip_pvt p,
int  resp,
char *  rest,
struct sip_request req,
int  ignore,
int  seqno,
int  sipmethod
[static]
 

handle_response_peerpoke: Handle qualification responses (OPTIONS)

Definition at line 9840 of file chan_sip.c.

References ast_device_state_changed(), ast_log(), ast_sched_add(), ast_sched_del(), ast_set_flag, sip_peer::call, DEFAULT_FREQ_NOTOK, DEFAULT_FREQ_OK, EVENT_FLAG_SYSTEM, sip_peer::lastms, LOG_NOTICE, manager_event(), sip_peer::maxms, sip_pvt::peerpoke, sip_peer::pokeexpire, sip_peer::ps, SIP_ACK, SIP_INVITE, SIP_NEEDDESTROY, sip_poke_peer_s(), and transmit_request().

Referenced by handle_response().

09841 {
09842    struct sip_peer *peer;
09843    int pingtime;
09844    struct timeval tv;
09845 
09846    if (resp != 100) {
09847       int statechanged = 0;
09848       int newstate = 0;
09849       peer = p->peerpoke;
09850       gettimeofday(&tv, NULL);
09851       pingtime = ast_tvdiff_ms(tv, peer->ps);
09852       if (pingtime < 1)
09853          pingtime = 1;
09854       if ((peer->lastms < 0)  || (peer->lastms > peer->maxms)) {
09855          if (pingtime <= peer->maxms) {
09856             ast_log(LOG_NOTICE, "Peer '%s' is now REACHABLE! (%dms / %dms)\n", peer->name, pingtime, peer->maxms);
09857             statechanged = 1;
09858             newstate = 1;
09859          }
09860       } else if ((peer->lastms > 0) && (peer->lastms <= peer->maxms)) {
09861          if (pingtime > peer->maxms) {
09862             ast_log(LOG_NOTICE, "Peer '%s' is now TOO LAGGED! (%dms / %dms)\n", peer->name, pingtime, peer->maxms);
09863             statechanged = 1;
09864             newstate = 2;
09865          }
09866       }
09867       if (!peer->lastms)
09868          statechanged = 1;
09869       peer->lastms = pingtime;
09870       peer->call = NULL;
09871       if (statechanged) {
09872          ast_device_state_changed("SIP/%s", peer->name);
09873          if (newstate == 2) {
09874             manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: SIP/%s\r\nPeerStatus: Lagged\r\nTime: %d\r\n", peer->name, pingtime);
09875          } else {
09876             manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: SIP/%s\r\nPeerStatus: Reachable\r\nTime: %d\r\n", peer->name, pingtime);
09877          }
09878       }
09879 
09880       if (peer->pokeexpire > -1)
09881          ast_sched_del(sched, peer->pokeexpire);
09882       if (sipmethod == SIP_INVITE)  /* Does this really happen? */
09883          transmit_request(p, SIP_ACK, seqno, 0, 0);
09884       ast_set_flag(p, SIP_NEEDDESTROY);   
09885 
09886       /* Try again eventually */
09887       if ((peer->lastms < 0)  || (peer->lastms > peer->maxms))
09888          peer->pokeexpire = ast_sched_add(sched, DEFAULT_FREQ_NOTOK, sip_poke_peer_s, peer);
09889       else
09890          peer->pokeexpire = ast_sched_add(sched, DEFAULT_FREQ_OK, sip_poke_peer_s, peer);
09891    }
09892    return 1;
09893 }

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

handle_response_register: Handle responses on REGISTER to services ---

Definition at line 9724 of file chan_sip.c.

References __get_header(), ast_log(), ast_sched_add(), ast_sched_del(), ast_set_flag, ast_strlen_zero(), ASTOBJ_UNREF, sip_pvt::authtries, sip_registry::call, sip_registry::contact, default_expiry, do_register_auth(), EVENT_FLAG_SYSTEM, sip_registry::expire, EXPIRY_GUARD_LIMIT, EXPIRY_GUARD_MIN, EXPIRY_GUARD_PCT, EXPIRY_GUARD_SECS, get_header(), global_regattempts_max, sip_registry::hostname, LOG_DEBUG, LOG_NOTICE, LOG_WARNING, manager_event(), MAX, MAX_AUTHTRIES, sip_registry::refresh, REG_STATE_REGISTERED, sip_registry::regattempts, sip_pvt::registry, sip_registry::regstate, regstate2str(), SIP_NEEDDESTROY, sip_registry_destroy(), sip_reregister(), sip_scheddestroy(), sipdebug, strcasestr(), sip_registry::timeout, and sip_registry::username.

Referenced by handle_response().

09725 {
09726    int expires, expires_ms;
09727    struct sip_registry *r;
09728    r=p->registry;
09729 
09730    switch (resp) {
09731    case 401:   /* Unauthorized */
09732       if ((p->authtries == MAX_AUTHTRIES) || do_register_auth(p, req, "WWW-Authenticate", "Authorization")) {
09733          ast_log(LOG_NOTICE, "Failed to authenticate on REGISTER to '%s@%s' (Tries %d)\n", p->registry->username, p->registry->hostname, p->authtries);
09734          ast_set_flag(p, SIP_NEEDDESTROY);   
09735          }
09736       break;
09737    case 403:   /* Forbidden */
09738       ast_log(LOG_WARNING, "Forbidden - wrong password on authentication for REGISTER for '%s' to '%s'\n", p->registry->username, p->registry->hostname);
09739       if (global_regattempts_max)
09740          p->registry->regattempts = global_regattempts_max+1;
09741       ast_sched_del(sched, r->timeout);
09742       ast_set_flag(p, SIP_NEEDDESTROY);   
09743       break;
09744    case 404:   /* Not found */
09745       ast_log(LOG_WARNING, "Got 404 Not found on SIP register to service %s@%s, giving up\n", p->registry->username,p->registry->hostname);
09746       if (global_regattempts_max)
09747          p->registry->regattempts = global_regattempts_max+1;
09748       ast_set_flag(p, SIP_NEEDDESTROY);   
09749       r->call = NULL;
09750       ast_sched_del(sched, r->timeout);
09751       break;
09752    case 407:   /* Proxy auth */
09753       if ((p->authtries == MAX_AUTHTRIES) || do_register_auth(p, req, "Proxy-Authenticate", "Proxy-Authorization")) {
09754          ast_log(LOG_NOTICE, "Failed to authenticate on REGISTER to '%s' (tries '%d')\n", get_header(&p->initreq, "From"), p->authtries);
09755          ast_set_flag(p, SIP_NEEDDESTROY);   
09756       }
09757       break;
09758    case 479:   /* SER: Not able to process the URI - address is wrong in register*/
09759       ast_log(LOG_WARNING, "Got error 479 on register to %s@%s, giving up (check config)\n", p->registry->username,p->registry->hostname);
09760       if (global_regattempts_max)
09761          p->registry->regattempts = global_regattempts_max+1;
09762       ast_set_flag(p, SIP_NEEDDESTROY);   
09763       r->call = NULL;
09764       ast_sched_del(sched, r->timeout);
09765       break;
09766    case 200:   /* 200 OK */
09767       if (!r) {
09768          ast_log(LOG_WARNING, "Got 200 OK on REGISTER that isn't a register\n");
09769          ast_set_flag(p, SIP_NEEDDESTROY);   
09770          return 0;
09771       }
09772 
09773       r->regstate=REG_STATE_REGISTERED;
09774       manager_event(EVENT_FLAG_SYSTEM, "Registry", "Channel: SIP\r\nDomain: %s\r\nStatus: %s\r\n", r->hostname, regstate2str(r->regstate));
09775       r->regattempts = 0;
09776       ast_log(LOG_DEBUG, "Registration successful\n");
09777       if (r->timeout > -1) {
09778          ast_log(LOG_DEBUG, "Cancelling timeout %d\n", r->timeout);
09779          ast_sched_del(sched, r->timeout);
09780       }
09781       r->timeout=-1;
09782       r->call = NULL;
09783       p->registry = NULL;
09784       /* Let this one hang around until we have all the responses */
09785       sip_scheddestroy(p, 32000);
09786       /* ast_set_flag(p, SIP_NEEDDESTROY);   */
09787 
09788       /* set us up for re-registering */
09789       /* figure out how long we got registered for */
09790       if (r->expire > -1)
09791          ast_sched_del(sched, r->expire);
09792       /* according to section 6.13 of RFC, contact headers override
09793          expires headers, so check those first */
09794       expires = 0;
09795       if (!ast_strlen_zero(get_header(req, "Contact"))) {
09796          char *contact = NULL;
09797          char *tmptmp = NULL;
09798          int start = 0;
09799          for(;;) {
09800             contact = __get_header(req, "Contact", &start);
09801             /* this loop ensures we get a contact header about our register request */
09802             if(!ast_strlen_zero(contact)) {
09803                if( (tmptmp=strstr(contact, p->our_contact))) {
09804                   contact=tmptmp;
09805                   break;
09806                }
09807             } else
09808                break;
09809          }
09810          tmptmp = strcasestr(contact, "expires=");
09811          if (tmptmp) {
09812             if (sscanf(tmptmp + 8, "%d;", &expires) != 1)
09813                expires = 0;
09814          }
09815 
09816       }
09817       if (!expires) 
09818          expires=atoi(get_header(req, "expires"));
09819       if (!expires)
09820          expires=default_expiry;
09821 
09822       expires_ms = expires * 1000;
09823       if (expires <= EXPIRY_GUARD_LIMIT)
09824          expires_ms -= MAX((expires_ms * EXPIRY_GUARD_PCT),EXPIRY_GUARD_MIN);
09825       else
09826          expires_ms -= EXPIRY_GUARD_SECS * 1000;
09827       if (sipdebug)
09828          ast_log(LOG_NOTICE, "Outbound Registration: Expiry for %s is %d sec (Scheduling reregistration in %d s)\n", r->hostname, expires, expires_ms/1000); 
09829 
09830       r->refresh= (int) expires_ms / 1000;
09831 
09832       /* Schedule re-registration before we expire */
09833       r->expire=ast_sched_add(sched, expires_ms, sip_reregister, r); 
09834       ASTOBJ_UNREF(r, sip_registry_destroy);
09835    }
09836    return 1;
09837 }

static char* hangup_cause2sip int  cause  )  [static]
 

hangup_cause2sip: 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 2354 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_USER_BUSY, ast_log(), and LOG_DEBUG.

Referenced by sip_hangup().

02355 {
02356    switch(cause)
02357    {
02358       case AST_CAUSE_UNALLOCATED:      /* 1 */
02359       case AST_CAUSE_NO_ROUTE_DESTINATION:   /* 3 IAX2: Can't find extension in context */
02360       case AST_CAUSE_NO_ROUTE_TRANSIT_NET:   /* 2 */
02361          return "404 Not Found";
02362                 case AST_CAUSE_CONGESTION:      /* 34 */
02363                 case AST_CAUSE_SWITCH_CONGESTION:  /* 42 */
02364                         return "503 Service Unavailable";
02365       case AST_CAUSE_NO_USER_RESPONSE: /* 18 */
02366          return "408 Request Timeout";
02367       case AST_CAUSE_NO_ANSWER:     /* 19 */
02368          return "480 Temporarily unavailable";
02369       case AST_CAUSE_CALL_REJECTED:    /* 21 */
02370          return "403 Forbidden";
02371       case AST_CAUSE_NUMBER_CHANGED:      /* 22 */
02372          return "410 Gone";
02373       case AST_CAUSE_NORMAL_UNSPECIFIED:  /* 31 */
02374          return "480 Temporarily unavailable";
02375       case AST_CAUSE_INVALID_NUMBER_FORMAT:
02376          return "484 Address incomplete";
02377       case AST_CAUSE_USER_BUSY:
02378          return "486 Busy here";
02379       case AST_CAUSE_FAILURE:
02380                   return "500 Server internal failure";
02381       case AST_CAUSE_FACILITY_REJECTED:   /* 29 */
02382          return "501 Not Implemented";
02383       case AST_CAUSE_CHAN_NOT_IMPLEMENTED:
02384          return "503 Service Unavailable";
02385       /* Used in chan_iax2 */
02386       case AST_CAUSE_DESTINATION_OUT_OF_ORDER:
02387          return "502 Bad Gateway";
02388       case AST_CAUSE_BEARERCAPABILITY_NOTAVAIL: /* Can't find codec to connect to host */
02389          return "488 Not Acceptable Here";
02390          
02391       case AST_CAUSE_NOTDEFINED:
02392       default:
02393          ast_log(LOG_DEBUG, "AST hangup cause %d (no match found in SIP)\n", cause);
02394          return NULL;
02395    }
02396 
02397    /* Never reached */
02398    return 0;
02399 }

static int hangup_sip2cause int  cause  )  [static]
 

hangup_sip2cause: Convert SIP hangup causes to Asterisk hangup causes ---

Definition at line 2286 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_NO_ANSWER, AST_CAUSE_NO_USER_RESPONSE, AST_CAUSE_NORMAL, and AST_CAUSE_UNALLOCATED.

Referenced by handle_response().

02287 {
02288 /* Possible values taken from causes.h */
02289 
02290    switch(cause) {
02291       case 603:   /* Declined */
02292       case 403:   /* Not found */
02293          return AST_CAUSE_CALL_REJECTED;
02294       case 404:   /* Not found */
02295          return AST_CAUSE_UNALLOCATED;
02296       case 408:   /* No reaction */
02297          return AST_CAUSE_NO_USER_RESPONSE;
02298       case 480:   /* No answer */
02299          return AST_CAUSE_FAILURE;
02300       case 483:   /* Too many hops */
02301          return AST_CAUSE_NO_ANSWER;
02302       case 486:   /* Busy everywhere */
02303          return AST_CAUSE_BUSY;
02304       case 488:   /* No codecs approved */
02305          return AST_CAUSE_BEARERCAPABILITY_NOTAVAIL;
02306       case 500:   /* Server internal failure */
02307          return AST_CAUSE_FAILURE;
02308       case 501:   /* Call rejected */
02309          return AST_CAUSE_FACILITY_REJECTED;
02310       case 502:   
02311          return AST_CAUSE_DESTINATION_OUT_OF_ORDER;
02312       case 503:   /* Service unavailable */
02313          return AST_CAUSE_CONGESTION;
02314       default:
02315          return AST_CAUSE_NORMAL;
02316    }
02317    /* Never reached */
02318    return 0;
02319 }

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

init_req: Initialize SIP request ---

Definition at line 4042 of file chan_sip.c.

References ast_log(), sip_request::data, sip_request::header, sip_request::headers, sip_request::len, LOG_WARNING, sip_request::method, sip_methods, and cfsip_methods::text.

04043 {
04044    /* Initialize a response */
04045    if (req->headers || req->len) {
04046       ast_log(LOG_WARNING, "Request already initialized?!?\n");
04047       return -1;
04048    }
04049    req->header[req->headers] = req->data + req->len;
04050    snprintf(req->header[req->headers], sizeof(req->data) - req->len, "%s %s SIP/2.0\r\n", sip_methods[sipmethod].text, recip);
04051    req->len += strlen(req->header[req->headers]);
04052    req->headers++;
04053    req->method = sipmethod;
04054    return 0;
04055 }

static int init_resp struct sip_request req,
char *  resp,
struct sip_request orig
[static]
 

init_resp: Initialize SIP response, based on SIP request ---

Definition at line 4026 of file chan_sip.c.

References ast_log(), sip_request::data, sip_request::header, sip_request::headers, sip_request::len, LOG_WARNING, sip_request::method, and SIP_RESPONSE.

04027 {
04028    /* Initialize a response */
04029    if (req->headers || req->len) {
04030       ast_log(LOG_WARNING, "Request already initialized?!?\n");
04031       return -1;
04032    }
04033    req->method = SIP_RESPONSE;
04034    req->header[req->headers] = req->data + req->len;
04035    snprintf(req->header[req->headers], sizeof(req->data) - req->len, "SIP/2.0 %s\r\n", resp);
04036    req->len += strlen(req->header[req->headers]);
04037    req->headers++;
04038    return 0;
04039 }

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

initreqprep: Initiate new SIP request to peer/user ---

Definition at line 4800 of file chan_sip.c.

References add_header(), ast_build_string(), AST_DIGIT_ANYNUM, ast_inet_ntoa(), AST_PRES_ALLOWED, AST_PRES_RESTRICTION, 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_callerid, DEFAULT_MAX_FORWARDS, default_useragent, sip_pvt::exten, sip_pvt::fromdomain, sip_pvt::fromname, sip_pvt::fromuser, sip_pvt::fullcontact, init_req(), sip_pvt::lastmsg, n, sip_pvt::ocseq, sip_pvt::options, sip_pvt::our_contact, sip_pvt::ourip, ourport, sip_pvt::owner, pedanticsipchecking, sip_pvt::rpid, sip_pvt::sa, SIP_INVITE, sip_methods, SIP_NOTIFY, SIP_SENDRPID, SIP_USEREQPHONE, sip_pvt::tag, cfsip_methods::text, sip_pvt::theirtag, sip_pvt::tohost, sip_pvt::uri, sip_invite_param::uri_options, username, sip_pvt::username, sip_pvt::via, and sip_invite_param::vxml_url.

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

04801 {
04802    char invite_buf[256] = "";
04803    char *invite = invite_buf;
04804    size_t invite_max = sizeof(invite_buf);
04805    char from[256];
04806    char to[256];
04807    char tmp[BUFSIZ/2];
04808    char tmp2[BUFSIZ/2];
04809    char iabuf[INET_ADDRSTRLEN];
04810    char *l = NULL, *n = NULL;
04811    int x;
04812    char urioptions[256]="";
04813 
04814    if (ast_test_flag(p, SIP_USEREQPHONE)) {
04815       char onlydigits = 1;
04816       x=0;
04817 
04818       /* Test p->username against allowed characters in AST_DIGIT_ANY
04819       If it matches the allowed characters list, then sipuser = ";user=phone"
04820       If not, then sipuser = ""
04821          */
04822          /* + is allowed in first position in a tel: uri */
04823          if (p->username && p->username[0] == '+')
04824          x=1;
04825 
04826       for (; x < strlen(p->username); x++) {
04827          if (!strchr(AST_DIGIT_ANYNUM, p->username[x])) {
04828                      onlydigits = 0;
04829             break;
04830          }
04831       }
04832 
04833       /* If we have only digits, add ;user=phone to the uri */
04834       if (onlydigits)
04835          strcpy(urioptions, ";user=phone");
04836    }
04837 
04838 
04839    snprintf(p->lastmsg, sizeof(p->lastmsg), "Init: %s", sip_methods[sipmethod].text);
04840 
04841    if (p->owner) {
04842       l = p->owner->cid.cid_num;
04843       n = p->owner->cid.cid_name;
04844    }
04845    /* if we are not sending RPID and user wants his callerid restricted */
04846    if (!ast_test_flag(p, SIP_SENDRPID) && ((p->callingpres & AST_PRES_RESTRICTION) != AST_PRES_ALLOWED)) {
04847       l = CALLERID_UNKNOWN;
04848       n = l;
04849    }
04850    if (!l)
04851       l = default_callerid;
04852    if (ast_strlen_zero(n))
04853       n = l;
04854    /* Allow user to be overridden */
04855    if (!ast_strlen_zero(p->fromuser))
04856       l = p->fromuser;
04857    else /* Save for any further attempts */
04858       ast_copy_string(p->fromuser, l, sizeof(p->fromuser));
04859 
04860    /* Allow user to be overridden */
04861    if (!ast_strlen_zero(p->fromname))
04862       n = p->fromname;
04863    else /* Save for any further attempts */
04864       ast_copy_string(p->fromname, n, sizeof(p->fromname));
04865 
04866    if (pedanticsipchecking) {
04867       ast_uri_encode(n, tmp, sizeof(tmp), 0);
04868       n = tmp;
04869       ast_uri_encode(l, tmp2, sizeof(tmp2), 0);
04870       l = tmp2;
04871    }
04872 
04873    if ((ourport != 5060) && ast_strlen_zero(p->fromdomain)) /* Needs to be 5060 */
04874       snprintf(from, sizeof(from), "\"%s\" <sip:%s@%s:%d>;tag=%s", n, l, ast_strlen_zero(p->fromdomain) ? ast_inet_ntoa(iabuf, sizeof(iabuf), p->ourip) : p->fromdomain, ourport, p->tag);
04875    else
04876       snprintf(from, sizeof(from), "\"%s\" <sip:%s@%s>;tag=%s", n, l, ast_strlen_zero(p->fromdomain) ? ast_inet_ntoa(iabuf, sizeof(iabuf), p->ourip) : p->fromdomain, p->tag);
04877 
04878    /* If we're calling a registered SIP peer, use the fullcontact to dial to the peer */
04879    if (!ast_strlen_zero(p->fullcontact)) {
04880       /* If we have full contact, trust it */
04881       ast_build_string(&invite, &invite_max, "%s", p->fullcontact);
04882    } else {
04883       /* Otherwise, use the username while waiting for registration */
04884       ast_build_string(&invite, &invite_max, "sip:");
04885       if (!ast_strlen_zero(p->username)) {
04886          n = p->username;
04887          if (pedanticsipchecking) {
04888             ast_uri_encode(n, tmp, sizeof(tmp), 0);
04889             n = tmp;
04890          }
04891          ast_build_string(&invite, &invite_max, "%s@", n);
04892       }
04893       ast_build_string(&invite, &invite_max, "%s", p->tohost);
04894       if (ntohs(p->sa.sin_port) != 5060)     /* Needs to be 5060 */
04895          ast_build_string(&invite, &invite_max, ":%d", ntohs(p->sa.sin_port));
04896       ast_build_string(&invite, &invite_max, "%s", urioptions);
04897    }
04898 
04899    /* If custom URI options have been provided, append them */
04900    if (p->options && p->options->uri_options)
04901       ast_build_string(&invite, &invite_max, ";%s", p->options->uri_options);
04902 
04903    ast_copy_string(p->uri, invite_buf, sizeof(p->uri));
04904 
04905    if (sipmethod == SIP_NOTIFY && !ast_strlen_zero(p->theirtag)) { 
04906       /* If this is a NOTIFY, use the From: tag in the subscribe (RFC 3265) */
04907       snprintf(to, sizeof(to), "<sip:%s>;tag=%s", p->uri, p->theirtag);
04908    } else if (p->options && p->options->vxml_url) {
04909       /* If there is a VXML URL append it to the SIP URL */
04910       snprintf(to, sizeof(to), "<%s>;%s", p->uri, p->options->vxml_url);
04911    } else {
04912       snprintf(to, sizeof(to), "<%s>", p->uri);
04913    }
04914    
04915    memset(req, 0, sizeof(struct sip_request));
04916    init_req(req, sipmethod, p->uri);
04917    snprintf(tmp, sizeof(tmp), "%d %s", ++p->ocseq, sip_methods[sipmethod].text);
04918 
04919    add_header(req, "Via", p->via);
04920    /* SLD: FIXME?: do Route: here too?  I think not cos this is the first request.
04921     * OTOH, then we won't have anything in p->route anyway */
04922    /* Build Remote Party-ID and From */
04923    if (ast_test_flag(p, SIP_SENDRPID) && (sipmethod == SIP_INVITE)) {
04924       build_rpid(p);
04925       add_header(req, "From", p->rpid_from);
04926    } else {
04927       add_header(req, "From", from);
04928    }
04929    add_header(req, "To", to);
04930    ast_copy_string(p->exten, l, sizeof(p->exten));
04931    build_contact(p);
04932    add_header(req, "Contact", p->our_contact);
04933    add_header(req, "Call-ID", p->callid);
04934    add_header(req, "CSeq", tmp);
04935    add_header(req, "User-Agent", default_useragent);
04936    add_header(req, "Max-Forwards", DEFAULT_MAX_FORWARDS);
04937    if (p->rpid)
04938       add_header(req, "Remote-Party-ID", p->rpid);
04939 }

static const char* insecure2str int  port,
int  invite
[static]
 

insecure2str: Convert Insecure setting to printable string ---

Definition at line 7744 of file chan_sip.c.

Referenced by _sip_show_peer().

07745 {
07746    if (port && invite)
07747       return "port,invite";
07748    else if (port)
07749       return "port";
07750    else if (invite)
07751       return "invite";
07752    else
07753       return "no";
07754 }

char* key void   ) 
 

Returns the ASTERISK_GPL_KEY.

This returns the ASTERISK_GPL_KEY, signifiying that you agree to the terms of the GPL stated in the ASTERISK_GPL_KEY. Your module will not load if it does not return the EXACT message:

 char *key(void) {
         return ASTERISK_GPL_KEY;
 }

Returns:
ASTERISK_GPL_KEY

Definition at line 13468 of file chan_sip.c.

References ASTERISK_GPL_KEY.

13469 {
13470    return ASTERISK_GPL_KEY;
13471 }

static void list_route struct sip_route route  )  [static]
 

list_route: List all routes - mostly for debugging ---

Definition at line 6052 of file chan_sip.c.

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

Referenced by build_route().

06053 {
06054    if (!route) {
06055       ast_verbose("list_route: no route\n");
06056       return;
06057    }
06058    while (route) {
06059       ast_verbose("list_route: hop: <%s>\n", route->hop);
06060       route = route->next;
06061    }
06062 }

int load_module void   ) 
 

Initialize the module.

Initialize the Agents module. This function is being called by Asterisk when loading the module. Among other thing it registers applications, cli commands and reads the cofiguration file.

Returns:
int Always 0.

Definition at line 13316 of file chan_sip.c.

References app_dtmfmode, app_sipaddheader, app_sipgetheader, ast_channel_register(), ast_cli_register_multiple(), ast_custom_function_register(), ast_log(), ast_manager_register2(), ast_register_application(), ast_rtp_proto_register(), ASTOBJ_CONTAINER_INIT, channeltype, checksipdomain_function, descrip_dtmfmode, descrip_sipaddheader, descrip_sipgetheader, EVENT_FLAG_SYSTEM, io_context_create(), LOG_ERROR, LOG_WARNING, manager_sip_show_peer(), manager_sip_show_peers(), mandescr_show_peer, mandescr_show_peers, peerl, regl, reload_config(), restart_monitor(), sched_context_create(), sip_addheader(), sip_dtmfmode(), sip_getheader(), sip_header_function, sip_poke_all_peers(), sip_rtp, sip_send_all_registers(), sip_tech, sipchaninfo_function, sippeer_function, synopsis_dtmfmode, synopsis_sipaddheader, synopsis_sipgetheader, and userl.

13317 {
13318    ASTOBJ_CONTAINER_INIT(&userl);   /* User object list */
13319    ASTOBJ_CONTAINER_INIT(&peerl);   /* Peer object list */
13320    ASTOBJ_CONTAINER_INIT(&regl); /* Registry object list */
13321 
13322    sched = sched_context_create();
13323    if (!sched) {
13324       ast_log(LOG_WARNING, "Unable to create schedule context\n");
13325    }
13326 
13327    io = io_context_create();
13328    if (!io) {
13329       ast_log(LOG_WARNING, "Unable to create I/O context\n");
13330    }
13331 
13332    reload_config();  /* Load the configuration from sip.conf */
13333 
13334    /* Make sure we can register our sip channel type */
13335    if (ast_channel_register(&sip_tech)) {
13336       ast_log(LOG_ERROR, "Unable to register channel type %s\n", channeltype);
13337       return -1;
13338    }
13339 
13340    /* Register all CLI functions for SIP */
13341    ast_cli_register_multiple(my_clis, sizeof(my_clis)/ sizeof(my_clis[0]));
13342 
13343    /* Tell the RTP subdriver that we're here */
13344    ast_rtp_proto_register(&sip_rtp);
13345 
13346    /* Register dialplan applications */
13347    ast_register_application(app_dtmfmode, sip_dtmfmode, synopsis_dtmfmode, descrip_dtmfmode);
13348 
13349    /* These will be removed soon */
13350    ast_register_application(app_sipaddheader, sip_addheader, synopsis_sipaddheader, descrip_sipaddheader);
13351    ast_register_application(app_sipgetheader, sip_getheader, synopsis_sipgetheader, descrip_sipgetheader);
13352 
13353    /* Register dialplan functions */
13354    ast_custom_function_register(&sip_header_function);
13355    ast_custom_function_register(&sippeer_function);
13356    ast_custom_function_register(&sipchaninfo_function);
13357    ast_custom_function_register(&checksipdomain_function);
13358 
13359    /* Register manager commands */
13360    ast_manager_register2("SIPpeers", EVENT_FLAG_SYSTEM, manager_sip_show_peers,
13361          "List SIP peers (text format)", mandescr_show_peers);
13362    ast_manager_register2("SIPshowpeer", EVENT_FLAG_SYSTEM, manager_sip_show_peer,
13363          "Show SIP peer (text format)", mandescr_show_peer);
13364 
13365    sip_poke_all_peers();   
13366    sip_send_all_registers();
13367    
13368    /* And start the monitor for the first time */
13369    restart_monitor();
13370 
13371    return 0;
13372 }

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

lws2sws: Parse multiline SIP headers into one header

Definition at line 3296 of file chan_sip.c.

References t.

Referenced by sipsock_read().

03297 { 
03298    int h = 0, t = 0; 
03299    int lws = 0; 
03300 
03301    for (; h < len;) { 
03302       /* Eliminate all CRs */ 
03303       if (msgbuf[h] == '\r') { 
03304          h++; 
03305          continue; 
03306       } 
03307       /* Check for end-of-line */ 
03308       if (msgbuf[h] == '\n') { 
03309          /* Check for end-of-message */ 
03310          if (h + 1 == len) 
03311             break; 
03312          /* Check for a continuation line */ 
03313          if (msgbuf[h + 1] == ' ' || msgbuf[h + 1] == '\t') { 
03314             /* Merge continuation line */ 
03315             h++; 
03316             continue; 
03317          } 
03318          /* Propagate LF and start new line */ 
03319          msgbuf[t++] = msgbuf[h++]; 
03320          lws = 0;
03321          continue; 
03322       } 
03323       if (msgbuf[h] == ' ' || msgbuf[h] == '\t') { 
03324          if (lws) { 
03325             h++; 
03326             continue; 
03327          } 
03328          msgbuf[t++] = msgbuf[h++]; 
03329          lws = 1; 
03330          continue; 
03331       } 
03332       msgbuf[t++] = msgbuf[h++]; 
03333       if (lws) 
03334          lws = 0; 
03335    } 
03336    msgbuf[t] = '\0'; 
03337    return t; 
03338 }

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

Definition at line 3048 of file chan_sip.c.

References thread_safe_rand().

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

03049 {
03050    snprintf(tagbuf, len, "as%08x", thread_safe_rand());
03051 }

static int manager_sip_show_peer struct mansession s,
struct message m
[static]
 

manager_sip_show_peer: Show SIP peers in the manager API ---

Definition at line 7964 of file chan_sip.c.

References _sip_show_peer(), ast_cli(), ast_strlen_zero(), astman_get_header(), astman_send_error(), and mansession::fd.

Referenced by load_module().

07965 {
07966    char *id = astman_get_header(m,"ActionID");
07967    char *a[4];
07968    char *peer;
07969    int ret;
07970 
07971    peer = astman_get_header(m,"Peer");
07972    if (ast_strlen_zero(peer)) {
07973       astman_send_error(s, m, "Peer: <name> missing.\n");
07974       return 0;
07975    }
07976    a[0] = "sip";
07977    a[1] = "show";
07978    a[2] = "peer";
07979    a[3] = peer;
07980 
07981    if (!ast_strlen_zero(id))
07982       ast_cli(s->fd, "ActionID: %s\r\n",id);
07983    ret = _sip_show_peer(1, s->fd, s, m, 4, a );
07984    ast_cli( s->fd, "\r\n\r\n" );
07985    return ret;
07986 }

static int manager_sip_show_peers struct mansession s,
struct message m
[static]
 

manager_sip_show_peers: Show SIP peers in the manager API ---

Definition at line 7545 of file chan_sip.c.

References _sip_show_peers(), ast_cli(), ast_strlen_zero(), astman_get_header(), astman_send_ack(), mansession::fd, and total.

Referenced by load_module().

07546 {
07547    char *id = astman_get_header(m,"ActionID");
07548    char *a[] = { "sip", "show", "peers" };
07549    char idtext[256] = "";
07550    int total = 0;
07551 
07552    if (!ast_strlen_zero(id))
07553       snprintf(idtext,256,"ActionID: %s\r\n",id);
07554 
07555    astman_send_ack(s, m, "Peer status list will follow");
07556    /* List the peers in separate manager events */
07557    _sip_show_peers(s->fd, &total, s, m, 3, a);
07558    /* Send final confirmation */
07559    ast_cli(s->fd,
07560    "Event: PeerlistComplete\r\n"
07561    "ListItems: %d\r\n"
07562    "%s"
07563    "\r\n", total, idtext);
07564    return 0;
07565 }

static char* nat2str int  nat  )  [static]
 

nat2str: Convert NAT setting to text string

Definition at line 7447 of file chan_sip.c.

References SIP_NAT_ALWAYS, SIP_NAT_NEVER, SIP_NAT_RFC3581, and SIP_NAT_ROUTE.

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

07448 {
07449    switch(nat) {
07450    case SIP_NAT_NEVER:
07451       return "No";
07452    case SIP_NAT_ROUTE:
07453       return "Route";
07454    case SIP_NAT_ALWAYS:
07455       return "Always";
07456    case SIP_NAT_RFC3581:
07457       return "RFC3581";
07458    default:
07459       return "Unknown";
07460    }
07461 }

static void parse_copy struct sip_request dst,
struct sip_request src
[static]
 

parse_copy: Copy SIP request, parse it

Definition at line 1463 of file chan_sip.c.

References sip_request::data, sip_request::len, and parse_request().

Referenced by send_request(), and send_response().

01464 {
01465    memset(dst, 0, sizeof(*dst));
01466    memcpy(dst->data, src->data, sizeof(dst->data));
01467    dst->len = src->len;
01468    parse_request(dst);
01469 }

static void parse_moved_contact struct sip_pvt p,
struct sip_request req
[static]
 

parse_moved_contact: Parse 302 Moved temporalily response

Definition at line 9512 of file chan_sip.c.

References ast_log(), ast_test_flag, get_header(), get_in_brackets(), LOG_DEBUG, s, and SIP_PROMISCREDIR.

Referenced by handle_response().

09513 {
09514    char tmp[256];
09515    char *s, *e;
09516    ast_copy_string(tmp, get_header(req, "Contact"), sizeof(tmp));
09517    s = get_in_brackets(tmp);
09518    e = strchr(s, ';');
09519    if (e)
09520       *e = '\0';
09521    if (ast_test_flag(p, SIP_PROMISCREDIR)) {
09522       if (!strncasecmp(s, "sip:", 4))
09523          s += 4;
09524       e = strchr(s, '/');
09525       if (e)
09526          *e = '\0';
09527       ast_log(LOG_DEBUG, "Found promiscuous redirection to 'SIP/%s'\n", s);
09528       if (p->owner)
09529          snprintf(p->owner->call_forward, sizeof(p->owner->call_forward), "SIP/%s", s);
09530    } else {
09531       e = strchr(tmp, '@');
09532       if (e)
09533          *e = '\0';
09534       e = strchr(tmp, '/');
09535       if (e)
09536          *e = '\0';
09537       if (!strncasecmp(s, "sip:", 4))
09538          s += 4;
09539       ast_log(LOG_DEBUG, "Found 302 Redirect to extension '%s'\n", s);
09540       if (p->owner)
09541          ast_copy_string(p->owner->call_forward, s, sizeof(p->owner->call_forward));
09542    }
09543 }

static int parse_ok_contact struct sip_pvt pvt,
struct sip_request req
[static]
 

parse_ok_contact: Parse contact header for 200 OK on INVITE ---

Definition at line 5813 of file chan_sip.c.

References ast_gethostbyname(), ast_log(), ast_test_flag, DEFAULT_SIP_PORT, sip_pvt::fullcontact, get_header(), get_in_brackets(), hp, LOG_NOTICE, LOG_WARNING, n, sip_pvt::okcontacturi, sip_pvt::recv, sip_pvt::sa, SIP_LEN_CONTACT, SIP_NAT, and SIP_NAT_ROUTE.

Referenced by handle_response_invite().

05814 {
05815    char contact[SIP_LEN_CONTACT]; 
05816    char *c, *n, *pt;
05817    int port;
05818    struct hostent *hp;
05819    struct ast_hostent ahp;
05820    struct sockaddr_in oldsin;
05821 
05822    /* Look for brackets */
05823    ast_copy_string(contact, get_header(req, "Contact"), sizeof(contact));
05824    c = get_in_brackets(contact);
05825 
05826    /* Save full contact to call pvt for later bye or re-invite */
05827    ast_copy_string(pvt->fullcontact, c, sizeof(pvt->fullcontact));   
05828 
05829    /* Save URI for later ACKs, BYE or RE-invites */
05830    ast_copy_string(pvt->okcontacturi, c, sizeof(pvt->okcontacturi));
05831    
05832    /* Make sure it's a SIP URL */
05833    if (strncasecmp(c, "sip:", 4)) {
05834       ast_log(LOG_NOTICE, "'%s' is not a valid SIP contact (missing sip:) trying to use anyway\n", c);
05835    } else
05836       c += 4;
05837 
05838    /* Ditch arguments */
05839    n = strchr(c, ';');
05840    if (n) 
05841       *n = '\0';
05842 
05843    /* Grab host */
05844    n = strchr(c, '@');
05845    if (!n) {
05846       n = c;
05847       c = NULL;
05848    } else {
05849       *n = '\0';
05850       n++;
05851    }
05852    pt = strchr(n, ':');
05853    if (pt) {
05854       *pt = '\0';
05855       pt++;
05856       port = atoi(pt);
05857    } else
05858       port = DEFAULT_SIP_PORT;
05859 
05860    memcpy(&oldsin, &pvt->sa, sizeof(oldsin));
05861 
05862    if (!(ast_test_flag(pvt, SIP_NAT) & SIP_NAT_ROUTE)) {
05863       /* XXX This could block for a long time XXX */
05864       /* We should only do this if it's a name, not an IP */
05865       hp = ast_gethostbyname(n, &ahp);
05866       if (!hp)  {
05867          ast_log(LOG_WARNING, "Invalid host '%s'\n", n);
05868          return -1;
05869       }
05870       pvt->sa.sin_family = AF_INET;
05871       memcpy(&pvt->sa.sin_addr, hp->h_addr, sizeof(pvt->sa.sin_addr));
05872       pvt->sa.sin_port = htons(port);
05873    } else {
05874       /* Don't trust the contact field.  Just use what they came to us
05875          with. */
05876       memcpy(&pvt->sa, &pvt->recv, sizeof(pvt->sa));
05877    }
05878    return 0;
05879 }

static enum parse_register_result parse_register_contact struct sip_pvt pvt,
struct sip_peer p,
struct sip_request req
[static]
 

parse_register_contact: Parse contact header and save registration ---

Definition at line 5889 of file chan_sip.c.

References sip_peer::addr, ast_db_put(), ast_gethostbyname(), ast_inet_ntoa(), ast_log(), ast_sched_add(), ast_sched_del(), ast_sched_when(), ast_strlen_zero(), ast_test_flag, ast_verbose(), default_expiry, DEFAULT_SIP_PORT, destroy_association(), EVENT_FLAG_SYSTEM, sip_peer::expire, expire_register(), sip_pvt::expiry, expiry, sip_peer::flags_page2, sip_peer::fullcontact, get_header(), get_in_brackets(), hp, inaddrcmp(), sip_peer::lastms, LOG_NOTICE, LOG_WARNING, manager_event(), max_expiry, n, option_verbose, sip_pvt::our_contact, PARSE_REGISTER_FAILED, PARSE_REGISTER_QUERY, PARSE_REGISTER_UPDATE, sip_pvt::recv, register_peer_exten(), SIP_NAT, SIP_NAT_ROUTE, SIP_PAGE2_RT_FROMCONTACT, sip_poke_peer(), SIP_REALTIME, sip_pvt::sipoptions, sip_peer::sipoptions, strcasestr(), sip_peer::useragent, sip_peer::username, and VERBOSE_PREFIX_3.

Referenced by register_verify().

05890 {
05891    char contact[BUFSIZ]; 
05892    char data[BUFSIZ];
05893    char iabuf[INET_ADDRSTRLEN];
05894    char *expires = get_header(req, "Expires");
05895    int expiry = atoi(expires);
05896    char *c, *n, *pt;
05897    int port;
05898    char *useragent;
05899    struct hostent *hp;
05900    struct ast_hostent ahp;
05901    struct sockaddr_in oldsin;
05902 
05903    if (ast_strlen_zero(expires)) {  /* No expires header */
05904       expires = strcasestr(get_header(req, "Contact"), ";expires=");
05905       if (expires) {
05906          char *ptr;
05907          if ((ptr = strchr(expires, ';')))
05908             *ptr = '\0';
05909          if (sscanf(expires + 9, "%d", &expiry) != 1)
05910             expiry = default_expiry;
05911       } else {
05912          /* Nothing has been specified */
05913          expiry = default_expiry;
05914       }
05915    }
05916    /* Look for brackets */
05917    ast_copy_string(contact, get_header(req, "Contact"), sizeof(contact));
05918    if (strchr(contact, '<') == NULL) { /* No <, check for ; and strip it */
05919       char *ptr = strchr(contact, ';');   /* This is Header options, not URI options */
05920       if (ptr)
05921          *ptr = '\0';
05922    }
05923    c = get_in_brackets(contact);
05924 
05925    /* if they did not specify Contact: or Expires:, they are querying
05926       what we currently have stored as their contact address, so return
05927       it
05928    */
05929    if (ast_strlen_zero(c) && ast_strlen_zero(expires)) {
05930       /* If we have an active registration, tell them when the registration is going to expire */
05931       if ((p->expire > -1) && !ast_strlen_zero(p->fullcontact)) {
05932          pvt->expiry = ast_sched_when(sched, p->expire);
05933       } 
05934       return PARSE_REGISTER_QUERY;
05935    } else if (!strcasecmp(c, "*") || !expiry) { /* Unregister this peer */
05936       /* This means remove all registrations and return OK */
05937       memset(&p->addr, 0, sizeof(p->addr));
05938       if (p->expire > -1)
05939          ast_sched_del(sched, p->expire);
05940       p->expire = -1;
05941 
05942       destroy_association(p);
05943       
05944       register_peer_exten(p, 0);
05945       p->fullcontact[0] = '\0';
05946       p->useragent[0] = '\0';
05947       p->sipoptions = 0;
05948       p->lastms = 0;
05949 
05950       if (option_verbose > 2)
05951          ast_verbose(VERBOSE_PREFIX_3 "Unregistered SIP '%s'\n", p->name);
05952          manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: SIP/%s\r\nPeerStatus: Unregistered\r\n", p->name);
05953       return PARSE_REGISTER_UPDATE;
05954    }
05955    ast_copy_string(p->fullcontact, c, sizeof(p->fullcontact));
05956    /* For the 200 OK, we should use the received contact */
05957    snprintf(pvt->our_contact, sizeof(pvt->our_contact) - 1, "<%s>", c);
05958    /* Make sure it's a SIP URL */
05959    if (strncasecmp(c, "sip:", 4)) {
05960       ast_log(LOG_NOTICE, "'%s' is not a valid SIP contact (missing sip:) trying to use anyway\n", c);
05961    } else
05962       c += 4;
05963    /* Ditch q */
05964    n = strchr(c, ';');
05965    if (n) {
05966       *n = '\0';
05967    }
05968    /* Grab host */
05969    n = strchr(c, '@');
05970    if (!n) {
05971       n = c;
05972       c = NULL;
05973    } else {
05974       *n = '\0';
05975       n++;
05976    }
05977    pt = strchr(n, ':');
05978    if (pt) {
05979       *pt = '\0';
05980       pt++;
05981       port = atoi(pt);
05982    } else
05983       port = DEFAULT_SIP_PORT;
05984    memcpy(&oldsin, &p->addr, sizeof(oldsin));
05985    if (!(ast_test_flag(p, SIP_NAT) & SIP_NAT_ROUTE)) {
05986       /* XXX This could block for a long time XXX */
05987       hp = ast_gethostbyname(n, &ahp);
05988       if (!hp)  {
05989          ast_log(LOG_WARNING, "Invalid host '%s'\n", n);
05990          return PARSE_REGISTER_FAILED;
05991       }
05992       p->addr.sin_family = AF_INET;
05993       memcpy(&p->addr.sin_addr, hp->h_addr, sizeof(p->addr.sin_addr));
05994       p->addr.sin_port = htons(port);
05995    } else {
05996       /* Don't trust the contact field.  Just use what they came to us
05997          with */
05998       memcpy(&p->addr, &pvt->recv, sizeof(p->addr));
05999    }
06000 
06001    if (c)   /* Overwrite the default username from config at registration */
06002       ast_copy_string(p->username, c, sizeof(p->username));
06003    else
06004       p->username[0] = '\0';
06005 
06006    if (p->expire > -1)
06007       ast_sched_del(sched, p->expire);
06008    if ((expiry < 1) || (expiry > max_expiry))
06009       expiry = max_expiry;
06010    if (!ast_test_flag(p, SIP_REALTIME))
06011       p->expire = ast_sched_add(sched, (expiry + 10) * 1000, expire_register, p);
06012    else
06013       p->expire = -1;
06014    pvt->expiry = expiry;
06015    snprintf(data, sizeof(data), "%s:%d:%d:%s:%s", ast_inet_ntoa(iabuf, sizeof(iabuf), p->addr.sin_addr), ntohs(p->addr.sin_port), expiry, p->username, p->fullcontact);
06016    if (!ast_test_flag((&p->flags_page2), SIP_PAGE2_RT_FROMCONTACT)) 
06017       ast_db_put("SIP/Registry", p->name, data);
06018    manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: SIP/%s\r\nPeerStatus: Registered\r\n", p->name);
06019    if (inaddrcmp(&p->addr, &oldsin)) {
06020       sip_poke_peer(p);
06021       if (option_verbose > 2)
06022          ast_verbose(VERBOSE_PREFIX_3 "Registered SIP '%s' at %s port %d expires %d\n", p->name, ast_inet_ntoa(iabuf, sizeof(iabuf), p->addr.sin_addr), ntohs(p->addr.sin_port), expiry);
06023       register_peer_exten(p, 1);
06024    }
06025    
06026    /* Save SIP options profile */
06027    p->sipoptions = pvt->sipoptions;
06028 
06029    /* Save User agent */
06030    useragent = get_header(req, "User-Agent");
06031    if (useragent && strcasecmp(useragent, p->useragent)) {
06032       ast_copy_string(p->useragent, useragent, sizeof(p->useragent));
06033       if (option_verbose > 3) {
06034          ast_verbose(VERBOSE_PREFIX_3 "Saved useragent \"%s\" for peer %s\n",p->useragent,p->name);  
06035       }
06036    }
06037    return PARSE_REGISTER_UPDATE;
06038 }

static void parse_request struct sip_request req  )  [static]
 

parse_request: Parse a SIP message ----

Definition at line 3341 of file chan_sip.c.

References ast_log(), ast_strlen_zero(), determine_firstline_parts(), LOG_DEBUG, LOG_WARNING, option_debug, SIP_MAX_HEADERS, SIP_MAX_LINES, and sipdebug.

Referenced by parse_copy(), sipsock_read(), transmit_invite(), transmit_notify_with_mwi(), transmit_notify_with_sipfrag(), transmit_register(), transmit_reinvite_with_sdp(), and transmit_sip_request().

03342 {
03343    /* Divide fields by NULL's */
03344    char *c;
03345    int f = 0;
03346 
03347    c = req->data;
03348 
03349    /* First header starts immediately */
03350    req->header[f] = c;
03351    while(*c) {
03352       if (*c == '\n') {
03353          /* We've got a new header */
03354          *c = 0;
03355 
03356          if (sipdebug && option_debug > 3)
03357             ast_log(LOG_DEBUG, "Header %d: %s (%d)\n", f, req->header[f], (int) strlen(req->header[f]));
03358          if (ast_strlen_zero(req->header[f])) {
03359             /* Line by itself means we're now in content */
03360             c++;
03361             break;
03362          }
03363          if (f >= SIP_MAX_HEADERS - 1) {
03364             ast_log(LOG_WARNING, "Too many SIP headers. Ignoring.\n");
03365          } else
03366             f++;
03367          req->header[f] = c + 1;
03368       } else if (*c == '\r') {
03369          /* Ignore but eliminate \r's */
03370          *c = 0;
03371       }
03372       c++;
03373    }
03374    /* Check for last header */
03375    if (!ast_strlen_zero(req->header[f])) {
03376       if (sipdebug && option_debug > 3)
03377          ast_log(LOG_DEBUG, "Header %d: %s (%d)\n", f, req->header[f], (int) strlen(req->header[f]));
03378       f++;
03379    }
03380    req->headers = f;
03381    /* Now we process any mime content */
03382    f = 0;
03383    req->line[f] = c;
03384    while(*c) {
03385       if (*c == '\n') {
03386          /* We've got a new line */
03387          *c = 0;
03388          if (sipdebug && option_debug > 3)
03389             ast_log(LOG_DEBUG, "Line: %s (%d)\n", req->line[f], (int) strlen(req->line[f]));
03390          if (f >= SIP_MAX_LINES - 1) {
03391             ast_log(LOG_WARNING, "Too many SDP lines. Ignoring.\n");
03392          } else
03393             f++;
03394          req->line[f] = c + 1;
03395       } else if (*c == '\r') {
03396          /* Ignore and eliminate \r's */
03397          *c = 0;
03398       }
03399       c++;
03400    }
03401    /* Check for last line */
03402    if (!ast_strlen_zero(req->line[f])) 
03403       f++;
03404    req->lines = f;
03405    if (*c) 
03406       ast_log(LOG_WARNING, "Odd content, extra stuff left over ('%s')\n", c);
03407    /* Split up the first line parts */
03408    determine_firstline_parts(req);
03409 }

unsigned int parse_sip_options struct sip_pvt pvt,
char *  supported
 

parse_sip_options: Parse supported header in incoming packet

Definition at line 992 of file chan_sip.c.

References ast_log(), ast_strdupa, ast_strlen_zero(), LOG_DEBUG, option_debug, sip_options, sipdebug, and text.

Referenced by handle_request_invite().

00993 {
00994    char *next = NULL;
00995    char *sep = NULL;
00996    char *temp = ast_strdupa(supported);
00997    int i;
00998    unsigned int profile = 0;
00999 
01000    if (ast_strlen_zero(supported) )
01001       return 0;
01002 
01003    if (option_debug > 2 && sipdebug)
01004       ast_log(LOG_DEBUG, "Begin: parsing SIP \"Supported: %s\"\n", supported);
01005 
01006    next = temp;
01007    while (next) {
01008       char res=0;
01009       if ( (sep = strchr(next, ',')) != NULL) {
01010          *sep = '\0';
01011          sep++;
01012       }
01013       while (*next == ' ') /* Skip spaces */
01014          next++;
01015       if (option_debug > 2 && sipdebug)
01016          ast_log(LOG_DEBUG, "Found SIP option: -%s-\n", next);
01017       for (i=0; (i < (sizeof(sip_options) / sizeof(sip_options[0]))) && !res; i++) {
01018          if (!strcasecmp(next, sip_options[i].text)) {
01019             profile |= sip_options[i].id;
01020             res = 1;
01021             if (option_debug > 2 && sipdebug)
01022                ast_log(LOG_DEBUG, "Matched SIP option: %s\n", next);
01023          }
01024       }
01025       if (!res) 
01026          if (option_debug > 2 && sipdebug)
01027             ast_log(LOG_DEBUG, "Found no match for SIP option: %s (Please file bug report!)\n", next);
01028       next = sep;
01029    }
01030    if (pvt) {
01031       pvt->sipoptions = profile;
01032       if (option_debug)
01033          ast_log(LOG_DEBUG, "* SIP extension value: %d for call %s\n", profile, pvt->callid);
01034    }
01035    return profile;
01036 }

static int peer_status struct sip_peer peer,
char *  status,
int  statuslen
[static]
 

peer_status: Report Peer status in character string

Definition at line 7465 of file chan_sip.c.

References sip_peer::lastms, and sip_peer::maxms.

07466 {
07467    int res = 0;
07468    if (peer->maxms) {
07469       if (peer->lastms < 0) {
07470          ast_copy_string(status, "UNREACHABLE", statuslen);
07471       } else if (peer->lastms > peer->maxms) {
07472          snprintf(status, statuslen, "LAGGED (%d ms)", peer->lastms);
07473          res = 1;
07474       } else if (peer->lastms) {
07475          snprintf(status, statuslen, "OK (%d ms)", peer->lastms);
07476          res = 1;
07477       } else {
07478          ast_copy_string(status, "UNKNOWN", statuslen);
07479       }
07480    } else { 
07481       ast_copy_string(status, "Unmonitored", statuslen);
07482       /* Checking if port is 0 */
07483       res = -1;
07484    }
07485    return res;
07486 }

static void print_codec_to_cli int  fd,
struct ast_codec_pref pref
[static]
 

print_codec_to_cli: Print codec list from preference to CLI/manager

Definition at line 7904 of file chan_sip.c.

References ast_cli(), ast_codec_pref_index(), and ast_getformatname().

Referenced by _sip_show_peer(), and sip_show_settings().

07905 {
07906    int x, codec;
07907 
07908    for(x = 0; x < 32 ; x++) {
07909       codec = ast_codec_pref_index(pref, x);
07910       if (!codec)
07911          break;
07912       ast_cli(fd, "%s", ast_getformatname(codec));
07913       if (x < 31 && ast_codec_pref_index(pref, x + 1))
07914          ast_cli(fd, ",");
07915    }
07916    if (!x)
07917       ast_cli(fd, "none");
07918 }

static void print_group int  fd,
unsigned int  group,
int  crlf
[static]
 

print_group: Print call group and pickup group ---

Definition at line 7721 of file chan_sip.c.

References ast_cli(), and ast_print_group().

Referenced by _sip_show_peer(), and sip_show_user().

07722 {
07723    char buf[256];
07724    ast_cli(fd, crlf ? "%s\r\n" : "%s\n", ast_print_group(buf, sizeof(buf), group) );
07725 }

static int process_sdp struct sip_pvt p,
struct sip_request req
[static]
 

process_sdp: Process SIP SDP and activate RTP channels---

Definition at line 3474 of file chan_sip.c.

References append_history(), ast_bridged_channel(), ast_clear_flag, ast_codec_choose(), AST_FRAME_NULL, ast_getformatname_multiple(), ast_gethostbyname(), ast_inet_ntoa(), ast_log(), ast_moh_start(), ast_moh_stop(), ast_queue_frame(), AST_RTP_DTMF, ast_rtp_get_current_formats(), ast_rtp_lookup_mime_multiple(), ast_rtp_pt_clear(), ast_rtp_set_m_type(), ast_rtp_set_peer(), ast_rtp_set_rtpmap_type(), ast_rtp_stop(), ast_set_flag, ast_set_read_format(), ast_set_write_format(), ast_strdupa, ast_strlen_zero(), ast_test_flag, ast_verbose(), callevents, sip_request::data, debug, EVENT_FLAG_CALL, get_sdp(), get_sdp_iterate(), host, hp, LOG_DEBUG, LOG_ERROR, LOG_NOTICE, LOG_WARNING, manager_event(), noncodeccapability, pedanticsipchecking, portno, sdpLineNum_iterator_init(), SIP_CALL_ONHOLD, sip_debug_test_pvt(), SIP_DTMF, SIP_DTMF_AUTO, SIP_DTMF_INBAND, SIP_DTMF_RFC2833, and SIP_NOVIDEO.

03475 {
03476    char *m;
03477    char *c;
03478    char *a;
03479    char host[258];
03480    char iabuf[INET_ADDRSTRLEN];
03481    int len = -1;
03482    int portno = -1;
03483    int vportno = -1;
03484    int peercapability, peernoncodeccapability;
03485    int vpeercapability=0, vpeernoncodeccapability=0;
03486    struct sockaddr_in sin;
03487    char *codecs;
03488    struct hostent *hp;
03489    struct ast_hostent ahp;
03490    int codec;
03491    int destiterator = 0;
03492    int iterator;
03493    int sendonly = 0;
03494    int x,y;
03495    int debug=sip_debug_test_pvt(p);
03496    struct ast_channel *bridgepeer = NULL;
03497 
03498    if (!p->rtp) {
03499       ast_log(LOG_ERROR, "Got SDP but have no RTP session allocated.\n");
03500       return -1;
03501    }
03502 
03503    /* Update our last rtprx when we receive an SDP, too */
03504    time(&p->lastrtprx);
03505    time(&p->lastrtptx);
03506 
03507    m = get_sdp(req, "m");
03508    sdpLineNum_iterator_init(&destiterator, req);
03509    c = get_sdp_iterate(&destiterator, req, "c");
03510    if (ast_strlen_zero(m) || ast_strlen_zero(c)) {
03511       ast_log(LOG_WARNING, "Insufficient information for SDP (m = '%s', c = '%s')\n", m, c);
03512       return -1;
03513    }
03514    if (sscanf(c, "IN IP4 %256s", host) != 1) {
03515       ast_log(LOG_WARNING, "Invalid host in c= line, '%s'\n", c);
03516       return -1;
03517    }
03518    /* XXX This could block for a long time, and block the main thread! XXX */
03519    hp = ast_gethostbyname(host, &ahp);
03520    if (!hp) {
03521       ast_log(LOG_WARNING, "Unable to lookup host in c= line, '%s'\n", c);
03522       return -1;
03523    }
03524    sdpLineNum_iterator_init(&iterator, req);
03525    ast_set_flag(p, SIP_NOVIDEO); 
03526    while ((m = get_sdp_iterate(&iterator, req, "m"))[0] != '\0') {
03527       int found = 0;
03528       if ((sscanf(m, "audio %d/%d RTP/AVP %n", &x, &y, &len) == 2) ||
03529           (sscanf(m, "audio %d RTP/AVP %n", &x, &len) == 1)) {
03530          found = 1;
03531          portno = x;
03532          /* Scan through the RTP payload types specified in a "m=" line: */
03533          ast_rtp_pt_clear(p->rtp);
03534          codecs = m + len;
03535          while(!ast_strlen_zero(codecs)) {
03536             if (sscanf(codecs, "%d%n", &codec, &len) != 1) {
03537                ast_log(LOG_WARNING, "Error in codec string '%s'\n", codecs);
03538                return -1;
03539             }
03540             if (debug)
03541                ast_verbose("Found RTP audio format %d\n", codec);
03542             ast_rtp_set_m_type(p->rtp, codec);
03543             codecs = ast_skip_blanks(codecs + len);
03544          }
03545       }
03546       if (p->vrtp)
03547          ast_rtp_pt_clear(p->vrtp);  /* Must be cleared in case no m=video line exists */
03548 
03549       if (p->vrtp && (sscanf(m, "video %d RTP/AVP %n", &x, &len) == 1)) {
03550          found = 1;
03551          ast_clear_flag(p, SIP_NOVIDEO);  
03552          vportno = x;
03553          /* Scan through the RTP payload types specified in a "m=" line: */
03554          codecs = m + len;
03555          while(!ast_strlen_zero(codecs)) {
03556             if (sscanf(codecs, "%d%n", &codec, &len) != 1) {
03557                ast_log(LOG_WARNING, "Error in codec string '%s'\n", codecs);
03558                return -1;
03559             }
03560             if (debug)
03561                ast_verbose("Found RTP video format %d\n", codec);
03562             ast_rtp_set_m_type(p->vrtp, codec);
03563             codecs = ast_skip_blanks(codecs + len);
03564          }
03565       }
03566       if (!found )
03567          ast_log(LOG_WARNING, "Unknown SDP media type in offer: %s\n", m);
03568    }
03569    if (portno == -1 && vportno == -1) {
03570       /* No acceptable offer found in SDP */
03571       return -2;
03572    }
03573    /* Check for Media-description-level-address for audio */
03574    if (pedanticsipchecking) {
03575       c = get_sdp_iterate(&destiterator, req, "c");
03576       if (!ast_strlen_zero(c)) {
03577          if (sscanf(c, "IN IP4 %256s", host) != 1) {
03578             ast_log(LOG_WARNING, "Invalid secondary host in c= line, '%s'\n", c);
03579          } else {
03580             /* XXX This could block for a long time, and block the main thread! XXX */
03581             hp = ast_gethostbyname(host, &ahp);
03582             if (!hp) {
03583                ast_log(LOG_WARNING, "Unable to lookup host in secondary c= line, '%s'\n", c);
03584             }
03585          }
03586       }
03587    }
03588    /* RTP addresses and ports for audio and video */
03589    sin.sin_family = AF_INET;
03590    memcpy(&sin.sin_addr, hp->h_addr, sizeof(sin.sin_addr));
03591 
03592    /* Setup audio port number */
03593    sin.sin_port = htons(portno);
03594    if (p->rtp && sin.sin_port) {
03595       ast_rtp_set_peer(p->rtp, &sin);
03596       if (debug) {
03597          ast_verbose("Peer audio RTP is at port %s:%d\n", ast_inet_ntoa(iabuf,sizeof(iabuf), sin.sin_addr), ntohs(sin.sin_port));
03598          ast_log(LOG_DEBUG,"Peer audio RTP is at port %s:%d\n",ast_inet_ntoa(iabuf, sizeof(iabuf), sin.sin_addr), ntohs(sin.sin_port));
03599       }
03600    }
03601    /* Check for Media-description-level-address for video */
03602    if (pedanticsipchecking) {
03603       c = get_sdp_iterate(&destiterator, req, "c");
03604       if (!ast_strlen_zero(c)) {
03605          if (sscanf(c, "IN IP4 %256s", host) != 1) {
03606             ast_log(LOG_WARNING, "Invalid secondary host in c= line, '%s'\n", c);
03607          } else {
03608             /* XXX This could block for a long time, and block the main thread! XXX */
03609             hp = ast_gethostbyname(host, &ahp);
03610             if (!hp) {
03611                ast_log(LOG_WARNING, "Unable to lookup host in secondary c= line, '%s'\n", c);
03612             }
03613          }
03614       }
03615    }
03616    /* Setup video port number */
03617    sin.sin_port = htons(vportno);
03618    if (p->vrtp && sin.sin_port) {
03619       ast_rtp_set_peer(p->vrtp, &sin);
03620       if (debug) {
03621          ast_verbose("Peer video RTP is at port %s:%d\n", ast_inet_ntoa(iabuf,sizeof(iabuf), sin.sin_addr), ntohs(sin.sin_port));
03622          ast_log(LOG_DEBUG,"Peer video RTP is at port %s:%d\n",ast_inet_ntoa(iabuf, sizeof(iabuf), sin.sin_addr), ntohs(sin.sin_port));
03623       }
03624    }
03625 
03626    /* Next, scan through each "a=rtpmap:" line, noting each
03627     * specified RTP payload type (with corresponding MIME subtype):
03628     */
03629    sdpLineNum_iterator_init(&iterator, req);
03630    while ((a = get_sdp_iterate(&iterator, req, "a"))[0] != '\0') {
03631       char* mimeSubtype = ast_strdupa(a); /* ensures we have enough space */
03632       if (!strcasecmp(a, "sendonly") || !strcasecmp(a, "inactive")) {
03633          sendonly = 1;
03634          continue;
03635       }
03636       if (!strcasecmp(a, "sendrecv")) {
03637          sendonly = 0;
03638       }
03639       if (sscanf(a, "rtpmap: %u %[^/]/", &codec, mimeSubtype) != 2) continue;
03640       if (debug)
03641          ast_verbose("Found description format %s\n", mimeSubtype);
03642       /* Note: should really look at the 'freq' and '#chans' params too */
03643       ast_rtp_set_rtpmap_type(p->rtp, codec, "audio", mimeSubtype);
03644       if (p->vrtp)
03645          ast_rtp_set_rtpmap_type(p->vrtp, codec, "video", mimeSubtype);
03646    }
03647 
03648    /* Now gather all of the codecs that were asked for: */
03649    ast_rtp_get_current_formats(p->rtp,
03650             &peercapability, &peernoncodeccapability);
03651    if (p->vrtp)
03652       ast_rtp_get_current_formats(p->vrtp,
03653             &vpeercapability, &vpeernoncodeccapability);
03654    p->jointcapability = p->capability & (peercapability | vpeercapability);
03655    p->peercapability = (peercapability | vpeercapability);
03656    p->noncodeccapability = noncodeccapability & peernoncodeccapability;
03657    
03658    if (ast_test_flag(p, SIP_DTMF) == SIP_DTMF_AUTO) {
03659       ast_clear_flag(p, SIP_DTMF);
03660       if (p->noncodeccapability & AST_RTP_DTMF) {
03661          /* XXX Would it be reasonable to drop the DSP at this point? XXX */
03662          ast_set_flag(p, SIP_DTMF_RFC2833);
03663       } else {
03664          ast_set_flag(p, SIP_DTMF_INBAND);
03665       }
03666    }
03667    
03668    if (debug) {
03669       /* shame on whoever coded this.... */
03670       const unsigned slen=512;
03671       char s1[slen], s2[slen], s3[slen], s4[slen];
03672 
03673       ast_verbose("Capabilities: us - %s, peer - audio=%s/video=%s, combined - %s\n",
03674          ast_getformatname_multiple(s1, slen, p->capability),
03675          ast_getformatname_multiple(s2, slen, peercapability),
03676          ast_getformatname_multiple(s3, slen, vpeercapability),
03677          ast_getformatname_multiple(s4, slen, p->jointcapability));
03678 
03679       ast_verbose("Non-codec capabilities: us - %s, peer - %s, combined - %s\n",
03680          ast_rtp_lookup_mime_multiple(s1, slen, noncodeccapability, 0),
03681          ast_rtp_lookup_mime_multiple(s2, slen, peernoncodeccapability, 0),
03682          ast_rtp_lookup_mime_multiple(s3, slen, p->noncodeccapability, 0));
03683    }
03684    if (!p->jointcapability) {
03685       ast_log(LOG_NOTICE, "No compatible codecs!\n");
03686       return -1;
03687    }
03688 
03689    if (!p->owner)    /* There's no open channel owning us */
03690       return 0;
03691 
03692    if (!(p->owner->nativeformats & p->jointcapability)) {
03693       const unsigned slen=512;
03694       char s1[slen], s2[slen];
03695       ast_log(LOG_DEBUG, "Oooh, we need to change our formats since our peer supports only %s and not %s\n", 
03696             ast_getformatname_multiple(s1, slen, p->jointcapability),
03697             ast_getformatname_multiple(s2, slen, p->owner->nativeformats));
03698       p->owner->nativeformats = ast_codec_choose(&p->prefs, p->jointcapability, 1);
03699       ast_set_read_format(p->owner, p->owner->readformat);
03700       ast_set_write_format(p->owner, p->owner->writeformat);
03701    }
03702    if ((bridgepeer=ast_bridged_channel(p->owner))) {
03703       /* We have a bridge */
03704       /* Turn on/off music on hold if we are holding/unholding */
03705       struct ast_frame af = { AST_FRAME_NULL, };
03706       if (sin.sin_addr.s_addr && !sendonly) {
03707          ast_moh_stop(bridgepeer);
03708       
03709          /* Activate a re-invite */
03710          ast_queue_frame(p->owner, &af);
03711       } else {
03712          /* No address for RTP, we're on hold */
03713          
03714          ast_moh_start(bridgepeer, NULL);
03715          if (sendonly)
03716             ast_rtp_stop(p->rtp);
03717          /* Activate a re-invite */
03718          ast_queue_frame(p->owner, &af);
03719       }
03720    }
03721 
03722    /* Manager Hold and Unhold events must be generated, if necessary */
03723    if (sin.sin_addr.s_addr && !sendonly) {           
03724            append_history(p, "Unhold", req->data);
03725 
03726       if (callevents && ast_test_flag(p, SIP_CALL_ONHOLD)) {
03727          manager_event(EVENT_FLAG_CALL, "Unhold",
03728             "Channel: %s\r\n"
03729             "Uniqueid: %s\r\n",
03730             p->owner->name, 
03731             p->owner->uniqueid);
03732 
03733             }
03734       ast_clear_flag(p, SIP_CALL_ONHOLD);
03735    } else {         
03736       /* No address for RTP, we're on hold */
03737            append_history(p, "Hold", req->data);
03738 
03739            if (callevents && !ast_test_flag(p, SIP_CALL_ONHOLD)) {
03740          manager_event(EVENT_FLAG_CALL, "Hold",
03741             "Channel: %s\r\n"
03742                   "Uniqueid: %s\r\n",
03743             p->owner->name, 
03744             p->owner->uniqueid);
03745       }
03746       ast_set_flag(p, SIP_CALL_ONHOLD);
03747    }
03748 
03749    return 0;
03750 }

static struct sip_peer* realtime_peer const char *  peername,
struct sockaddr_in *  sin
[static]
 

realtime_peer: Get peer from realtime storage Checks the "sippeers" realtime family from extconfig.conf

Definition at line 1677 of file chan_sip.c.

References ast_copy_flags, ast_inet_ntoa(), ast_load_realtime(), ast_log(), ast_sched_add(), ast_sched_del(), ast_set_flag, ast_test_flag, ast_variables_destroy(), ASTOBJ_CONTAINER_LINK, build_peer(), sip_peer::expire, expire_register(), sip_peer::flags_page2, global_rtautoclear, LOG_WARNING, ast_variable::name, ast_variable::next, peerl, SIP_PAGE2_RTAUTOCLEAR, SIP_PAGE2_RTCACHEFRIENDS, SIP_REALTIME, ast_variable::value, and var.

01678 {
01679    struct sip_peer *peer=NULL;
01680    struct ast_variable *var;
01681    struct ast_variable *tmp;
01682    char *newpeername = (char *) peername;
01683    char iabuf[80];
01684 
01685    /* First check on peer name */
01686    if (newpeername) 
01687       var = ast_load_realtime("sippeers", "name", peername, NULL);
01688    else if (sin) {   /* Then check on IP address */
01689       ast_inet_ntoa(iabuf, sizeof(iabuf), sin->sin_addr);
01690       var = ast_load_realtime("sippeers", "host", iabuf, NULL);   /* First check for fixed IP hosts */
01691       if (!var)
01692          var = ast_load_realtime("sippeers", "ipaddr", iabuf, NULL); /* Then check for registred hosts */
01693    
01694    } else
01695       return NULL;
01696 
01697    if (!var)
01698       return NULL;
01699 
01700    tmp = var;
01701    /* If this is type=user, then skip this object. */
01702    while(tmp) {
01703       if (!strcasecmp(tmp->name, "type") &&
01704           !strcasecmp(tmp->value, "user")) {
01705          ast_variables_destroy(var);
01706          return NULL;
01707       } else if (!newpeername && !strcasecmp(tmp->name, "name")) {
01708          newpeername = tmp->value;
01709       }
01710       tmp = tmp->next;
01711    }
01712    
01713    if (!newpeername) {  /* Did not find peer in realtime */
01714       ast_log(LOG_WARNING, "Cannot Determine peer name ip=%s\n", iabuf);
01715       ast_variables_destroy(var);
01716       return (struct sip_peer *) NULL;
01717    }
01718 
01719    /* Peer found in realtime, now build it in memory */
01720    peer = build_peer(newpeername, var, !ast_test_flag((&global_flags_page2), SIP_PAGE2_RTCACHEFRIENDS));
01721    if (!peer) {
01722       ast_variables_destroy(var);
01723       return (struct sip_peer *) NULL;
01724    }
01725 
01726    if (ast_test_flag((&global_flags_page2), SIP_PAGE2_RTCACHEFRIENDS)) {
01727       /* Cache peer */
01728       ast_copy_flags((&peer->flags_page2),(&global_flags_page2), SIP_PAGE2_RTAUTOCLEAR|SIP_PAGE2_RTCACHEFRIENDS);
01729       if (ast_test_flag((&global_flags_page2), SIP_PAGE2_RTAUTOCLEAR)) {
01730          if (peer->expire > -1) {
01731             ast_sched_del(sched, peer->expire);
01732          }
01733          peer->expire = ast_sched_add(sched, (global_rtautoclear) * 1000, expire_register, (void *)peer);
01734       }
01735       ASTOBJ_CONTAINER_LINK(&peerl,peer);
01736    } else {
01737       ast_set_flag(peer, SIP_REALTIME);
01738    }
01739    ast_variables_destroy(var);
01740 
01741    return peer;
01742 }

static void realtime_update_peer const char *  peername,
struct sockaddr_in *  sin,
const char *  username,
const char *  fullcontact,
int  expirey
[static]
 

realtime_update_peer: Update peer object in realtime storage ---

Definition at line 1599 of file chan_sip.c.

References ast_inet_ntoa(), ast_update_realtime(), and ipaddr.

01600 {
01601    char port[10];
01602    char ipaddr[20];
01603    char regseconds[20];
01604    time_t nowtime;
01605    
01606    time(&nowtime);
01607    nowtime += expirey;
01608    snprintf(regseconds, sizeof(regseconds), "%d", (int)nowtime);  /* Expiration time */
01609    ast_inet_ntoa(ipaddr, sizeof(ipaddr), sin->sin_addr);
01610    snprintf(port, sizeof(port), "%d", ntohs(sin->sin_port));
01611    
01612    if (fullcontact)
01613       ast_update_realtime("sippeers", "name", peername, "ipaddr", ipaddr, "port", port, "regseconds", regseconds, "username", username, "fullcontact", fullcontact, NULL);
01614    else
01615       ast_update_realtime("sippeers", "name", peername, "ipaddr", ipaddr, "port", port, "regseconds", regseconds, "username", username, NULL);
01616 }

static struct sip_user* realtime_user const char *  username  )  [static]
 

realtime_user: Load user from realtime storage Loads user from "sipusers" category in realtime (extconfig.conf) Users are matched on From: user name (the domain in skipped)

Definition at line 1791 of file chan_sip.c.

References ast_load_realtime(), ast_set_flag, ast_test_flag, ast_variables_destroy(), ASTOBJ_CONTAINER_LINK, build_user(), sip_user::flags_page2, ruserobjs, SIP_PAGE2_RTCACHEFRIENDS, SIP_REALTIME, suserobjs, user, userl, and var.

01792 {
01793    struct ast_variable *var;
01794    struct ast_variable *tmp;
01795    struct sip_user *user = NULL;
01796 
01797    var = ast_load_realtime("sipusers", "name", username, NULL);
01798 
01799    if (!var)
01800       return NULL;
01801 
01802    tmp = var;
01803    while (tmp) {
01804       if (!strcasecmp(tmp->name, "type") &&
01805          !strcasecmp(tmp->value, "peer")) {
01806          ast_variables_destroy(var);
01807          return NULL;
01808       }
01809       tmp = tmp->next;
01810    }
01811    
01812 
01813 
01814    user = build_user(username, var, !ast_test_flag((&global_flags_page2), SIP_PAGE2_RTCACHEFRIENDS));
01815    
01816    if (!user) {   /* No user found */
01817       ast_variables_destroy(var);
01818       return NULL;
01819    }
01820 
01821    if (ast_test_flag((&global_flags_page2), SIP_PAGE2_RTCACHEFRIENDS)) {
01822       ast_set_flag((&user->flags_page2), SIP_PAGE2_RTCACHEFRIENDS);
01823       suserobjs++;
01824       ASTOBJ_CONTAINER_LINK(&userl,user);
01825    } else {
01826       /* Move counter from s to r... */
01827       suserobjs--;
01828       ruserobjs++;
01829       ast_set_flag(user, SIP_REALTIME);
01830    }
01831    ast_variables_destroy(var);
01832    return user;
01833 }

static void receive_message struct sip_pvt p,
struct sip_request req
[static]
 

receive_message: Receive SIP MESSAGE method messages ---

Definition at line 7360 of file chan_sip.c.

References AST_FRAME_TEXT, ast_log(), ast_queue_frame(), ast_set_flag, ast_verbose(), sip_pvt::callid, get_header(), get_msg_text(), LOG_WARNING, sip_pvt::owner, sip_debug_test_pvt(), SIP_NEEDDESTROY, and transmit_response().

Referenced by handle_request_message().

07361 {
07362    char buf[1024];
07363    struct ast_frame f;
07364    char *content_type;
07365 
07366    content_type = get_header(req, "Content-Type");
07367    if (strcmp(content_type, "text/plain")) { /* No text/plain attachment */
07368       transmit_response(p, "415 Unsupported Media Type", req); /* Good enough, or? */
07369       ast_set_flag(p, SIP_NEEDDESTROY);
07370       return;
07371    }
07372 
07373    if (get_msg_text(buf, sizeof(buf), req)) {
07374       ast_log(LOG_WARNING, "Unable to retrieve text from %s\n", p->callid);
07375       transmit_response(p, "202 Accepted", req);
07376       ast_set_flag(p, SIP_NEEDDESTROY);
07377       return;
07378    }
07379 
07380    if (p->owner) {
07381       if (sip_debug_test_pvt(p))
07382          ast_verbose("Message received: '%s'\n", buf);
07383       memset(&f, 0, sizeof(f));
07384       f.frametype = AST_FRAME_TEXT;
07385       f.subclass = 0;
07386       f.offset = 0;
07387       f.data = buf;
07388       f.datalen = strlen(buf);
07389       ast_queue_frame(p->owner, &f);
07390       transmit_response(p, "202 Accepted", req); /* We respond 202 accepted, since we relay the message */
07391    } else { /* Message outside of a call, we do not support that */
07392       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);
07393       transmit_response(p, "405 Method Not Allowed", req); /* Good enough, or? */
07394    }
07395    ast_set_flag(p, SIP_NEEDDESTROY);
07396    return;
07397 }

static void reg_source_db struct sip_peer peer  )  [static]
 

reg_source_db: Get registration details from Asterisk DB ---

Definition at line 5752 of file chan_sip.c.

References sip_peer::addr, ast_db_get(), ast_inet_ntoa(), ast_sched_add(), ast_sched_del(), ast_test_flag, ast_verbose(), sip_peer::expire, expire_register(), expiry, sip_peer::flags_page2, sip_peer::fullcontact, option_verbose, sip_peer::pokeexpire, register_peer_exten(), SIP_PAGE2_RT_FROMCONTACT, sip_poke_peer(), sip_poke_peer_s(), sipsock, strsep(), thread_safe_rand(), sip_peer::username, username, and VERBOSE_PREFIX_3.

05753 {
05754    char data[256];
05755    char iabuf[INET_ADDRSTRLEN];
05756    struct in_addr in;
05757    int expiry;
05758    int port;
05759    char *scan, *addr, *port_str, *expiry_str, *username, *contact;
05760 
05761    if (ast_test_flag(&(peer->flags_page2), SIP_PAGE2_RT_FROMCONTACT)) 
05762       return;
05763    if (ast_db_get("SIP/Registry", peer->name, data, sizeof(data)))
05764       return;
05765 
05766    scan = data;
05767    addr = strsep(&scan, ":");
05768    port_str = strsep(&scan, ":");
05769    expiry_str = strsep(&scan, ":");
05770    username = strsep(&scan, ":");
05771    contact = scan;   /* Contact include sip: and has to be the last part of the database entry as long as we use : as a separator */
05772 
05773    if (!inet_aton(addr, &in))
05774       return;
05775 
05776    if (port_str)
05777       port = atoi(port_str);
05778    else
05779       return;
05780 
05781    if (expiry_str)
05782       expiry = atoi(expiry_str);
05783    else
05784       return;
05785 
05786    if (username)
05787       ast_copy_string(peer->username, username, sizeof(peer->username));
05788    if (contact)
05789       ast_copy_string(peer->fullcontact, contact, sizeof(peer->fullcontact));
05790 
05791    if (option_verbose > 2)
05792       ast_verbose(VERBOSE_PREFIX_3 "SIP Seeding peer from astdb: '%s' at %s@%s:%d for %d\n",
05793              peer->name, peer->username, ast_inet_ntoa(iabuf, sizeof(iabuf), in), port, expiry);
05794 
05795    memset(&peer->addr, 0, sizeof(peer->addr));
05796    peer->addr.sin_family = AF_INET;
05797    peer->addr.sin_addr = in;
05798    peer->addr.sin_port = htons(port);
05799    if (sipsock < 0) {
05800       /* SIP isn't up yet, so schedule a poke only, pretty soon */
05801       if (peer->pokeexpire > -1)
05802          ast_sched_del(sched, peer->pokeexpire);
05803       peer->pokeexpire = ast_sched_add(sched, thread_safe_rand() % 5000 + 1, sip_poke_peer_s, peer);
05804    } else
05805       sip_poke_peer(peer);
05806    if (peer->expire > -1)
05807       ast_sched_del(sched, peer->expire);
05808    peer->expire = ast_sched_add(sched, (expiry + 10) * 1000, expire_register, peer);
05809    register_peer_exten(peer, 1);
05810 }

static void register_peer_exten struct sip_peer peer,
int  onoff
[static]
 

register_peer_exten: Automatically add peer extension to dial plan ---

Definition at line 1619 of file chan_sip.c.

References ast_add_extension(), ast_context_remove_extension(), ast_strlen_zero(), channeltype, free, regcontext, sip_peer::regexten, strdup, and strsep().

01620 {
01621    char multi[256];
01622    char *stringp, *ext;
01623    if (!ast_strlen_zero(regcontext)) {
01624       ast_copy_string(multi, ast_strlen_zero(peer->regexten) ? peer->name : peer->regexten, sizeof(multi));
01625       stringp = multi;
01626       while((ext = strsep(&stringp, "&"))) {
01627          if (onoff)
01628             ast_add_extension(regcontext, 1, ext, 1, NULL, NULL, "Noop", strdup(peer->name), free, channeltype);
01629          else
01630             ast_context_remove_extension(regcontext, ext, 1, NULL);
01631       }
01632    }
01633 }

static int register_verify struct sip_pvt p,
struct sockaddr_in *  sin,
struct sip_request req,
char *  uri,
int  ignore
[static]
 

register_verify: Verify registration of user

Definition at line 6444 of file chan_sip.c.

References ast_apply_ha(), ast_copy_flags, ast_device_state_changed(), ast_inet_ntoa(), AST_LIST_EMPTY, ast_log(), ast_test_flag, ast_uri_decode(), ASTOBJ_CONTAINER_LINK, ASTOBJ_UNREF, autocreatepeer, build_contact(), check_auth(), check_sip_domain(), EVENT_FLAG_SYSTEM, sip_pvt::exten, find_peer(), sip_peer::flags_page2, get_header(), get_in_brackets(), global_alwaysauthreject, sip_peer::ha, sip_pvt::initreq, sip_peer::lastmsgssent, LOG_DEBUG, LOG_ERROR, LOG_NOTICE, LOG_WARNING, manager_event(), sip_peer::md5secret, name, option_debug, parse_register_contact(), PARSE_REGISTER_FAILED, PARSE_REGISTER_QUERY, PARSE_REGISTER_UPDATE, pedanticsipchecking, peerl, sip_pvt::randdata, sip_peer::secret, sip_cancel_destroy(), sip_destroy_peer(), SIP_NAT, SIP_PAGE2_DYNAMIC, SIP_REGISTER, t, temp_peer(), transmit_fake_auth_response(), transmit_response(), transmit_response_with_date(), and update_peer().

06445 {
06446    int res = -3;
06447    struct sip_peer *peer;
06448    char tmp[256];
06449    char iabuf[INET_ADDRSTRLEN];
06450    char *name, *c;
06451    char *t;
06452    char *domain;
06453 
06454    /* Terminate URI */
06455    t = uri;
06456    while(*t && (*t > 32) && (*t != ';'))
06457       t++;
06458    *t = '\0';
06459    
06460    ast_copy_string(tmp, get_header(req, "To"), sizeof(tmp));
06461    if (pedanticsipchecking)
06462       ast_uri_decode(tmp);
06463 
06464    c = get_in_brackets(tmp);
06465    /* Ditch ;user=phone */
06466    name = strchr(c, ';');
06467    if (name)
06468       *name = '\0';
06469 
06470    if (!strncmp(c, "sip:", 4)) {
06471       name = c + 4;
06472    } else {
06473       name = c;
06474       ast_log(LOG_NOTICE, "Invalid to address: '%s' from %s (missing sip:) trying to use anyway...\n", c, ast_inet_ntoa(iabuf, sizeof(iabuf), sin->sin_addr));
06475    }
06476 
06477    /* Strip off the domain name */
06478    if ((c = strchr(name, '@'))) {
06479       *c++ = '\0';
06480       domain = c;
06481       if ((c = strchr(domain, ':')))   /* Remove :port */
06482          *c = '\0';
06483       if (!AST_LIST_EMPTY(&domain_list)) {
06484          if (!check_sip_domain(domain, NULL, 0)) {
06485             transmit_response(p, "404 Not found (unknown domain)", &p->initreq);
06486             return -3;
06487          }
06488       }
06489    }
06490 
06491    ast_copy_string(p->exten, name, sizeof(p->exten));
06492    build_contact(p);
06493    peer = find_peer(name, NULL, 1);
06494    if (!(peer && ast_apply_ha(peer->ha, sin))) {
06495       if (peer)
06496          ASTOBJ_UNREF(peer,sip_destroy_peer);
06497    }
06498    if (peer) {
06499       if (!ast_test_flag(&peer->flags_page2, SIP_PAGE2_DYNAMIC)) {
06500          ast_log(LOG_ERROR, "Peer '%s' is trying to register, but not configured as host=dynamic\n", peer->name);
06501       } else {
06502          ast_copy_flags(p, peer, SIP_NAT);
06503          transmit_response(p, "100 Trying", req);
06504          if (!(res = check_auth(p, req, p->randdata, sizeof(p->randdata), peer->name, peer->secret, peer->md5secret, SIP_REGISTER, uri, 0, ignore))) {
06505             sip_cancel_destroy(p);
06506             switch (parse_register_contact(p, peer, req)) {
06507             case PARSE_REGISTER_FAILED:
06508                ast_log(LOG_WARNING, "Failed to parse contact info\n");
06509                transmit_response_with_date(p, "400 Bad Request", req);
06510                peer->lastmsgssent = -1;
06511                res = 0;
06512                break;
06513             case PARSE_REGISTER_QUERY:
06514                transmit_response_with_date(p, "200 OK", req);
06515                peer->lastmsgssent = -1;
06516                res = 0;
06517                break;
06518             case PARSE_REGISTER_UPDATE:
06519                update_peer(peer, p->expiry);
06520                /* Say OK and ask subsystem to retransmit msg counter */
06521                transmit_response_with_date(p, "200 OK", req);
06522                peer->lastmsgssent = -1;
06523                res = 0;
06524                break;
06525             }
06526          } 
06527       }
06528    }
06529    if (!peer && autocreatepeer) {
06530       /* Create peer if we have autocreate mode enabled */
06531       peer = temp_peer(name);
06532       if (peer) {
06533          ASTOBJ_CONTAINER_LINK(&peerl, peer);
06534          sip_cancel_destroy(p);
06535          switch (parse_register_contact(p, peer, req)) {
06536          case PARSE_REGISTER_FAILED:
06537             ast_log(LOG_WARNING, "Failed to parse contact info\n");
06538             transmit_response_with_date(p, "400 Bad Request", req);
06539             peer->lastmsgssent = -1;
06540             res = 0;
06541             break;
06542          case PARSE_REGISTER_QUERY:
06543             transmit_response_with_date(p, "200 OK", req);
06544             peer->lastmsgssent = -1;
06545             res = 0;
06546             break;
06547          case PARSE_REGISTER_UPDATE:
06548             /* Say OK and ask subsystem to retransmit msg counter */
06549             transmit_response_with_date(p, "200 OK", req);
06550             manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: SIP/%s\r\nPeerStatus: Registered\r\n", peer->name);
06551             peer->lastmsgssent = -1;
06552             res = 0;
06553             break;
06554          }
06555       }
06556    }
06557    if (!res) {
06558       ast_device_state_changed("SIP/%s", peer->name);
06559    }
06560    if (res < 0) {
06561       switch (res) {
06562       case -1:
06563          /* Wrong password in authentication. Go away, don't try again until you fixed it */
06564          transmit_response(p, "403 Forbidden (Bad auth)", &p->initreq);
06565          break;
06566       case -2:
06567          /* Username and digest username does not match. 
06568             Asterisk uses the From: username for authentication. We need the
06569             users to use the same authentication user name until we support
06570             proper authentication by digest auth name */
06571          transmit_response(p, "403 Authentication user name does not match account name", &p->initreq);
06572          break;
06573       case -3:
06574          if (global_alwaysauthreject) {
06575             transmit_fake_auth_response(p, &p->initreq, p->randdata, sizeof(p->randdata), 1);
06576          } else {
06577             /* URI not found */
06578             transmit_response(p, "404 Not found", &p->initreq);
06579          }
06580          /* Set res back to -2 because we don't want to return an invalid domain message. That check already happened up above. */
06581          res = -2;
06582          break;
06583       }
06584       if (option_debug > 1) {
06585          ast_log(LOG_DEBUG, "SIP REGISTER attempt failed for %s : %s\n",
06586             peer->name,
06587             (res == -1) ? "Bad password" : ((res == -2 ) ? "Bad digest user" : "Peer not found"));
06588       }
06589    }
06590    if (peer)
06591       ASTOBJ_UNREF(peer,sip_destroy_peer);
06592 
06593    return res;
06594 }

static char* regstate2str int  regstate  )  [static]
 

Definition at line 5292 of file chan_sip.c.

References REG_STATE_AUTHSENT, REG_STATE_FAILED, REG_STATE_NOAUTH, REG_STATE_REGISTERED, REG_STATE_REGSENT, REG_STATE_REJECTED, REG_STATE_TIMEOUT, and REG_STATE_UNREGISTERED.

05293 {
05294    switch(regstate) {
05295    case REG_STATE_FAILED:
05296       return "Failed";
05297    case REG_STATE_UNREGISTERED:
05298       return "Unregistered";
05299    case REG_STATE_REGSENT:
05300       return "Request Sent";
05301    case REG_STATE_AUTHSENT:
05302       return "Auth. Sent";
05303    case REG_STATE_REGISTERED:
05304       return "Registered";
05305    case REG_STATE_REJECTED:
05306       return "Rejected";
05307    case REG_STATE_TIMEOUT:
05308       return "Timeout";
05309    case REG_STATE_NOAUTH:
05310       return "No Authentication";
05311    default:
05312       return "Unknown";
05313    }
05314 }

int reload void   ) 
 

Reload stuff.

This function is where any reload routines take place. Re-read config files, change signalling, whatever is appropriate on a reload.

Returns:
The return value is not used.

Definition at line 13280 of file chan_sip.c.

References sip_reload().

13281 {
13282    return sip_reload(0, 0, NULL);
13283 }

static int reload_config void   )  [static]
 

reload_config: Re-read SIP.conf config file ---

Definition at line 12467 of file chan_sip.c.

References __ourip, add_realm_authentication(), add_sip_domain(), allow_external_domains, ast_append_ha(), ast_category_browse(), ast_clear_flag, ast_config_destroy(), ast_config_load(), ast_context_create(), ast_context_find(), ast_find_ourip(), AST_FLAGS_ALL, ast_get_ip_or_srv(), ast_gethostbyname(), ast_inet_ntoa(), AST_LIST_EMPTY, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_parse_allow_disallow(), ast_set2_flag, ast_set_flag, ast_str2tos(), ast_strdupa, ast_strlen_zero(), ast_true(), ast_variable_browse(), ast_variable_retrieve(), ast_verbose(), ASTOBJ_CONTAINER_LINK, ASTOBJ_UNREF, authl, autocreatepeer, bindaddr, build_peer(), build_user(), callevents, cfg, channeltype, compactheaders, config, context, DEFAULT_CALLERID, default_callerid, DEFAULT_CONTEXT, default_context, DEFAULT_DEFAULT_EXPIRY, default_expiry, DEFAULT_EXPIRY, default_fromdomain, default_language, DEFAULT_MAX_EXPIRY, DEFAULT_MAXMS, DEFAULT_MWITIME, DEFAULT_NOTIFYMIME, default_notifymime, default_qualify, DEFAULT_REALM, DEFAULT_REGISTRATION_TIMEOUT, DEFAULT_SIP_PORT, default_subscribecontext, DEFAULT_USERAGENT, default_useragent, DEFAULT_VMEXTEN, dumphistory, expiry, externexpire, externhost, externip, externrefresh, format, global_allowguest, global_alwaysauthreject, global_capability, global_musicclass, global_mwitime, global_notifyringing, global_realm, global_reg_timeout, global_regattempts_max, global_rtautoclear, global_rtpholdtimeout, global_rtpkeepalive, global_rtptimeout, global_vmexten, handle_common_options(), hp, ast_variable::lineno, localaddr, LOG_DEBUG, LOG_NOTICE, LOG_WARNING, max_expiry, ast_variable::name, ast_variable::next, notify_config, notify_types, option_debug, option_verbose, ourport, outboundproxyip, pedanticsipchecking, peerl, recordhistory, regcontext, relaxdtmf, SIP_CAN_REINVITE, SIP_DEBUG_CONFIG, sip_destroy_peer(), sip_destroy_user(), SIP_DOMAIN_AUTO, SIP_DOMAIN_CONFIG, SIP_DTMF_RFC2833, SIP_NAT_RFC3581, SIP_PAGE2_IGNOREREGEXPIRE, SIP_PAGE2_RTAUTOCLEAR, SIP_PAGE2_RTCACHEFRIENDS, SIP_PAGE2_RTUPDATE, sip_register(), SIP_USEREQPHONE, sipdebug, sipsock, srvlookup, tos, user, userl, ast_variable::value, VERBOSE_PREFIX_2, and videosupport.

12468 {
12469    struct ast_config *cfg;
12470    struct ast_variable *v;
12471    struct sip_peer *peer;
12472    struct sip_user *user;
12473    struct ast_hostent ahp;
12474    char *cat;
12475    char *utype;
12476    struct hostent *hp;
12477    int format;
12478    char iabuf[INET_ADDRSTRLEN];
12479    struct ast_flags dummy;
12480    int auto_sip_domains = 0;
12481    struct sockaddr_in old_bindaddr = bindaddr;
12482 
12483    cfg = ast_config_load(config);
12484 
12485    /* We *must* have a config file otherwise stop immediately */
12486    if (!cfg) {
12487       ast_log(LOG_NOTICE, "Unable to load config %s\n", config);
12488       return -1;
12489    }
12490    
12491    /* Reset IP addresses  */
12492    memset(&bindaddr, 0, sizeof(bindaddr));
12493    memset(&localaddr, 0, sizeof(localaddr));
12494    memset(&externip, 0, sizeof(externip));
12495    memset(&prefs, 0 , sizeof(prefs));
12496    sipdebug &= ~SIP_DEBUG_CONFIG;
12497 
12498    /* Initialize some reasonable defaults at SIP reload */
12499    ast_copy_string(default_context, DEFAULT_CONTEXT, sizeof(default_context));
12500    default_subscribecontext[0] = '\0';
12501    default_language[0] = '\0';
12502    default_fromdomain[0] = '\0';
12503    default_qualify = 0;
12504    allow_external_domains = 1;   /* Allow external invites */
12505    externhost[0] = '\0';
12506    externexpire = 0;
12507    externrefresh = 10;
12508    ast_copy_string(default_useragent, DEFAULT_USERAGENT, sizeof(default_useragent));
12509    ast_copy_string(default_notifymime, DEFAULT_NOTIFYMIME, sizeof(default_notifymime));
12510    global_notifyringing = 1;
12511    global_alwaysauthreject = 0;
12512    ast_copy_string(global_realm, DEFAULT_REALM, sizeof(global_realm));
12513    ast_copy_string(global_musicclass, "default", sizeof(global_musicclass));
12514    ast_copy_string(default_callerid, DEFAULT_CALLERID, sizeof(default_callerid));
12515    memset(&outboundproxyip, 0, sizeof(outboundproxyip));
12516    outboundproxyip.sin_port = htons(DEFAULT_SIP_PORT);
12517    outboundproxyip.sin_family = AF_INET;  /* Type of address: IPv4 */
12518    videosupport = 0;
12519    compactheaders = 0;
12520    dumphistory = 0;
12521    recordhistory = 0;
12522    relaxdtmf = 0;
12523    callevents = 0;
12524    ourport = DEFAULT_SIP_PORT;
12525    global_rtptimeout = 0;
12526    global_rtpholdtimeout = 0;
12527    global_rtpkeepalive = 0;
12528    global_rtautoclear = 120;
12529    pedanticsipchecking = 0;
12530    global_reg_timeout = DEFAULT_REGISTRATION_TIMEOUT;
12531    global_regattempts_max = 0;
12532    ast_clear_flag(&global_flags, AST_FLAGS_ALL);
12533    ast_clear_flag(&global_flags_page2, AST_FLAGS_ALL);
12534    ast_set_flag(&global_flags, SIP_DTMF_RFC2833);
12535    ast_set_flag(&global_flags, SIP_NAT_RFC3581);
12536    ast_set_flag(&global_flags, SIP_CAN_REINVITE);
12537    ast_set_flag(&global_flags_page2, SIP_PAGE2_RTUPDATE);
12538    global_mwitime = DEFAULT_MWITIME;
12539    strcpy(global_vmexten, DEFAULT_VMEXTEN);
12540    srvlookup = 0;
12541    autocreatepeer = 0;
12542    regcontext[0] = '\0';
12543    tos = 0;
12544    expiry = DEFAULT_EXPIRY;
12545    global_allowguest = 1;
12546 
12547    /* Read the [general] config section of sip.conf (or from realtime config) */
12548    v = ast_variable_browse(cfg, "general");
12549    while(v) {
12550       if (handle_common_options(&global_flags, &dummy, v)) {
12551          v = v->next;
12552          continue;
12553       }
12554 
12555       /* Create the interface list */
12556       if (!strcasecmp(v->name, "context")) {
12557          ast_copy_string(default_context, v->value, sizeof(default_context));
12558       } else if (!strcasecmp(v->name, "realm")) {
12559          ast_copy_string(global_realm, v->value, sizeof(global_realm));
12560       } else if (!strcasecmp(v->name, "useragent")) {
12561          ast_copy_string(default_useragent, v->value, sizeof(default_useragent));
12562          ast_log(LOG_DEBUG, "Setting User Agent Name to %s\n",
12563             default_useragent);
12564       } else if (!strcasecmp(v->name, "rtcachefriends")) {
12565          ast_set2_flag((&global_flags_page2), ast_true(v->value), SIP_PAGE2_RTCACHEFRIENDS); 
12566       } else if (!strcasecmp(v->name, "rtupdate")) {
12567          ast_set2_flag((&global_flags_page2), ast_true(v->value), SIP_PAGE2_RTUPDATE); 
12568       } else if (!strcasecmp(v->name, "ignoreregexpire")) {
12569          ast_set2_flag((&global_flags_page2), ast_true(v->value), SIP_PAGE2_IGNOREREGEXPIRE);   
12570       } else if (!strcasecmp(v->name, "rtautoclear")) {
12571          int i = atoi(v->value);
12572          if (i > 0)
12573             global_rtautoclear = i;
12574          else
12575             i = 0;
12576          ast_set2_flag((&global_flags_page2), i || ast_true(v->value), SIP_PAGE2_RTAUTOCLEAR);
12577       } else if (!strcasecmp(v->name, "usereqphone")) {
12578          ast_set2_flag((&global_flags), ast_true(v->value), SIP_USEREQPHONE); 
12579       } else if (!strcasecmp(v->name, "relaxdtmf")) {
12580          relaxdtmf = ast_true(v->value);
12581       } else if (!strcasecmp(v->name, "checkmwi")) {
12582          if ((sscanf(v->value, "%d", &global_mwitime) != 1) || (global_mwitime < 0)) {
12583             ast_log(LOG_WARNING, "'%s' is not a valid MWI time setting at line %d.  Using default (10).\n", v->value, v->lineno);
12584             global_mwitime = DEFAULT_MWITIME;
12585          }
12586       } else if (!strcasecmp(v->name, "vmexten")) {
12587          ast_copy_string(global_vmexten, v->value, sizeof(global_vmexten));
12588       } else if (!strcasecmp(v->name, "rtptimeout")) {
12589          if ((sscanf(v->value, "%d", &global_rtptimeout) != 1) || (global_rtptimeout < 0)) {
12590             ast_log(LOG_WARNING, "'%s' is not a valid RTP hold time at line %d.  Using default.\n", v->value, v->lineno);
12591             global_rtptimeout = 0;
12592          }
12593       } else if (!strcasecmp(v->name, "rtpholdtimeout")) {
12594          if ((sscanf(v->value, "%d", &global_rtpholdtimeout) != 1) || (global_rtpholdtimeout < 0)) {
12595             ast_log(LOG_WARNING, "'%s' is not a valid RTP hold time at line %d.  Using default.\n", v->value, v->lineno);
12596             global_rtpholdtimeout = 0;
12597          }
12598       } else if (!strcasecmp(v->name, "rtpkeepalive")) {
12599          if ((sscanf(v->value, "%d", &global_rtpkeepalive) != 1) || (global_rtpkeepalive < 0)) {
12600             ast_log(LOG_WARNING, "'%s' is not a valid RTP keepalive time at line %d.  Using default.\n", v->value, v->lineno);
12601             global_rtpkeepalive = 0;
12602          }
12603       } else if (!strcasecmp(v->name, "videosupport")) {
12604          videosupport = ast_true(v->value);
12605       } else if (!strcasecmp(v->name, "compactheaders")) {
12606          compactheaders = ast_true(v->value);
12607       } else if (!strcasecmp(v->name, "notifymimetype")) {
12608          ast_copy_string(default_notifymime, v->value, sizeof(default_notifymime));
12609       } else if (!strcasecmp(v->name, "notifyringing")) {
12610          global_notifyringing = ast_true(v->value);
12611       } else if (!strcasecmp(v->name, "alwaysauthreject")) {
12612          global_alwaysauthreject = ast_true(v->value);
12613       } else if (!strcasecmp(v->name, "musicclass") || !strcasecmp(v->name, "musiconhold")) {
12614          ast_copy_string(global_musicclass, v->value, sizeof(global_musicclass));
12615       } else if (!strcasecmp(v->name, "language")) {
12616          ast_copy_string(default_language, v->value, sizeof(default_language));
12617       } else if (!strcasecmp(v->name, "regcontext")) {
12618          ast_copy_string(regcontext, v->value, sizeof(regcontext));
12619          /* Create context if it doesn't exist already */
12620          if (!ast_context_find(regcontext))
12621             ast_context_create(NULL, regcontext, channeltype);
12622       } else if (!strcasecmp(v->name, "callerid")) {
12623          ast_copy_string(default_callerid, v->value, sizeof(default_callerid));
12624       } else if (!strcasecmp(v->name, "fromdomain")) {
12625          ast_copy_string(default_fromdomain, v->value, sizeof(default_fromdomain));
12626       } else if (!strcasecmp(v->name, "outboundproxy")) {
12627          if (ast_get_ip_or_srv(&outboundproxyip, v->value, "_sip._udp") < 0)
12628             ast_log(LOG_WARNING, "Unable to locate host '%s'\n", v->value);
12629       } else if (!strcasecmp(v->name, "outboundproxyport")) {
12630          /* Port needs to be after IP */
12631          sscanf(v->value, "%d", &format);
12632          outboundproxyip.sin_port = htons(format);
12633       } else if (!strcasecmp(v->name, "autocreatepeer")) {
12634          autocreatepeer = ast_true(v->value);
12635       } else if (!strcasecmp(v->name, "srvlookup")) {
12636          srvlookup = ast_true(v->value);
12637       } else if (!strcasecmp(v->name, "pedantic")) {
12638          pedanticsipchecking = ast_true(v->value);
12639       } else if (!strcasecmp(v->name, "maxexpirey") || !strcasecmp(v->name, "maxexpiry")) {
12640          max_expiry = atoi(v->value);
12641          if (max_expiry < 1)
12642             max_expiry = DEFAULT_MAX_EXPIRY;
12643       } else if (!strcasecmp(v->name, "defaultexpiry") || !strcasecmp(v->name, "defaultexpirey")) {
12644          default_expiry = atoi(v->value);
12645          if (default_expiry < 1)
12646             default_expiry = DEFAULT_DEFAULT_EXPIRY;
12647       } else if (!strcasecmp(v->name, "sipdebug")) {
12648          if (ast_true(v->value))
12649             sipdebug |= SIP_DEBUG_CONFIG;
12650       } else if (!strcasecmp(v->name, "dumphistory")) {
12651          dumphistory = ast_true(v->value);
12652       } else if (!strcasecmp(v->name, "recordhistory")) {
12653          recordhistory = ast_true(v->value);
12654       } else if (!strcasecmp(v->name, "registertimeout")) {
12655          global_reg_timeout = atoi(v->value);
12656          if (global_reg_timeout < 1)
12657             global_reg_timeout = DEFAULT_REGISTRATION_TIMEOUT;
12658       } else if (!strcasecmp(v->name, "registerattempts")) {
12659          global_regattempts_max = atoi(v->value);
12660       } else if (!strcasecmp(v->name, "bindaddr")) {
12661          if (!(hp = ast_gethostbyname(v->value, &ahp))) {
12662             ast_log(LOG_WARNING, "Invalid address: %s\n", v->value);
12663          } else {
12664             memcpy(&bindaddr.sin_addr, hp->h_addr, sizeof(bindaddr.sin_addr));
12665          }
12666       } else if (!strcasecmp(v->name, "localnet")) {
12667          struct ast_ha *na;
12668          if (!(na = ast_append_ha("d", v->value, localaddr)))
12669             ast_log(LOG_WARNING, "Invalid localnet value: %s\n", v->value);
12670          else
12671             localaddr = na;
12672       } else if (!strcasecmp(v->name, "localmask")) {
12673          ast_log(LOG_WARNING, "Use of localmask is no long supported -- use localnet with mask syntax\n");
12674       } else if (!strcasecmp(v->name, "externip")) {
12675          if (!(hp = ast_gethostbyname(v->value, &ahp))) 
12676             ast_log(LOG_WARNING, "Invalid address for externip keyword: %s\n", v->value);
12677          else
12678             memcpy(&externip.sin_addr, hp->h_addr, sizeof(externip.sin_addr));
12679          externexpire = 0;
12680       } else if (!strcasecmp(v->name, "externhost")) {
12681          ast_copy_string(externhost, v->value, sizeof(externhost));
12682          if (!(hp = ast_gethostbyname(externhost, &ahp))) 
12683             ast_log(LOG_WARNING, "Invalid address for externhost keyword: %s\n", externhost);
12684          else
12685             memcpy(&externip.sin_addr, hp->h_addr, sizeof(externip.sin_addr));
12686          time(&externexpire);
12687       } else if (!strcasecmp(v->name, "externrefresh")) {
12688          if (sscanf(v->value, "%d", &externrefresh) != 1) {
12689             ast_log(LOG_WARNING, "Invalid externrefresh value '%s', must be an integer >0 at line %d\n", v->value, v->lineno);
12690             externrefresh = 10;
12691          }
12692       } else if (!strcasecmp(v->name, "allow")) {
12693          ast_parse_allow_disallow(&prefs, &global_capability, v->value, 1);
12694       } else if (!strcasecmp(v->name, "disallow")) {
12695          ast_parse_allow_disallow(&prefs, &global_capability, v->value, 0);
12696       } else if (!strcasecmp(v->name, "allowexternaldomains")) {
12697          allow_external_domains = ast_true(v->value);
12698       } else if (!strcasecmp(v->name, "autodomain")) {
12699          auto_sip_domains = ast_true(v->value);
12700       } else if (!strcasecmp(v->name, "domain")) {
12701          char *domain = ast_strdupa(v->value);
12702          char *context = strchr(domain, ',');
12703 
12704          if (context)
12705             *context++ = '\0';
12706 
12707          if (option_debug && ast_strlen_zero(context))
12708             ast_log(LOG_DEBUG, "No context specified at line %d for domain '%s'\n", v->lineno, domain);
12709          if (ast_strlen_zero(domain))
12710             ast_log(LOG_WARNING, "Empty domain specified at line %d\n", v->lineno);
12711          else
12712             add_sip_domain(ast_strip(domain), SIP_DOMAIN_CONFIG, context ? ast_strip(context) : "");
12713       } else if (!strcasecmp(v->name, "register")) {
12714          sip_register(v->value, v->lineno);
12715       } else if (!strcasecmp(v->name, "tos")) {
12716          if (ast_str2tos(v->value, &tos))
12717             ast_log(LOG_WARNING, "Invalid tos value at line %d, should be 'lowdelay', 'throughput', 'reliability', 'mincost', or 'none'\n", v->lineno);
12718       } else if (!strcasecmp(v->name, "bindport")) {
12719          if (sscanf(v->value, "%d", &ourport) == 1) {
12720             bindaddr.sin_port = htons(ourport);
12721          } else {
12722             ast_log(LOG_WARNING, "Invalid port number '%s' at line %d of %s\n", v->value, v->lineno, config);
12723          }
12724       } else if (!strcasecmp(v->name, "qualify")) {
12725          if (!strcasecmp(v->value, "no")) {
12726             default_qualify = 0;
12727          } else if (!strcasecmp(v->value, "yes")) {
12728             default_qualify = DEFAULT_MAXMS;
12729          } else if (sscanf(v->value, "%d", &default_qualify) != 1) {
12730             ast_log(LOG_WARNING, "Qualification default should be 'yes', 'no', or a number of milliseconds at line %d of sip.conf\n", v->lineno);
12731             default_qualify = 0;
12732          }
12733       } else if (!strcasecmp(v->name, "callevents")) {
12734          callevents = ast_true(v->value);
12735       }
12736       /* else if (strcasecmp(v->name,"type"))
12737        * ast_log(LOG_WARNING, "Ignoring %s\n", v->name);
12738        */
12739        v = v->next;
12740    }
12741 
12742    if (!allow_external_domains && AST_LIST_EMPTY(&domain_list)) {
12743       ast_log(LOG_WARNING, "To disallow external domains, you need to configure local SIP domains.\n");
12744       allow_external_domains = 1;
12745    }
12746    
12747    /* Build list of authentication to various SIP realms, i.e. service providers */
12748    v = ast_variable_browse(cfg, "authentication");
12749    while(v) {
12750       /* Format for authentication is auth = username:password@realm */
12751       if (!strcasecmp(v->name, "auth")) {
12752          authl = add_realm_authentication(authl, v->value, v->lineno);
12753       }
12754       v = v->next;
12755    }
12756    
12757    /* Load peers, users and friends */
12758    cat = ast_category_browse(cfg, NULL);
12759    while(cat) {
12760       if (strcasecmp(cat, "general") && strcasecmp(cat, "authentication")) {
12761          utype = ast_variable_retrieve(cfg, cat, "type");
12762          if (utype) {
12763             if (!strcasecmp(utype, "user") || !strcasecmp(utype, "friend")) {
12764                user = build_user(cat, ast_variable_browse(cfg, cat), 0);
12765                if (user) {
12766                   ASTOBJ_CONTAINER_LINK(&userl,user);
12767                   ASTOBJ_UNREF(user, sip_destroy_user);
12768                }
12769             }
12770             if (!strcasecmp(utype, "peer") || !strcasecmp(utype, "friend")) {
12771                peer = build_peer(cat, ast_variable_browse(cfg, cat), 0);
12772                if (peer) {
12773                   ASTOBJ_CONTAINER_LINK(&peerl,peer);
12774                   ASTOBJ_UNREF(peer, sip_destroy_peer);
12775                }
12776             } else if (strcasecmp(utype, "user")) {
12777                ast_log(LOG_WARNING, "Unknown type '%s' for '%s' in %s\n", utype, cat, "sip.conf");
12778             }
12779          } else
12780             ast_log(LOG_WARNING, "Section '%s' lacks type\n", cat);
12781       }
12782       cat = ast_category_browse(cfg, cat);
12783    }
12784    if (ast_find_ourip(&__ourip, bindaddr)) {
12785       ast_log(LOG_WARNING, "Unable to get own IP address, SIP disabled\n");
12786       return 0;
12787    }
12788    if (!ntohs(bindaddr.sin_port))
12789       bindaddr.sin_port = ntohs(DEFAULT_SIP_PORT);
12790    bindaddr.sin_family = AF_INET;
12791    ast_mutex_lock(&netlock);
12792    if ((sipsock > -1) && (memcmp(&old_bindaddr, &bindaddr, sizeof(struct sockaddr_in)))) {
12793       close(sipsock);
12794       sipsock = -1;
12795    }
12796    if (sipsock < 0) {
12797       sipsock = socket(AF_INET, SOCK_DGRAM, 0);
12798       if (sipsock < 0) {
12799          ast_log(LOG_WARNING, "Unable to create SIP socket: %s\n", strerror(errno));
12800       } else {
12801          /* Allow SIP clients on the same host to access us: */
12802          const int reuseFlag = 1;
12803          setsockopt(sipsock, SOL_SOCKET, SO_REUSEADDR,
12804                (const char*)&reuseFlag,
12805                sizeof reuseFlag);
12806 
12807          if (bind(sipsock, (struct sockaddr *)&bindaddr, sizeof(bindaddr)) < 0) {
12808             ast_log(LOG_WARNING, "Failed to bind to %s:%d: %s\n",
12809             ast_inet_ntoa(iabuf, sizeof(iabuf), bindaddr.sin_addr), ntohs(bindaddr.sin_port),
12810             strerror(errno));
12811             close(sipsock);
12812             sipsock = -1;
12813          } else {
12814             if (option_verbose > 1) { 
12815                ast_verbose(VERBOSE_PREFIX_2 "SIP Listening on %s:%d\n", 
12816                ast_inet_ntoa(iabuf, sizeof(iabuf), bindaddr.sin_addr), ntohs(bindaddr.sin_port));
12817                ast_verbose(VERBOSE_PREFIX_2 "Using TOS bits %d\n", tos);
12818             }
12819             if (setsockopt(sipsock, IPPROTO_IP, IP_TOS, &tos, sizeof(tos))) 
12820                ast_log(LOG_WARNING, "Unable to set TOS to %d\n", tos);
12821          }
12822       }
12823    }
12824    ast_mutex_unlock(&netlock);
12825 
12826    /* Add default domains - host name, IP address and IP:port */
12827    /* Only do this if user added any sip domain with "localdomains" */
12828    /* In order to *not* break backwards compatibility */
12829    /*    Some phones address us at IP only, some with additional port number */
12830    if (auto_sip_domains) {
12831       char temp[MAXHOSTNAMELEN];
12832 
12833       /* First our default IP address */
12834       if (bindaddr.sin_addr.s_addr) {
12835          ast_inet_ntoa(temp, sizeof(temp), bindaddr.sin_addr);
12836          add_sip_domain(temp, SIP_DOMAIN_AUTO, NULL);
12837       } else {
12838          ast_log(LOG_NOTICE, "Can't add wildcard IP address to domain list, please add IP address to domain manually.\n");
12839       }
12840 
12841       /* Our extern IP address, if configured */
12842       if (externip.sin_addr.s_addr) {
12843          ast_inet_ntoa(temp, sizeof(temp), externip.sin_addr);
12844          add_sip_domain(temp, SIP_DOMAIN_AUTO, NULL);
12845       }
12846 
12847       /* Extern host name (NAT traversal support) */
12848       if (!ast_strlen_zero(externhost))
12849          add_sip_domain(externhost, SIP_DOMAIN_AUTO, NULL);
12850       
12851       /* Our host name */
12852       if (!gethostname(temp, sizeof(temp)))
12853          add_sip_domain(temp, SIP_DOMAIN_AUTO, NULL);
12854    }
12855 
12856    /* Release configuration from memory */
12857    ast_config_destroy(cfg);
12858 
12859    /* Load the list of manual NOTIFY types to support */
12860    if (notify_types)
12861       ast_config_destroy(notify_types);
12862    notify_types = ast_config_load(notify_config);
12863 
12864    return 0;
12865 }

static int reply_digest struct sip_pvt p,
struct sip_request req,
char *  header,
int  sipmethod,
char *  digest,
int  digest_len
[static]
 

reply_digest: reply to authentication for outbound registrations ---

Definition at line 9031 of file chan_sip.c.

References ast_log(), ast_strlen_zero(), build_reply_digest(), sip_registry::domain, sip_pvt::domain, get_header(), key(), keys, 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().

09033 {
09034    char tmp[512];
09035    char *c;
09036    char oldnonce[256];
09037 
09038    /* table of recognised keywords, and places where they should be copied */
09039    const struct x {
09040       const char *key;
09041       char *dst;
09042       int dstlen;
09043    } *i, keys[] = {
09044       { "realm=", p->realm, sizeof(p->realm) },
09045       { "nonce=", p->nonce, sizeof(p->nonce) },
09046       { "opaque=", p->opaque, sizeof(p->opaque) },
09047       { "qop=", p->qop, sizeof(p->qop) },
09048       { "domain=", p->domain, sizeof(p->domain) },
09049       { NULL, NULL, 0 },
09050    };
09051 
09052    ast_copy_string(tmp, get_header(req, header), sizeof(tmp));
09053    if (ast_strlen_zero(tmp)) 
09054       return -1;
09055    if (strncasecmp(tmp, "Digest ", strlen("Digest "))) {
09056       ast_log(LOG_WARNING, "missing Digest.\n");
09057       return -1;
09058    }
09059    c = tmp + strlen("Digest ");
09060    for (i = keys; i->key != NULL; i++)
09061       i->dst[0] = '\0'; /* init all to empty strings */
09062    ast_copy_string(oldnonce, p->nonce, sizeof(oldnonce));
09063    while (c && *(c = ast_skip_blanks(c))) {  /* lookup for keys */
09064       for (i = keys; i->key != NULL; i++) {
09065          char *src, *separator;
09066          if (strncasecmp(c, i->key, strlen(i->key)) != 0)
09067             continue;
09068          /* Found. Skip keyword, take text in quotes or up to the separator. */
09069          c += strlen(i->key);
09070          if (*c == '\"') {
09071             src = ++c;
09072             separator = "\"";
09073          } else {
09074             src = c;
09075             separator = ",";
09076          }
09077          strsep(&c, separator); /* clear separator and move ptr */
09078          ast_copy_string(i->dst, src, i->dstlen);
09079          break;
09080       }
09081       if (i->key == NULL) /* not found, try ',' */
09082          strsep(&c, ",");
09083    }
09084    /* Reset nonce count */
09085    if (strcmp(p->nonce, oldnonce)) 
09086       p->noncecount = 0;
09087 
09088    /* Save auth data for following registrations */
09089    if (p->registry) {
09090       struct sip_registry *r = p->registry;
09091 
09092       if (strcmp(r->nonce, p->nonce)) {
09093          ast_copy_string(r->realm, p->realm, sizeof(r->realm));
09094          ast_copy_string(r->nonce, p->nonce, sizeof(r->nonce));
09095          ast_copy_string(r->domain, p->domain, sizeof(r->domain));
09096          ast_copy_string(r->opaque, p->opaque, sizeof(r->opaque));
09097          ast_copy_string(r->qop, p->qop, sizeof(r->qop));
09098          r->noncecount = 0;
09099       }
09100    }
09101    return build_reply_digest(p, sipmethod, digest, digest_len); 
09102 }

static int reqprep struct sip_request req,
struct sip_pvt p,
int  sipmethod,
int  seqno,
int  newbranch
[static]
 

reqprep: Initialize a SIP request response packet ---

Definition at line 4107 of file chan_sip.c.

References add_header(), add_route(), ast_strlen_zero(), ast_test_flag, sip_pvt::branch, build_via(), copy_header(), DEFAULT_MAX_FORWARDS, default_useragent, get_header(), get_in_brackets(), sip_route::hop, init_req(), sip_pvt::initreq, sip_pvt::lastmsg, n, sip_route::next, sip_pvt::ocseq, sip_pvt::okcontacturi, sip_pvt::our_contact, sip_request::rlPart2, sip_pvt::route, sip_pvt::rpid, set_destination(), SIP_ACK, SIP_CANCEL, sip_methods, SIP_OUTGOING, strcasestr(), text, cfsip_methods::text, thread_safe_rand(), sip_pvt::uri, and sip_pvt::via.

04108 {
04109    struct sip_request *orig = &p->initreq;
04110    char stripped[80];
04111    char tmp[80];
04112    char newto[256];
04113    char *c, *n;
04114    char *ot, *of;
04115    int is_strict = 0;   /* Strict routing flag */
04116 
04117    memset(req, 0, sizeof(struct sip_request));
04118    
04119    snprintf(p->lastmsg, sizeof(p->lastmsg), "Tx: %s", sip_methods[sipmethod].text);
04120    
04121    if (!seqno) {
04122       p->ocseq++;
04123       seqno = p->ocseq;
04124    }
04125    
04126    if (newbranch) {
04127       p->branch ^= thread_safe_rand();
04128       build_via(p, p->via, sizeof(p->via));
04129    }
04130 
04131    /* Check for strict or loose router */
04132    if (p->route && !ast_strlen_zero(p->route->hop) && strstr(p->route->hop,";lr") == NULL)
04133       is_strict = 1;
04134 
04135    if (sipmethod == SIP_CANCEL) {
04136       c = p->initreq.rlPart2; /* Use original URI */
04137    } else if (sipmethod == SIP_ACK) {
04138       /* Use URI from Contact: in 200 OK (if INVITE) 
04139       (we only have the contacturi on INVITEs) */
04140       if (!ast_strlen_zero(p->okcontacturi))
04141          c = is_strict ? p->route->hop : p->okcontacturi;
04142       else
04143          c = p->initreq.rlPart2;
04144    } else if (!ast_strlen_zero(p->okcontacturi)) {
04145          c = is_strict ? p->route->hop : p->okcontacturi; /* Use for BYE or REINVITE */
04146    } else if (!ast_strlen_zero(p->uri)) {
04147       c = p->uri;
04148    } else {
04149       /* We have no URI, use To: or From:  header as URI (depending on direction) */
04150       c = get_header(orig, (ast_test_flag(p, SIP_OUTGOING)) ? "To" : "From");
04151       ast_copy_string(stripped, c, sizeof(stripped));
04152       c = get_in_brackets(stripped);
04153       n = strchr(c, ';');
04154       if (n)
04155          *n = '\0';
04156    }  
04157    init_req(req, sipmethod, c);
04158 
04159    snprintf(tmp, sizeof(tmp), "%d %s", seqno, sip_methods[sipmethod].text);
04160 
04161    add_header(req, "Via", p->via);
04162    if (p->route) {
04163       set_destination(p, p->route->hop);
04164       if (is_strict)
04165          add_route(req, p->route->next);
04166       else
04167          add_route(req, p->route);
04168    }
04169 
04170    ot = get_header(orig, "To");
04171    of = get_header(orig, "From");
04172 
04173    /* Add tag *unless* this is a CANCEL, in which case we need to send it exactly
04174       as our original request, including tag (or presumably lack thereof) */
04175    if (!strcasestr(ot, "tag=") && sipmethod != SIP_CANCEL) {
04176       /* Add the proper tag if we don't have it already.  If they have specified
04177          their tag, use it.  Otherwise, use our own tag */
04178       if (ast_test_flag(p, SIP_OUTGOING) && !ast_strlen_zero(p->theirtag))
04179          snprintf(newto, sizeof(newto), "%s;tag=%s", ot, p->theirtag);
04180       else if (!ast_test_flag(p, SIP_OUTGOING))
04181          snprintf(newto, sizeof(newto), "%s;tag=%s", ot, p->tag);
04182       else
04183          snprintf(newto, sizeof(newto), "%s", ot);
04184       ot = newto;
04185    }
04186 
04187    if (ast_test_flag(p, SIP_OUTGOING)) {
04188       add_header(req, "From", of);
04189       add_header(req, "To", ot);
04190    } else {
04191       add_header(req, "From", ot);
04192       add_header(req, "To", of);
04193    }
04194    add_header(req, "Contact", p->our_contact);
04195    copy_header(req, orig, "Call-ID");
04196    add_header(req, "CSeq", tmp);
04197 
04198    add_header(req, "User-Agent", default_useragent);
04199    add_header(req, "Max-Forwards", DEFAULT_MAX_FORWARDS);
04200 
04201    if (p->rpid)
04202       add_header(req, "Remote-Party-ID", p->rpid);
04203 
04204    return 0;
04205 }

static int respprep struct sip_request resp,
struct sip_pvt p,
char *  msg,
struct sip_request req
[static]
 

respprep: Prepare SIP response packet ---

Definition at line 4059 of file chan_sip.c.

References add_header(), ALLOWED_METHODS, ast_strlen_zero(), ast_test_flag, copy_all_header(), copy_header(), copy_via_headers(), default_useragent, sip_pvt::expiry, get_header(), init_resp(), sip_pvt::method, sip_pvt::our_contact, SIP_LEN_CONTACT, SIP_OUTGOING, SIP_REGISTER, SIP_SUBSCRIBE, strcasestr(), sip_pvt::tag, and sip_pvt::theirtag.

04060 {
04061    char newto[256], *ot;
04062 
04063    memset(resp, 0, sizeof(*resp));
04064    init_resp(resp, msg, req);
04065    copy_via_headers(p, resp, req, "Via");
04066    if (msg[0] == '2')
04067       copy_all_header(resp, req, "Record-Route");
04068    copy_header(resp, req, "From");
04069    ot = get_header(req, "To");
04070    if (!strcasestr(ot, "tag=") && strncmp(msg, "100", 3)) {
04071       /* Add the proper tag if we don't have it already.  If they have specified
04072          their tag, use it.  Otherwise, use our own tag */
04073       if (!ast_strlen_zero(p->theirtag) && ast_test_flag(p, SIP_OUTGOING))
04074          snprintf(newto, sizeof(newto), "%s;tag=%s", ot, p->theirtag);
04075       else if (p->tag && !ast_test_flag(p, SIP_OUTGOING))
04076          snprintf(newto, sizeof(newto), "%s;tag=%s", ot, p->tag);
04077       else {
04078          ast_copy_string(newto, ot, sizeof(newto));
04079          newto[sizeof(newto) - 1] = '\0';
04080       }
04081       ot = newto;
04082    }
04083    add_header(resp, "To", ot);
04084    copy_header(resp, req, "Call-ID");
04085    copy_header(resp, req, "CSeq");
04086    add_header(resp, "User-Agent", default_useragent);
04087    add_header(resp, "Allow", ALLOWED_METHODS);
04088    if (msg[0] == '2' && (p->method == SIP_SUBSCRIBE || p->method == SIP_REGISTER)) {
04089       /* For registration responses, we also need expiry and
04090          contact info */
04091       char tmp[256];
04092 
04093       snprintf(tmp, sizeof(tmp), "%d", p->expiry);
04094       add_header(resp, "Expires", tmp);
04095       if (p->expiry) {  /* Only add contact if we have an expiry time */
04096          char contact[SIP_LEN_CONTACT];
04097          snprintf(contact, sizeof(contact), "%s;expires=%d", p->our_contact, p->expiry);
04098          add_header(resp, "Contact", contact);  /* Not when we unregister */
04099       }
04100    } else if (p->our_contact[0]) {
04101       add_header(resp, "Contact", p->our_contact);
04102    }
04103    return 0;
04104 }

static int restart_monitor void   )  [static]
 

restart_monitor: Start the channel monitor thread ---

Definition at line 11528 of file chan_sip.c.

References ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_pthread_create, AST_PTHREADT_NULL, AST_PTHREADT_STOP, do_monitor(), LOG_ERROR, LOG_WARNING, and monitor_thread.

11529 {
11530    /* If we're supposed to be stopped -- stay stopped */
11531    if (monitor_thread == AST_PTHREADT_STOP)
11532       return 0;
11533    if (ast_mutex_lock(&monlock)) {
11534       ast_log(LOG_WARNING, "Unable to lock monitor\n");
11535       return -1;
11536    }
11537    if (monitor_thread == pthread_self()) {
11538       ast_mutex_unlock(&monlock);
11539       ast_log(LOG_WARNING, "Cannot kill myself\n");
11540       return -1;
11541    }
11542    if (monitor_thread != AST_PTHREADT_NULL) {
11543       /* Wake up the thread */
11544       pthread_kill(monitor_thread, SIGURG);
11545    } else {
11546       /* Start a new monitor */
11547       if (ast_pthread_create(&monitor_thread, NULL, do_monitor, NULL) < 0) {
11548          ast_mutex_unlock(&monlock);
11549          ast_log(LOG_ERROR, "Unable to start monitor thread.\n");
11550          return -1;
11551       }
11552    }
11553    ast_mutex_unlock(&monlock);
11554    return 0;
11555 }

static int retrans_pkt void *  data  )  [static]
 

retrans_pkt: Retransmit SIP message if no answer ---

Definition at line 1164 of file chan_sip.c.

References __sip_xmit(), append_history(), ast_inet_ntoa(), ast_log(), ast_mutex_lock(), ast_mutex_trylock(), ast_mutex_unlock(), ast_queue_hangup(), ast_set_flag, ast_test_flag, ast_verbose(), sip_pvt::callid, sip_pkt::data, DEFAULT_RETRANS, FLAG_FATAL, FLAG_RESPONSE, free, ast_channel::lock, sip_pvt::lock, LOG_DEBUG, LOG_WARNING, MAX_RETRANS, sip_pkt::method, sip_pkt::next, option_debug, sip_pvt::owner, sip_pkt::owner, sip_pkt::packetlen, sip_pvt::packets, sip_pvt::recv, sip_pkt::retrans, sip_pkt::retransid, sip_pvt::sa, SIP_ALREADYGONE, sip_debug_test_pvt(), SIP_INVITE, sip_methods, SIP_NAT, SIP_NAT_ROUTE, SIP_NEEDDESTROY, SIP_OPTIONS, sipdebug, sip_pkt::timer_a, and sip_pkt::timer_t1.

01165 {
01166    struct sip_pkt *pkt=data, *prev, *cur = NULL;
01167    char iabuf[INET_ADDRSTRLEN];
01168    int reschedule = DEFAULT_RETRANS;
01169 
01170    /* Lock channel */
01171    ast_mutex_lock(&pkt->owner->lock);
01172 
01173    if (pkt->retrans < MAX_RETRANS) {
01174       char buf[80];
01175 
01176       pkt->retrans++;
01177       if (!pkt->timer_t1) {   /* Re-schedule using timer_a and timer_t1 */
01178          if (sipdebug && option_debug > 3)
01179             ast_log(LOG_DEBUG, "SIP TIMER: Not rescheduling id #%d:%s (Method %d) (No timer T1)\n", pkt->retransid, sip_methods[pkt->method].text, pkt->method);
01180       } else {
01181          int siptimer_a;
01182 
01183          if (sipdebug && option_debug > 3)
01184             ast_log(LOG_DEBUG, "SIP TIMER: Rescheduling retransmission #%d (%d) %s - %d\n", pkt->retransid, pkt->retrans, sip_methods[pkt->method].text, pkt->method);
01185          if (!pkt->timer_a)
01186             pkt->timer_a = 2 ;
01187          else
01188             pkt->timer_a = 2 * pkt->timer_a;
01189  
01190          /* For non-invites, a maximum of 4 secs */
01191          siptimer_a = pkt->timer_t1 * pkt->timer_a;   /* Double each time */
01192          if (pkt->method != SIP_INVITE && siptimer_a > 4000)
01193             siptimer_a = 4000;
01194       
01195          /* Reschedule re-transmit */
01196          reschedule = siptimer_a;
01197          if (option_debug > 3)
01198             ast_log(LOG_DEBUG, "** 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);
01199       } 
01200 
01201       if (pkt->owner && sip_debug_test_pvt(pkt->owner)) {
01202          if (ast_test_flag(pkt->owner, SIP_NAT) & SIP_NAT_ROUTE)
01203             ast_verbose("Retransmitting #%d (NAT) to %s:%d:\n%s\n---\n", pkt->retrans, ast_inet_ntoa(iabuf, sizeof(iabuf), pkt->owner->recv.sin_addr), ntohs(pkt->owner->recv.sin_port), pkt->data);
01204          else
01205             ast_verbose("Retransmitting #%d (no NAT) to %s:%d:\n%s\n---\n", pkt->retrans, ast_inet_ntoa(iabuf, sizeof(iabuf), pkt->owner->sa.sin_addr), ntohs(pkt->owner->sa.sin_port), pkt->data);
01206       }
01207       snprintf(buf, sizeof(buf), "ReTx %d", reschedule);
01208 
01209       append_history(pkt->owner, buf, pkt->data);
01210       __sip_xmit(pkt->owner, pkt->data, pkt->packetlen);
01211       ast_mutex_unlock(&pkt->owner->lock);
01212       return  reschedule;
01213    } 
01214    /* Too many retries */
01215    if (pkt->owner && pkt->method != SIP_OPTIONS) {
01216       if (ast_test_flag(pkt, FLAG_FATAL) || sipdebug) /* Tell us if it's critical or if we're debugging */
01217          ast_log(LOG_WARNING, "Maximum retries exceeded on transmission %s for seqno %d (%s %s)\n", pkt->owner->callid, pkt->seqno, (ast_test_flag(pkt, FLAG_FATAL)) ? "Critical" : "Non-critical", (ast_test_flag(pkt, FLAG_RESPONSE)) ? "Response" : "Request");
01218    } else {
01219       if (pkt->method == SIP_OPTIONS && sipdebug)
01220          ast_log(LOG_WARNING, "Cancelling retransmit of OPTIONs (call id %s) \n", pkt->owner->callid);
01221    }
01222    append_history(pkt->owner, "MaxRetries", (ast_test_flag(pkt, FLAG_FATAL)) ? "(Critical)" : "(Non-critical)");
01223       
01224    pkt->retransid = -1;
01225 
01226    if (ast_test_flag(pkt, FLAG_FATAL)) {
01227       while(pkt->owner->owner && ast_mutex_trylock(&pkt->owner->owner->lock)) {
01228          ast_mutex_unlock(&pkt->owner->lock);
01229          usleep(1);
01230          ast_mutex_lock(&pkt->owner->lock);
01231       }
01232       if (pkt->owner->owner) {
01233          ast_set_flag(pkt->owner, SIP_ALREADYGONE);
01234          ast_log(LOG_WARNING, "Hanging up call %s - no reply to our critical packet.\n", pkt->owner->callid);
01235          ast_queue_hangup(pkt->owner->owner);
01236          ast_mutex_unlock(&pkt->owner->owner->lock);
01237       } else {
01238          /* If no channel owner, destroy now */
01239          ast_set_flag(pkt->owner, SIP_NEEDDESTROY);   
01240       }
01241    }
01242    /* In any case, go ahead and remove the packet */
01243    prev = NULL;
01244    cur = pkt->owner->packets;
01245    while(cur) {
01246       if (cur == pkt)
01247          break;
01248       prev = cur;
01249       cur = cur->next;
01250    }
01251    if (cur) {
01252       if (prev)
01253          prev->next = cur->next;
01254       else
01255          pkt->owner->packets = cur->next;
01256       ast_mutex_unlock(&pkt->owner->lock);
01257       free(cur);
01258       pkt = NULL;
01259    } else
01260       ast_log(LOG_WARNING, "Weird, couldn't find packet owner!\n");
01261    if (pkt)
01262       ast_mutex_unlock(&pkt->owner->lock);
01263    return 0;
01264 }

static void sdpLineNum_iterator_init int *  iterator,
struct sip_request req
[static]
 

Definition at line 2881 of file chan_sip.c.

References sip_request::sdp_start.

02882 {
02883    *iterator = req->sdp_start;
02884 }

static int send_request struct sip_pvt p,
struct sip_request req,
int  reliable,
int  seqno
[static]
 

send_request: Send SIP Request to the other part of the dialogue ---

Definition at line 1506 of file chan_sip.c.

References __sip_reliable_xmit(), __sip_xmit(), append_history(), ast_inet_ntoa(), ast_test_flag, ast_verbose(), sip_request::data, get_header(), sip_request::len, sip_request::method, parse_copy(), recordhistory, sip_debug_test_pvt(), SIP_NAT, and SIP_NAT_ROUTE.

01507 {
01508    int res;
01509    char iabuf[INET_ADDRSTRLEN];
01510    struct sip_request tmp;
01511    char tmpmsg[80];
01512 
01513    if (sip_debug_test_pvt(p)) {
01514       if (ast_test_flag(p, SIP_NAT) & SIP_NAT_ROUTE)
01515          ast_verbose("%sTransmitting (NAT) to %s:%d:\n%s\n---\n", reliable ? "Reliably " : "", ast_inet_ntoa(iabuf, sizeof(iabuf), p->recv.sin_addr), ntohs(p->recv.sin_port), req->data);
01516       else
01517          ast_verbose("%sTransmitting (no NAT) to %s:%d:\n%s\n---\n", reliable ? "Reliably " : "", ast_inet_ntoa(iabuf, sizeof(iabuf), p->sa.sin_addr), ntohs(p->sa.sin_port), req->data);
01518    }
01519    if (reliable) {
01520       if (recordhistory) {
01521          parse_copy(&tmp, req);
01522          snprintf(tmpmsg, sizeof(tmpmsg), "%s / %s", tmp.data, get_header(&tmp, "CSeq"));
01523          append_history(p, "TxReqRel", tmpmsg);
01524       }
01525       res = __sip_reliable_xmit(p, seqno, 0, req->data, req->len, (reliable > 1), req->method);
01526    } else {
01527       if (recordhistory) {
01528          parse_copy(&tmp, req);
01529          snprintf(tmpmsg, sizeof(tmpmsg), "%s / %s", tmp.data, get_header(&tmp, "CSeq"));
01530          append_history(p, "TxReq", tmpmsg);
01531       }
01532       res = __sip_xmit(p, req->data, req->len);
01533    }
01534    return res;
01535 }

static int send_response struct sip_pvt p,
struct sip_request req,
int  reliable,
int  seqno
[static]
 

send_response: Transmit response on SIP request---

Definition at line 1472 of file chan_sip.c.

References __sip_reliable_xmit(), __sip_xmit(), append_history(), ast_inet_ntoa(), ast_test_flag, ast_verbose(), sip_request::data, get_header(), sip_request::len, sip_request::method, parse_copy(), recordhistory, sip_debug_test_pvt(), SIP_NAT, and SIP_NAT_ROUTE.

01473 {
01474    int res;
01475    char iabuf[INET_ADDRSTRLEN];
01476    struct sip_request tmp;
01477    char tmpmsg[80];
01478 
01479    if (sip_debug_test_pvt(p)) {
01480       if (ast_test_flag(p, SIP_NAT) & SIP_NAT_ROUTE)
01481          ast_verbose("%sTransmitting (NAT) to %s:%d:\n%s\n---\n", reliable ? "Reliably " : "", ast_inet_ntoa(iabuf, sizeof(iabuf), p->recv.sin_addr), ntohs(p->recv.sin_port), req->data);
01482       else
01483          ast_verbose("%sTransmitting (no NAT) to %s:%d:\n%s\n---\n", reliable ? "Reliably " : "", ast_inet_ntoa(iabuf, sizeof(iabuf), p->sa.sin_addr), ntohs(p->sa.sin_port), req->data);
01484    }
01485    if (reliable) {
01486       if (recordhistory) {
01487          parse_copy(&tmp, req);
01488          snprintf(tmpmsg, sizeof(tmpmsg), "%s / %s", tmp.data, get_header(&tmp, "CSeq"));
01489          append_history(p, "TxRespRel", tmpmsg);
01490       }
01491       res = __sip_reliable_xmit(p, seqno, 1, req->data, req->len, (reliable > 1), req->method);
01492    } else {
01493       if (recordhistory) {
01494          parse_copy(&tmp, req);
01495          snprintf(tmpmsg, sizeof(tmpmsg), "%s / %s", tmp.data, get_header(&tmp, "CSeq"));
01496          append_history(p, "TxResp", tmpmsg);
01497       }
01498       res = __sip_xmit(p, req->data, req->len);
01499    }
01500    if (res > 0)
01501       return 0;
01502    return res;
01503 }

static void set_destination struct sip_pvt p,
char *  uri
[static]
 

set_destination: Set destination from SIP URI ---

Definition at line 3963 of file chan_sip.c.

References ast_gethostbyname(), ast_inet_ntoa(), ast_log(), ast_verbose(), debug, DEFAULT_SIP_PORT, hostname, hp, LOG_WARNING, sip_pvt::sa, and sip_debug_test_pvt().

Referenced by reqprep().

03964 {
03965    char *h, *maddr, hostname[256];
03966    char iabuf[INET_ADDRSTRLEN];
03967    int port, hn;
03968    struct hostent *hp;
03969    struct ast_hostent ahp;
03970    int debug=sip_debug_test_pvt(p);
03971 
03972    /* Parse uri to h (host) and port - uri is already just the part inside the <> */
03973    /* general form we are expecting is sip[s]:username[:password]@host[:port][;...] */
03974 
03975    if (debug)
03976       ast_verbose("set_destination: Parsing <%s> for address/port to send to\n", uri);
03977 
03978    /* Find and parse hostname */
03979    h = strchr(uri, '@');
03980    if (h)
03981       ++h;
03982    else {
03983       h = uri;
03984       if (strncmp(h, "sip:", 4) == 0)
03985          h += 4;
03986       else if (strncmp(h, "sips:", 5) == 0)
03987          h += 5;
03988    }
03989    hn = strcspn(h, ":;>") + 1;
03990    if (hn > sizeof(hostname)) 
03991       hn = sizeof(hostname);
03992    ast_copy_string(hostname, h, hn);
03993    h += hn - 1;
03994 
03995    /* Is "port" present? if not default to DEFAULT_SIP_PORT */
03996    if (*h == ':') {
03997       /* Parse port */
03998       ++h;
03999       port = strtol(h, &h, 10);
04000    }
04001    else
04002       port = DEFAULT_SIP_PORT;
04003 
04004    /* Got the hostname:port - but maybe there's a "maddr=" to override address? */
04005    maddr = strstr(h, "maddr=");
04006    if (maddr) {
04007       maddr += 6;
04008       hn = strspn(maddr, "0123456789.") + 1;
04009       if (hn > sizeof(hostname)) hn = sizeof(hostname);
04010       ast_copy_string(hostname, maddr, hn);
04011    }
04012    
04013    hp = ast_gethostbyname(hostname, &ahp);
04014    if (hp == NULL)  {
04015       ast_log(LOG_WARNING, "Can't find address for host '%s'\n", hostname);
04016       return;
04017    }
04018    p->sa.sin_family = AF_INET;
04019    memcpy(&p->sa.sin_addr, hp->h_addr, sizeof(p->sa.sin_addr));
04020    p->sa.sin_port = htons(port);
04021    if (debug)
04022       ast_verbose("set_destination: set destination to %s, port %d\n", ast_inet_ntoa(iabuf, sizeof(iabuf), p->sa.sin_addr), port);
04023 }

static int sip_addheader struct ast_channel chan,
void *  data
[static]
 

sip_addheader: Add a SIP header ---

Definition at line 13018 of file chan_sip.c.

References ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_strlen_zero(), ast_channel::lock, LOG_DEBUG, LOG_WARNING, pbx_builtin_getvar_helper(), pbx_builtin_setvar_helper(), and sipdebug.

Referenced by load_module().

13019 {
13020    int no = 0;
13021    int ok = 0;
13022    char varbuf[128];
13023    
13024    if (ast_strlen_zero((char *)data)) {
13025       ast_log(LOG_WARNING, "This application requires the argument: Header\n");
13026       return 0;
13027    }
13028    ast_mutex_lock(&chan->lock);
13029 
13030    /* Check for headers */
13031    while (!ok && no <= 50) {
13032       no++;
13033       snprintf(varbuf, sizeof(varbuf), "_SIPADDHEADER%02d", no);
13034       if (ast_strlen_zero(pbx_builtin_getvar_helper(chan, varbuf + 1)))
13035          ok = 1;
13036    }
13037    if (ok) {
13038       pbx_builtin_setvar_helper (chan, varbuf, (char *)data);
13039       if (sipdebug)
13040          ast_log(LOG_DEBUG,"SIP Header added \"%s\" as %s\n", (char *) data, varbuf);
13041    } else {
13042       ast_log(LOG_WARNING, "Too many SIP headers added, max 50\n");
13043    }
13044    ast_mutex_unlock(&chan->lock);
13045    return 0;
13046 }

static int sip_addrcmp char *  name,
struct sockaddr_in *  sin
[static]
 

sip_addrcmp: Support routine for find_peer ---

Definition at line 1745 of file chan_sip.c.

References sip_peer::addr, ast_test_flag, inaddrcmp(), and SIP_INSECURE_PORT.

Referenced by find_peer().

01746 {
01747    /* We know name is the first field, so we can cast */
01748    struct sip_peer *p = (struct sip_peer *)name;
01749    return   !(!inaddrcmp(&p->addr, sin) || 
01750                (ast_test_flag(p, SIP_INSECURE_PORT) &&
01751                (p->addr.sin_addr.s_addr == sin->sin_addr.s_addr)));
01752 }

static struct sip_pvt* sip_alloc char *  callid,
struct sockaddr_in *  sin,
int  useglobal_nat,
const int  intended_method
[static]
 

sip_alloc: Allocate SIP_PVT structure and set defaults ---

Definition at line 3054 of file chan_sip.c.

References __ourip, ast_copy_flags, ast_log(), ast_mutex_destroy(), ast_mutex_init(), ast_mutex_lock(), ast_mutex_unlock(), AST_RTP_DTMF, ast_rtp_new_with_bindaddr(), ast_rtp_setnat(), ast_rtp_settos(), ast_sip_ouraddrfor(), ast_test_flag, ast_variables_destroy(), build_callid(), build_via(), calloc, default_context, default_fromdomain, free, global_capability, global_musicclass, global_rtpholdtimeout, global_rtpkeepalive, global_rtptimeout, iflist, LOG_DEBUG, LOG_WARNING, make_our_tag(), NONE, option_debug, SIP_DTMF, SIP_DTMF_AUTO, SIP_DTMF_RFC2833, SIP_FLAGS_TO_COPY, sip_methods, SIP_NAT, SIP_NAT_ROUTE, SIP_OPTIONS, SIP_REGISTER, text, thread_safe_rand(), tos, and videosupport.

Referenced by find_call(), sip_notify(), sip_poke_peer(), sip_request_call(), sip_send_mwi_to_peer(), and transmit_register().

03055 {
03056    struct sip_pvt *p;
03057 
03058    if (!(p = calloc(1, sizeof(*p))))
03059       return NULL;
03060 
03061    ast_mutex_init(&p->lock);
03062 
03063    p->method = intended_method;
03064    p->initid = -1;
03065    p->autokillid = -1;
03066    p->subscribed = NONE;
03067    p->stateid = -1;
03068    p->prefs = prefs;
03069    if (intended_method != SIP_OPTIONS) /* Peerpoke has it's own system */
03070       p->timer_t1 = 500;   /* Default SIP retransmission timer T1 (RFC 3261) */
03071 #ifdef OSP_SUPPORT
03072    p->osphandle = -1;
03073    p->osptimelimit = 0;
03074 #endif   
03075    if (sin) {
03076       memcpy(&p->sa, sin, sizeof(p->sa));
03077       if (ast_sip_ouraddrfor(&p->sa.sin_addr,&p->ourip))
03078          memcpy(&p->ourip, &__ourip, sizeof(p->ourip));
03079    } else {
03080       memcpy(&p->ourip, &__ourip, sizeof(p->ourip));
03081    }
03082 
03083    p->branch = thread_safe_rand();  
03084    make_our_tag(p->tag, sizeof(p->tag));
03085    /* Start with 101 instead of 1 */
03086    p->ocseq = 101;
03087 
03088    if (sip_methods[intended_method].need_rtp) {
03089       p->rtp = ast_rtp_new_with_bindaddr(sched, io, 1, 0, bindaddr.sin_addr);
03090       if (videosupport)
03091          p->vrtp = ast_rtp_new_with_bindaddr(sched, io, 1, 0, bindaddr.sin_addr);
03092       if (!p->rtp || (videosupport && !p->vrtp)) {
03093          ast_log(LOG_WARNING, "Unable to create RTP audio %s session: %s\n", videosupport ? "and video" : "", strerror(errno));
03094          ast_mutex_destroy(&p->lock);
03095          if (p->chanvars) {
03096             ast_variables_destroy(p->chanvars);
03097             p->chanvars = NULL;
03098          }
03099          free(p);
03100          return NULL;
03101       }
03102       ast_rtp_settos(p->rtp, tos);
03103       if (p->vrtp)
03104          ast_rtp_settos(p->vrtp, tos);
03105       p->rtptimeout = global_rtptimeout;
03106       p->rtpholdtimeout = global_rtpholdtimeout;
03107       p->rtpkeepalive = global_rtpkeepalive;
03108    }
03109 
03110    if (useglobal_nat && sin) {
03111       /* Setup NAT structure according to global settings if we have an address */
03112       ast_copy_flags(p, &global_flags, SIP_NAT);
03113       memcpy(&p->recv, sin, sizeof(p->recv));
03114       if (p->rtp)
03115          ast_rtp_setnat(p->rtp, (ast_test_flag(p, SIP_NAT) & SIP_NAT_ROUTE));
03116       if (p->vrtp)
03117          ast_rtp_setnat(p->vrtp, (ast_test_flag(p, SIP_NAT) & SIP_NAT_ROUTE));
03118    }
03119 
03120    if (p->method != SIP_REGISTER)
03121       ast_copy_string(p->fromdomain, default_fromdomain, sizeof(p->fromdomain));
03122    build_via(p, p->via, sizeof(p->via));
03123    if (!callid)
03124       build_callid(p->callid, sizeof(p->callid), p->ourip, p->fromdomain);
03125    else
03126       ast_copy_string(p->callid, callid, sizeof(p->callid));
03127    ast_copy_flags(p, &global_flags, SIP_FLAGS_TO_COPY);
03128    /* Assign default music on hold class */
03129    strcpy(p->musicclass, global_musicclass);
03130    p->capability = global_capability;
03131    if ((ast_test_flag(p, SIP_DTMF) == SIP_DTMF_RFC2833) || (ast_test_flag(p, SIP_DTMF) == SIP_DTMF_AUTO))
03132       p->noncodeccapability |= AST_RTP_DTMF;
03133    strcpy(p->context, default_context);
03134 
03135    /* Add to active dialog list */
03136    ast_mutex_lock(&iflock);
03137    p->next = iflist;
03138    iflist = p;
03139    ast_mutex_unlock(&iflock);
03140    if (option_debug)
03141       ast_log(LOG_DEBUG, "Allocating new SIP dialog for %s - %s (%s)\n", callid ? callid : "(No Call-ID)", sip_methods[intended_method].text, p->rtp ? "With RTP" : "No RTP");
03142    return p;
03143 }

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 2523 of file chan_sip.c.

References ast_channel::_state, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_setstate(), AST_STATE_UP, sip_pvt::initreq, sip_pvt::lock, LOG_DEBUG, ast_channel::name, option_debug, ast_channel::tech_pvt, transmit_response_with_sdp(), and try_suggested_sip_codec().

02524 {
02525    int res = 0;
02526    struct sip_pvt *p = ast->tech_pvt;
02527 
02528    ast_mutex_lock(&p->lock);
02529    if (ast->_state != AST_STATE_UP) {
02530 #ifdef OSP_SUPPORT   
02531       time(&p->ospstart);
02532 #endif
02533       try_suggested_sip_codec(p);   
02534 
02535       ast_setstate(ast, AST_STATE_UP);
02536       if (option_debug)
02537          ast_log(LOG_DEBUG, "sip_answer(%s)\n", ast->name);
02538       res = transmit_response_with_sdp(p, "200 OK", &p->initreq, 1);
02539    }
02540    ast_mutex_unlock(&p->lock);
02541    return res;
02542 }

static int sip_call struct ast_channel ast,
char *  dest,
int  timeout
[static]
 

sip_call: Initiate SIP call from PBX used from the dial() application

Definition at line 2011 of file chan_sip.c.

References ast_channel::_state, sip_invite_param::addsipheaders, AST_LIST_TRAVERSE, ast_log(), ast_sched_add(), ast_set_flag, AST_STATE_DOWN, AST_STATE_RESERVED, ast_var_name(), ast_var_value(), auto_congest(), sip_pvt::callingpres, sip_pvt::capability, ast_channel::cid, ast_callerid::cid_pres, sip_invite_param::distinctive_ring, INC_CALL_LIMIT, sip_pvt::initid, sip_pvt::jointcapability, LOG_DEBUG, LOG_WARNING, sip_pvt::maxtime, ast_channel::name, sip_pvt::options, sip_invite_param::osptoken, SIP_INVITE, SIP_OUTGOING, ast_channel::tech_pvt, transmit_invite(), update_call_counter(), sip_invite_param::uri_options, sip_pvt::username, ast_channel::varshead, and sip_invite_param::vxml_url.

02012 {
02013    int res;
02014    struct sip_pvt *p;
02015 #ifdef OSP_SUPPORT
02016    char *osphandle = NULL;
02017 #endif   
02018    struct varshead *headp;
02019    struct ast_var_t *current;
02020    
02021 
02022    
02023    p = ast->tech_pvt;
02024    if ((ast->_state != AST_STATE_DOWN) && (ast->_state != AST_STATE_RESERVED)) {
02025       ast_log(LOG_WARNING, "sip_call called on %s, neither down nor reserved\n", ast->name);
02026       return -1;
02027    }
02028 
02029 
02030    /* Check whether there is vxml_url, distinctive ring variables */
02031 
02032    headp=&ast->varshead;
02033    AST_LIST_TRAVERSE(headp,current,entries) {
02034       /* Check whether there is a VXML_URL variable */
02035       if (!p->options->vxml_url && !strcasecmp(ast_var_name(current), "VXML_URL")) {
02036          p->options->vxml_url = ast_var_value(current);
02037                } else if (!p->options->uri_options && !strcasecmp(ast_var_name(current), "SIP_URI_OPTIONS")) {
02038                        p->options->uri_options = ast_var_value(current);
02039       } else if (!p->options->distinctive_ring && !strcasecmp(ast_var_name(current), "ALERT_INFO")) {
02040          /* Check whether there is a ALERT_INFO variable */
02041          p->options->distinctive_ring = ast_var_value(current);
02042       } else if (!p->options->addsipheaders && !strncasecmp(ast_var_name(current), "SIPADDHEADER", strlen("SIPADDHEADER"))) {
02043          /* Check whether there is a variable with a name starting with SIPADDHEADER */
02044          p->options->addsipheaders = 1;
02045       }
02046 
02047       
02048 #ifdef OSP_SUPPORT
02049       else if (!p->options->osptoken && !strcasecmp(ast_var_name(current), "OSPTOKEN")) {
02050          p->options->osptoken = ast_var_value(current);
02051       } else if (!osphandle && !strcasecmp(ast_var_name(current), "OSPHANDLE")) {
02052          osphandle = ast_var_value(current);
02053       }
02054 #endif
02055    }
02056    
02057    res = 0;
02058    ast_set_flag(p, SIP_OUTGOING);
02059 #ifdef OSP_SUPPORT
02060    if (!p->options->osptoken || !osphandle || (sscanf(osphandle, "%d", &p->osphandle) != 1)) {
02061       /* Force Disable OSP support */
02062       ast_log(LOG_DEBUG, "Disabling OSP support for this call. osptoken = %s, osphandle = %s\n", p->options->osptoken, osphandle);
02063       p->options->osptoken = NULL;
02064       osphandle = NULL;
02065       p->osphandle = -1;
02066    }
02067 #endif
02068    ast_log(LOG_DEBUG, "Outgoing Call for %s\n", p->username);
02069    res = update_call_counter(p, INC_CALL_LIMIT);
02070    if ( res != -1 ) {
02071       p->callingpres = ast->cid.cid_pres;
02072       p->jointcapability = p->capability;
02073       transmit_invite(p, SIP_INVITE, 1, 2);
02074       if (p->maxtime) {
02075          /* Initialize auto-congest time */
02076          p->initid = ast_sched_add(sched, p->maxtime * 4, auto_congest, p);
02077       }
02078    }
02079    return res;
02080 }

static int sip_cancel_destroy struct sip_pvt p  )  [static]
 

sip_cancel_destroy: Cancel destruction of SIP call ---

Definition at line 1352 of file chan_sip.c.

References append_history(), ast_sched_del(), and sip_pvt::autokillid.

Referenced by cb_extensionstate(), check_user_full(), handle_request_invite(), handle_request_subscribe(), handle_response(), handle_response_invite(), and register_verify().

01353 {
01354    if (p->autokillid > -1)
01355       ast_sched_del(sched, p->autokillid);
01356    append_history(p, "CancelDestroy", "");
01357    p->autokillid = -1;
01358    return 0;
01359 }

static int sip_debug_test_addr struct sockaddr_in *  addr  )  [inline, static]
 

sip_debug_test_addr: See if we pass debug IP filter

Definition at line 1039 of file chan_sip.c.

References debugaddr, and sipdebug.

Referenced by check_user_full(), sip_debug_test_pvt(), and sipsock_read().

01040 {
01041    if (sipdebug == 0)
01042       return 0;
01043    if (debugaddr.sin_addr.s_addr) {
01044       if (((ntohs(debugaddr.sin_port) != 0)
01045          && (debugaddr.sin_port != addr->sin_port))
01046          || (debugaddr.sin_addr.s_addr != addr->sin_addr.s_addr))
01047          return 0;
01048    }
01049    return 1;
01050 }

static int sip_debug_test_pvt struct sip_pvt p  )  [inline, static]
 

sip_debug_test_pvt: Test PVT for debugging output

Definition at line 1053 of file chan_sip.c.

References ast_test_flag, sip_pvt::recv, sip_pvt::sa, sip_debug_test_addr(), SIP_NAT, SIP_NAT_ROUTE, and sipdebug.

Referenced by __sip_destroy(), add_sdp(), build_route(), check_via(), do_register_auth(), get_also_info(), get_destination(), get_rdnis(), get_refer_info(), handle_request(), process_sdp(), receive_message(), retrans_pkt(), send_request(), send_response(), set_destination(), sip_scheddestroy(), sip_sendtext(), transmit_invite(), transmit_notify_with_mwi(), transmit_notify_with_sipfrag(), transmit_register(), transmit_reinvite_with_sdp(), and transmit_sip_request().

01054 {
01055    if (sipdebug == 0)
01056       return 0;
01057    return sip_debug_test_addr(((ast_test_flag(p, SIP_NAT) & SIP_NAT_ROUTE) ? &p->recv : &p->sa));
01058 }

static void sip_destroy struct sip_pvt p  )  [static]
 

sip_destroy: Destroy SIP call structure ---

Definition at line 2275 of file chan_sip.c.

References __sip_destroy(), ast_mutex_lock(), and ast_mutex_unlock().

Referenced by __sip_autodestruct(), sip_destroy_peer(), sip_do_reload(), sip_notify(), sip_poke_noanswer(), sip_poke_peer(), sip_registry_destroy(), sip_request_call(), sip_send_mwi_to_peer(), and transmit_register().

02276 {
02277    ast_mutex_lock(&iflock);
02278    __sip_destroy(p, 1);
02279    ast_mutex_unlock(&iflock);
02280 }

static void sip_destroy_peer struct sip_peer peer  )  [static]
 

sip_destroy_peer: Destroy peer object from memory

Definition at line 1636 of file chan_sip.c.

References apeerobjs, ast_dnsmgr_release(), ast_free_ha(), ast_sched_del(), ast_test_flag, ast_variables_destroy(), sip_peer::call, sip_peer::chanvars, clear_realm_authentication(), sip_peer::expire, free, sip_peer::ha, sip_peer::pokeexpire, register_peer_exten(), rpeerobjs, sip_destroy(), SIP_REALTIME, SIP_SELFDESTRUCT, and speerobjs.

Referenced by _sip_show_peer(), build_peer(), check_user_full(), create_addr(), do_monitor(), expire_register(), function_sippeer(), register_verify(), reload_config(), sip_devicestate(), sip_do_debug_peer(), sip_prune_realtime(), unload_module(), and update_call_counter().

01637 {
01638    /* Delete it, it needs to disappear */
01639    if (peer->call)
01640       sip_destroy(peer->call);
01641    if (peer->chanvars) {
01642       ast_variables_destroy(peer->chanvars);
01643       peer->chanvars = NULL;
01644    }
01645    if (peer->expire > -1)
01646       ast_sched_del(sched, peer->expire);
01647    if (peer->pokeexpire > -1)
01648       ast_sched_del(sched, peer->pokeexpire);
01649    register_peer_exten(peer, 0);
01650    ast_free_ha(peer->ha);
01651    if (ast_test_flag(peer, SIP_SELFDESTRUCT))
01652       apeerobjs--;
01653    else if (ast_test_flag(peer, SIP_REALTIME))
01654       rpeerobjs--;
01655    else
01656       speerobjs--;
01657    clear_realm_authentication(peer->auth);
01658    peer->auth = (struct sip_auth *) NULL;
01659    if (peer->dnsmgr)
01660       ast_dnsmgr_release(peer->dnsmgr);
01661    free(peer);
01662 }

static void sip_destroy_user struct sip_user user  )  [static]
 

sip_destroy_user: Remove user object from in-memory storage ---

Definition at line 1774 of file chan_sip.c.

References ast_free_ha(), ast_test_flag, ast_variables_destroy(), sip_user::chanvars, free, sip_user::ha, ruserobjs, SIP_REALTIME, and suserobjs.

Referenced by check_user_full(), reload_config(), sip_prune_realtime(), sip_show_user(), unload_module(), and update_call_counter().

01775 {
01776    ast_free_ha(user->ha);
01777    if (user->chanvars) {
01778       ast_variables_destroy(user->chanvars);
01779       user->chanvars = NULL;
01780    }
01781    if (ast_test_flag(user, SIP_REALTIME))
01782       ruserobjs--;
01783    else
01784       suserobjs--;
01785    free(user);
01786 }

static int sip_devicestate void *  data  )  [static]
 

sip_devicestate: Part of PBX channel interface ---

Definition at line 11654 of file chan_sip.c.

References sip_peer::addr, AST_DEVICE_BUSY, AST_DEVICE_INUSE, AST_DEVICE_INVALID, AST_DEVICE_NOT_INUSE, AST_DEVICE_UNAVAILABLE, AST_DEVICE_UNKNOWN, ast_gethostbyname(), ast_log(), ast_strdupa, ASTOBJ_UNREF, sip_peer::call_limit, sip_peer::defaddr, find_peer(), host, hp, sip_peer::inUse, sip_peer::lastms, LOG_DEBUG, sip_peer::maxms, option_debug, and sip_destroy_peer().

11655 {
11656    char *host;
11657    char *tmp;
11658 
11659    struct hostent *hp;
11660    struct ast_hostent ahp;
11661    struct sip_peer *p;
11662 
11663    int res = AST_DEVICE_INVALID;
11664 
11665    host = ast_strdupa(data);
11666    if ((tmp = strchr(host, '@')))
11667       host = tmp + 1;
11668 
11669    if (option_debug > 2) 
11670       ast_log(LOG_DEBUG, "Checking device state for peer %s\n", host);
11671 
11672    if ((p = find_peer(host, NULL, 1))) {
11673       if (p->addr.sin_addr.s_addr || p->defaddr.sin_addr.s_addr) {
11674          /* we have an address for the peer */
11675          /* if qualify is turned on, check the status */
11676          if (p->maxms && (p->lastms > p->maxms)) {
11677             res = AST_DEVICE_UNAVAILABLE;
11678          } else {
11679             /* qualify is not on, or the peer is responding properly */
11680             /* check call limit */
11681             if (p->call_limit && (p->inUse == p->call_limit))
11682                res = AST_DEVICE_BUSY;
11683             else if (p->call_limit && p->inUse)
11684                res = AST_DEVICE_INUSE;
11685             else if (p->call_limit)
11686                res = AST_DEVICE_NOT_INUSE;
11687             else
11688                res = AST_DEVICE_UNKNOWN;
11689          }
11690       } else {
11691          /* there is no address, it's unavailable */
11692          res = AST_DEVICE_UNAVAILABLE;
11693       }
11694       ASTOBJ_UNREF(p,sip_destroy_peer);
11695    } else {
11696       hp = ast_gethostbyname(host, &ahp);
11697       if (hp)
11698          res = AST_DEVICE_UNKNOWN;
11699    }
11700 
11701    return res;
11702 }

static int sip_do_debug int  fd,
int  argc,
char *  argv[]
[static]
 

sip_do_debug: Turn on SIP debugging (CLI command)

Definition at line 8863 of file chan_sip.c.

References ast_cli(), debugaddr, RESULT_SHOWUSAGE, RESULT_SUCCESS, SIP_DEBUG_CONSOLE, sip_do_debug_ip(), sip_do_debug_peer(), and sipdebug.

08864 {
08865    int oldsipdebug = sipdebug & SIP_DEBUG_CONSOLE;
08866    if (argc != 2) {
08867       if (argc != 4) 
08868          return RESULT_SHOWUSAGE;
08869       else if (strncmp(argv[2], "ip\0", 3) == 0)
08870          return sip_do_debug_ip(fd, argc, argv);
08871       else if (strncmp(argv[2], "peer\0", 5) == 0)
08872          return sip_do_debug_peer(fd, argc, argv);
08873       else return RESULT_SHOWUSAGE;
08874    }
08875    sipdebug |= SIP_DEBUG_CONSOLE;
08876    memset(&debugaddr, 0, sizeof(debugaddr));
08877    if (oldsipdebug)
08878       ast_cli(fd, "SIP Debugging re-enabled\n");
08879    else
08880       ast_cli(fd, "SIP Debugging enabled\n");
08881    return RESULT_SUCCESS;
08882 }

static int sip_do_debug_ip int  fd,
int  argc,
char *  argv[]
[static]
 

sip_do_debug: Enable SIP Debugging in CLI ---

Definition at line 8807 of file chan_sip.c.

References ast_cli(), ast_gethostbyname(), ast_inet_ntoa(), debugaddr, hp, RESULT_SHOWUSAGE, RESULT_SUCCESS, SIP_DEBUG_CONSOLE, and sipdebug.

Referenced by sip_do_debug().

08808 {
08809    struct hostent *hp;
08810    struct ast_hostent ahp;
08811    char iabuf[INET_ADDRSTRLEN];
08812    int port = 0;
08813    char *p, *arg;
08814 
08815    if (argc != 4)
08816       return RESULT_SHOWUSAGE;
08817    arg = argv[3];
08818    p = strstr(arg, ":");
08819    if (p) {
08820       *p = '\0';
08821       p++;
08822       port = atoi(p);
08823    }
08824    hp = ast_gethostbyname(arg, &ahp);
08825    if (hp == NULL)  {
08826       return RESULT_SHOWUSAGE;
08827    }
08828    debugaddr.sin_family = AF_INET;
08829    memcpy(&debugaddr.sin_addr, hp->h_addr, sizeof(debugaddr.sin_addr));
08830    debugaddr.sin_port = htons(port);
08831    if (port == 0)
08832       ast_cli(fd, "SIP Debugging Enabled for IP: %s\n", ast_inet_ntoa(iabuf, sizeof(iabuf), debugaddr.sin_addr));
08833    else
08834       ast_cli(fd, "SIP Debugging Enabled for IP: %s:%d\n", ast_inet_ntoa(iabuf, sizeof(iabuf), debugaddr.sin_addr), port);
08835    sipdebug |= SIP_DEBUG_CONSOLE;
08836    return RESULT_SUCCESS;
08837 }

static int sip_do_debug_peer int  fd,
int  argc,
char *  argv[]
[static]
 

sip_do_debug_peer: Turn on SIP debugging with peer mask

Definition at line 8840 of file chan_sip.c.

References sip_peer::addr, ast_cli(), ast_inet_ntoa(), ASTOBJ_UNREF, debugaddr, find_peer(), RESULT_SHOWUSAGE, RESULT_SUCCESS, SIP_DEBUG_CONSOLE, sip_destroy_peer(), and sipdebug.

Referenced by sip_do_debug().

08841 {
08842    struct sip_peer *peer;
08843    char iabuf[INET_ADDRSTRLEN];
08844    if (argc != 4)
08845       return RESULT_SHOWUSAGE;
08846    peer = find_peer(argv[3], NULL, 1);
08847    if (peer) {
08848       if (peer->addr.sin_addr.s_addr) {
08849          debugaddr.sin_family = AF_INET;
08850          memcpy(&debugaddr.sin_addr, &peer->addr.sin_addr, sizeof(debugaddr.sin_addr));
08851          debugaddr.sin_port = peer->addr.sin_port;
08852          ast_cli(fd, "SIP Debugging Enabled for IP: %s:%d\n", ast_inet_ntoa(iabuf, sizeof(iabuf), debugaddr.sin_addr), ntohs(debugaddr.sin_port));
08853          sipdebug |= SIP_DEBUG_CONSOLE;
08854       } else
08855          ast_cli(fd, "Unable to get IP address of peer '%s'\n", argv[3]);
08856       ASTOBJ_UNREF(peer,sip_destroy_peer);
08857    } else
08858       ast_cli(fd, "No such peer '%s'\n", argv[3]);
08859    return RESULT_SUCCESS;
08860 }

static int sip_do_history int  fd,
int  argc,
char *  argv[]
[static]
 

sip_do_history: Enable SIP History logging (CLI) ---

Definition at line 8942 of file chan_sip.c.

References ast_cli(), recordhistory, RESULT_SHOWUSAGE, and RESULT_SUCCESS.

08943 {
08944    if (argc != 2) {
08945       return RESULT_SHOWUSAGE;
08946    }
08947    recordhistory = 1;
08948    ast_cli(fd, "SIP History Recording Enabled (use 'sip show history')\n");
08949    return RESULT_SUCCESS;
08950 }

static int sip_do_reload void   )  [static]
 

sip_do_reload: Reload module

Definition at line 13232 of file chan_sip.c.

References ast_log(), ASTOBJ_CONTAINER_TRAVERSE, ASTOBJ_RDLOCK, authl, clear_realm_authentication(), clear_sip_domains(), LOG_DEBUG, option_debug, regl, and sip_destroy().

Referenced by do_monitor().

13233 {
13234    clear_realm_authentication(authl);
13235    clear_sip_domains();
13236    authl = NULL;
13237 
13238    /* First, destroy all outstanding registry calls */
13239    /* This is needed, since otherwise active registry entries will not be destroyed */
13240    ASTOBJ_CONTAINER_TRAVERSE(&regl, 1, do {
13241       ASTOBJ_RDLOCK(iterator);
13242       if (iterator->call) {
13243          if (option_debug > 2)
13244             ast_log(LOG_DEBUG, "Destroying active SIP dialog for registry %s@%s\n", iterator->username, iterator->hostname);
13245          /* This will also remove references to the registry */
13246          sip_destroy(iterator->call);
13247       }
13248       ASTOBJ_UNLOCK(iterator);
13249    } while(0));
13250 
13251    ASTOBJ_CONTAINER_DESTROYALL(&userl, sip_destroy_user);
13252    ASTOBJ_CONTAINER_DESTROYALL(&regl, sip_registry_destroy);
13253    ASTOBJ_CONTAINER_MARKALL(&peerl);
13254    reload_config();
13255    /* Prune peers who still are supposed to be deleted */
13256    ASTOBJ_CONTAINER_PRUNE_MARKED(&peerl, sip_destroy_peer);
13257 
13258    sip_poke_all_peers();
13259    sip_send_all_registers();
13260 
13261    return 0;
13262 }

static int sip_dtmfmode struct ast_channel chan,
void *  data
[static]
 

sip_dtmfmode: change the DTMFmode for a SIP call (application) ---

Definition at line 12968 of file chan_sip.c.

References ast_clear_flag, ast_dsp_free(), ast_dsp_new(), ast_dsp_set_features(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_set_flag, ast_test_flag, channeltype, DSP_FEATURE_DTMF_DETECT, sip_pvt::lock, ast_channel::lock, LOG_WARNING, SIP_DTMF, SIP_DTMF_INBAND, SIP_DTMF_INFO, SIP_DTMF_RFC2833, ast_channel::tech_pvt, ast_channel::type, and sip_pvt::vad.

Referenced by load_module().

12969 {
12970    struct sip_pvt *p;
12971    char *mode;
12972    if (data)
12973       mode = (char *)data;
12974    else {
12975       ast_log(LOG_WARNING, "This application requires the argument: info, inband, rfc2833\n");
12976       return 0;
12977    }
12978    ast_mutex_lock(&chan->lock);
12979    if (chan->type != channeltype) {
12980       ast_log(LOG_WARNING, "Call this application only on SIP incoming calls\n");
12981       ast_mutex_unlock(&chan->lock);
12982       return 0;
12983    }
12984    p = chan->tech_pvt;
12985    if (!p) {
12986       ast_mutex_unlock(&chan->lock);
12987       return 0;
12988    }
12989    ast_mutex_lock(&p->lock);
12990    if (!strcasecmp(mode,"info")) {
12991       ast_clear_flag(p, SIP_DTMF);
12992       ast_set_flag(p, SIP_DTMF_INFO);
12993    } else if (!strcasecmp(mode,"rfc2833")) {
12994       ast_clear_flag(p, SIP_DTMF);
12995       ast_set_flag(p, SIP_DTMF_RFC2833);
12996    } else if (!strcasecmp(mode,"inband")) { 
12997       ast_clear_flag(p, SIP_DTMF);
12998       ast_set_flag(p, SIP_DTMF_INBAND);
12999    } else
13000       ast_log(LOG_WARNING, "I don't know about this dtmf mode: %s\n",mode);
13001    if (ast_test_flag(p, SIP_DTMF) == SIP_DTMF_INBAND) {
13002       if (!p->vad) {
13003          p->vad = ast_dsp_new();
13004          ast_dsp_set_features(p->vad, DSP_FEATURE_DTMF_DETECT);
13005       }
13006    } else {
13007       if (p->vad) {
13008          ast_dsp_free(p->vad);
13009          p->vad = NULL;
13010       }
13011    }
13012    ast_mutex_unlock(&p->lock);
13013    ast_mutex_unlock(&chan->lock);
13014    return 0;
13015 }

void sip_dump_history struct sip_pvt dialog  )  [static]
 

dump_history: Dump SIP history to debug log file at end of lifespan for SIP dialog

Definition at line 8688 of file chan_sip.c.

References ast_log(), sip_pvt::callid, sip_history::event, sip_pvt::history, LOG_DEBUG, sip_history::next, and sip_pvt::subscribed.

Referenced by __sip_destroy().

08689 {
08690    int x;
08691    struct sip_history *hist;
08692 
08693    if (!dialog)
08694       return;
08695 
08696    ast_log(LOG_DEBUG, "\n---------- SIP HISTORY for '%s' \n", dialog->callid);
08697    if (dialog->subscribed)
08698       ast_log(LOG_DEBUG, "  * Subscription\n");
08699    else
08700       ast_log(LOG_DEBUG, "  * SIP Call\n");
08701    x = 0;
08702    hist = dialog->history;
08703    while(hist) {
08704       x++;
08705       ast_log(LOG_DEBUG, "  %d. %s\n", x, hist->event);
08706       hist = hist->next;
08707    }
08708    if (!x)
08709       ast_log(LOG_DEBUG, "Call '%s' has no history\n", dialog->callid);
08710    ast_log(LOG_DEBUG, "\n---------- END SIP HISTORY for '%s' \n", dialog->callid);
08711    
08712 }

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 2598 of file chan_sip.c.

References ast_log(), ast_mutex_lock(), ast_mutex_unlock(), sip_pvt::lock, LOG_WARNING, sip_pvt::owner, and ast_channel::tech_pvt.

02599 {
02600    struct sip_pvt *p = newchan->tech_pvt;
02601    ast_mutex_lock(&p->lock);
02602    if (p->owner != oldchan) {
02603       ast_log(LOG_WARNING, "old channel wasn't %p but was %p\n", oldchan, p->owner);
02604       ast_mutex_unlock(&p->lock);
02605       return -1;
02606    }
02607    p->owner = newchan;
02608    ast_mutex_unlock(&p->lock);
02609    return 0;
02610 }

static int sip_get_codec struct ast_channel chan  )  [static]
 

sip_get_codec: Return SIP UA's codec (part of the RTP interface) ---

Definition at line 13183 of file chan_sip.c.

References sip_pvt::peercapability, and ast_channel::tech_pvt.

13184 {
13185    struct sip_pvt *p = chan->tech_pvt;
13186    return p->peercapability;  
13187 }

static struct ast_rtp* sip_get_rtp_peer struct ast_channel chan  )  [static]
 

sip_get_rtp_peer: Returns null if we can't reinvite (part of RTP interface)

Definition at line 12868 of file chan_sip.c.

References ast_mutex_lock(), ast_mutex_unlock(), ast_test_flag, sip_pvt::lock, sip_pvt::rtp, SIP_CAN_REINVITE, and ast_channel::tech_pvt.

12869 {
12870    struct sip_pvt *p;
12871    struct ast_rtp *rtp = NULL;
12872    p = chan->tech_pvt;
12873    if (!p)
12874       return NULL;
12875    ast_mutex_lock(&p->lock);
12876    if (p->rtp && ast_test_flag(p, SIP_CAN_REINVITE))
12877       rtp =  p->rtp;
12878    ast_mutex_unlock(&p->lock);
12879    return rtp;
12880 }

static struct ast_rtp* sip_get_vrtp_peer struct ast_channel chan  )  [static]
 

sip_get_vrtp_peer: Returns null if we can't reinvite video (part of RTP interface)

Definition at line 12883 of file chan_sip.c.

References ast_mutex_lock(), ast_mutex_unlock(), ast_test_flag, sip_pvt::lock, SIP_CAN_REINVITE, ast_channel::tech_pvt, and sip_pvt::vrtp.

12884 {
12885    struct sip_pvt *p;
12886    struct ast_rtp *rtp = NULL;
12887    p = chan->tech_pvt;
12888    if (!p)
12889       return NULL;
12890 
12891    ast_mutex_lock(&p->lock);
12892    if (p->vrtp && ast_test_flag(p, SIP_CAN_REINVITE))
12893       rtp = p->vrtp;
12894    ast_mutex_unlock(&p->lock);
12895    return rtp;
12896 }

static int sip_getheader struct ast_channel chan,
void *  data
[static]
 

sip_getheader: Get a SIP header (dialplan app) ---

Definition at line 13049 of file chan_sip.c.

References ast_goto_if_exists(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_strdupa, ast_strlen_zero(), ast_verbose(), channeltype, ast_channel::context, dep_warning, get_header(), sip_pvt::initreq, ast_channel::lock, LOG_DEBUG, LOG_WARNING, option_priority_jumping, option_verbose, sip_pvt::options, pbx_builtin_setvar_helper(), strsep(), ast_channel::tech_pvt, ast_channel::type, and VERBOSE_PREFIX_3.

Referenced by load_module().

13050 {
13051    char *argv, *varname = NULL, *header = NULL, *content, *options = NULL;
13052    static int dep_warning = 0;
13053    struct sip_pvt *p;
13054    int priority_jump = 0;
13055    
13056    if (!dep_warning) {
13057       ast_log(LOG_WARNING, "SIPGetHeader is deprecated, use the SIP_HEADER function instead.\n");
13058       dep_warning = 1;
13059    }
13060 
13061    argv = ast_strdupa(data);
13062    if (!argv) {
13063       ast_log(LOG_DEBUG, "Memory allocation failed\n");
13064       return 0;
13065    }
13066 
13067    if (strchr (argv, '=') ) { /* Pick out argument */
13068       varname = strsep (&argv, "=");
13069       if (strchr(argv, '|')) {
13070          header = strsep (&argv, "|");
13071          options = strsep (&argv, "\0");
13072       } else {
13073          header = strsep (&argv, "\0");
13074       }
13075 
13076    }
13077 
13078    if (!varname || !header) {
13079       ast_log(LOG_DEBUG, "SIPGetHeader: Ignoring command, Syntax error in argument\n");
13080       return 0;
13081    }
13082 
13083    if (options) {
13084       if (strchr(options, 'j'))
13085          priority_jump = 1;
13086    }
13087 
13088    ast_mutex_lock(&chan->lock);
13089    if (chan->type != channeltype) {
13090       ast_log(LOG_WARNING, "Call this application only on incoming SIP calls\n");
13091       ast_mutex_unlock(&chan->lock);
13092       return 0;
13093    }
13094 
13095    p = chan->tech_pvt;
13096    content = get_header(&p->initreq, header);   /* Get the header */
13097    if (!ast_strlen_zero(content)) {
13098       pbx_builtin_setvar_helper(chan, varname, content);
13099       if (option_verbose > 2)
13100          ast_verbose(VERBOSE_PREFIX_3 "SIPGetHeader: set variable %s to %s\n", varname, content);
13101       pbx_builtin_setvar_helper(chan, "SIPGETSTATUS", "FOUND");
13102    } else {
13103       ast_log(LOG_WARNING,"SIP Header %s not found for channel variable %s\n", header, varname);
13104       if (priority_jump || option_priority_jumping) {
13105          /* Goto priority n+101 if it exists, where n is the current priority number */
13106          ast_goto_if_exists(chan, chan->context, chan->exten, chan->priority + 101);
13107       }
13108       pbx_builtin_setvar_helper(chan, "SIPGETSTATUS", "NOTFOUND");
13109    }
13110    
13111    ast_mutex_unlock(&chan->lock);
13112    return 0;
13113 }

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 2404 of file chan_sip.c.

References __sip_pretend_ack(), ast_channel::_state, AST_CAUSE_NORMAL, ast_clear_flag, ast_copy_flags, ast_dsp_free(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_osp_terminate(), ast_set_flag, AST_STATE_UP, ast_strlen_zero(), ast_test_flag, ast_update_use_count(), sip_pvt::callid, sip_request::data, DEC_CALL_LIMIT, hangup_cause2sip(), ast_channel::hangupcause, INC_CALL_LIMIT, sip_pvt::initreq, sip_pvt::lock, LOG_DEBUG, LOG_WARNING, ast_channel::name, option_debug, sip_pvt::owner, sip_pvt::pendinginvite, SIP_ALREADYGONE, SIP_BYE, SIP_CAN_BYE, SIP_CANCEL, SIP_NEEDDESTROY, SIP_NEEDREINVITE, SIP_OUTGOING, SIP_PENDINGBYE, sip_scheddestroy(), ast_channel::tech_pvt, transmit_request_with_auth(), transmit_response_reliable(), update_call_counter(), usecnt, usecnt_lock, sip_pvt::username, and sip_pvt::vad.

02405 {
02406    struct sip_pvt *p = ast->tech_pvt;
02407    int needcancel = 0;
02408    struct ast_flags locflags = {0};
02409 
02410    if (!p) {
02411       ast_log(LOG_DEBUG, "Asked to hangup channel not connected\n");
02412       return 0;
02413    }
02414    if (option_debug)
02415       ast_log(LOG_DEBUG, "Hangup call %s, SIP callid %s)\n", ast->name, p->callid);
02416 
02417    ast_mutex_lock(&p->lock);
02418 #ifdef OSP_SUPPORT
02419    if ((p->osphandle > -1) && (ast->_state == AST_STATE_UP)) {
02420       ast_osp_terminate(p->osphandle, AST_CAUSE_NORMAL, p->ospstart, time(NULL) - p->ospstart);
02421    }
02422 #endif   
02423    ast_log(LOG_DEBUG, "update_call_counter(%s) - decrement call limit counter\n", p->username);
02424    update_call_counter(p, DEC_CALL_LIMIT);
02425    /* Determine how to disconnect */
02426    if (p->owner != ast) {
02427       ast_log(LOG_WARNING, "Huh?  We aren't the owner? Can't hangup call.\n");
02428       ast_mutex_unlock(&p->lock);
02429       return 0;
02430    }
02431    /* If the call is not UP, we need to send CANCEL instead of BYE */
02432    if (ast->_state != AST_STATE_UP)
02433       needcancel = 1;
02434 
02435    /* Disconnect */
02436    p = ast->tech_pvt;
02437    if (p->vad) {
02438       ast_dsp_free(p->vad);
02439    }
02440    p->owner = NULL;
02441    ast->tech_pvt = NULL;
02442 
02443    ast_mutex_lock(&usecnt_lock);
02444    usecnt--;
02445    ast_mutex_unlock(&usecnt_lock);
02446    ast_update_use_count();
02447 
02448    ast_set_flag(&locflags, SIP_NEEDDESTROY); 
02449 
02450    /* Start the process if it's not already started */
02451    if (!ast_test_flag(p, SIP_ALREADYGONE) && !ast_strlen_zero(p->initreq.data)) {
02452       if (needcancel) { /* Outgoing call, not up */
02453          if (ast_test_flag(p, SIP_OUTGOING)) {
02454             /* stop retransmitting an INVITE that has not received a response */
02455             __sip_pretend_ack(p);
02456 
02457             /* are we allowed to send CANCEL yet? if not, mark
02458                it pending */
02459             if (!ast_test_flag(p, SIP_CAN_BYE)) {
02460                ast_set_flag(p, SIP_PENDINGBYE);
02461             } else {
02462                /* Send a new request: CANCEL */
02463                transmit_request_with_auth(p, SIP_CANCEL, p->ocseq, 1, 0);
02464                /* Actually don't destroy us yet, wait for the 487 on our original 
02465                   INVITE, but do set an autodestruct just in case we never get it. */
02466                ast_clear_flag(&locflags, SIP_NEEDDESTROY);
02467                sip_scheddestroy(p, 32000);
02468             }
02469             if ( p->initid != -1 ) {
02470                /* channel still up - reverse dec of inUse counter
02471                   only if the channel is not auto-congested */
02472                update_call_counter(p, INC_CALL_LIMIT);
02473             }
02474          } else { /* Incoming call, not up */
02475             char *res;
02476             if (ast->hangupcause && ((res = hangup_cause2sip(ast->hangupcause)))) {
02477                transmit_response_reliable(p, res, &p->initreq, 1);
02478             } else 
02479                transmit_response_reliable(p, "603 Declined", &p->initreq, 1);
02480          }
02481       } else { /* Call is in UP state, send BYE */
02482          if (!p->pendinginvite) {
02483             /* Send a hangup */
02484             transmit_request_with_auth(p, SIP_BYE, 0, 1, 1);
02485          } else {
02486             /* Note we will need a BYE when this all settles out
02487                but we can't send one while we have "INVITE" outstanding. */
02488             ast_set_flag(p, SIP_PENDINGBYE); 
02489             ast_clear_flag(p, SIP_NEEDREINVITE);   
02490          }
02491       }
02492    }
02493    ast_copy_flags(p, (&locflags), SIP_NEEDDESTROY);   
02494    ast_mutex_unlock(&p->lock);
02495    return 0;
02496 }

static int sip_indicate struct ast_channel ast,
int  condition
[static]
 

sip_indicate: Play indication to user With SIP a lot of indications is sent as messages, letting the device play the indication - busy signal, congestion etc

Definition at line 2655 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_UNHOLD, AST_CONTROL_VIDUPDATE, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_set_flag, AST_SOFTHANGUP_DEV, ast_softhangup_nolock(), AST_STATE_RING, AST_STATE_UP, ast_test_flag, sip_pvt::callid, sip_pvt::initreq, sip_pvt::lock, LOG_DEBUG, LOG_WARNING, SIP_ALREADYGONE, SIP_NOVIDEO, SIP_OUTGOING, SIP_PROG_INBAND, SIP_PROG_INBAND_NEVER, SIP_PROG_INBAND_YES, SIP_PROGRESS_SENT, SIP_RINGING, sipdebug, ast_channel::tech_pvt, transmit_info_with_vidupdate(), transmit_response(), transmit_response_with_sdp(), and sip_pvt::vrtp.

02656 {
02657    struct sip_pvt *p = ast->tech_pvt;
02658    int res = 0;
02659 
02660    ast_mutex_lock(&p->lock);
02661    switch(condition) {
02662    case AST_CONTROL_RINGING:
02663       if (ast->_state == AST_STATE_RING) {
02664          if (!ast_test_flag(p, SIP_PROGRESS_SENT) ||
02665              (ast_test_flag(p, SIP_PROG_INBAND) == SIP_PROG_INBAND_NEVER)) {
02666             /* Send 180 ringing if out-of-band seems reasonable */
02667             transmit_response(p, "180 Ringing", &p->initreq);
02668             ast_set_flag(p, SIP_RINGING);
02669             if (ast_test_flag(p, SIP_PROG_INBAND) != SIP_PROG_INBAND_YES)
02670                break;
02671          } else {
02672             /* Well, if it's not reasonable, just send in-band */
02673          }
02674       }
02675       res = -1;
02676       break;
02677    case AST_CONTROL_BUSY:
02678       if (ast->_state != AST_STATE_UP) {
02679          transmit_response(p, "486 Busy Here", &p->initreq);
02680          ast_set_flag(p, SIP_ALREADYGONE);   
02681          ast_softhangup_nolock(ast, AST_SOFTHANGUP_DEV);
02682          break;
02683       }
02684       res = -1;
02685       break;
02686    case AST_CONTROL_CONGESTION:
02687       if (ast->_state != AST_STATE_UP) {
02688          transmit_response(p, "503 Service Unavailable", &p->initreq);
02689          ast_set_flag(p, SIP_ALREADYGONE);   
02690          ast_softhangup_nolock(ast, AST_SOFTHANGUP_DEV);
02691          break;
02692       }
02693       res = -1;
02694       break;
02695    case AST_CONTROL_PROCEEDING:
02696       if ((ast->_state != AST_STATE_UP) && !ast_test_flag(p, SIP_PROGRESS_SENT) && !ast_test_flag(p, SIP_OUTGOING)) {
02697          transmit_response(p, "100 Trying", &p->initreq);
02698          break;
02699       }
02700       res = -1;
02701       break;
02702    case AST_CONTROL_PROGRESS:
02703       if ((ast->_state != AST_STATE_UP) && !ast_test_flag(p, SIP_PROGRESS_SENT) && !ast_test_flag(p, SIP_OUTGOING)) {
02704          transmit_response_with_sdp(p, "183 Session Progress", &p->initreq, 0);
02705          ast_set_flag(p, SIP_PROGRESS_SENT); 
02706          break;
02707       }
02708       res = -1;
02709       break;
02710    case AST_CONTROL_HOLD:  /* The other part of the bridge are put on hold */
02711       if (sipdebug)
02712          ast_log(LOG_DEBUG, "Bridged channel now on hold%s\n", p->callid);
02713       res = -1;
02714       break;
02715    case AST_CONTROL_UNHOLD:   /* The other part of the bridge are back from hold */
02716       if (sipdebug)
02717          ast_log(LOG_DEBUG, "Bridged channel is back from hold, let's talk! : %s\n", p->callid);
02718       res = -1;
02719       break;
02720    case AST_CONTROL_VIDUPDATE:   /* Request a video frame update */
02721       if (p->vrtp && !ast_test_flag(p, SIP_NOVIDEO)) {
02722          transmit_info_with_vidupdate(p);
02723          res = 0;
02724       } else
02725          res = -1;
02726       break;
02727    case -1:
02728       res = -1;
02729       break;
02730    default:
02731       ast_log(LOG_WARNING, "Don't know how to indicate condition %d\n", condition);
02732       res = -1;
02733       break;
02734    }
02735    ast_mutex_unlock(&p->lock);
02736    return res;
02737 }

static struct ast_channel* sip_new struct sip_pvt i,
int  state,
char *  title
[static]
 

sip_new: Initiate a call in the SIP channel

Definition at line 2743 of file chan_sip.c.

References ast_channel::accountcode, ast_channel::adsicpe, ast_channel::amaflags, AST_ADSI_UNAVAILABLE, ast_best_codec(), ast_channel_alloc(), ast_codec_choose(), ast_dsp_digitmode(), ast_dsp_new(), ast_dsp_set_features(), ast_hangup(), ast_inet_ntoa(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_pbx_start(), ast_rtcp_fd(), ast_rtp_fd(), ast_set_callerid(), ast_setstate(), AST_STATE_DOWN, AST_STATE_RING, ast_strlen_zero(), ast_test_flag, ast_channel::callgroup, sip_pvt::capability, channeltype, ast_channel::cid, ast_callerid::cid_dnid, ast_callerid::cid_pres, ast_callerid::cid_rdnis, ast_channel::context, DSP_DIGITMODE_DTMF, DSP_DIGITMODE_RELAXDTMF, DSP_FEATURE_DTMF_DETECT, ast_channel::exten, ast_channel::fds, fmt, global_capability, sip_pvt::jointcapability, ast_channel::language, sip_pvt::lock, LOG_WARNING, ast_channel::musicclass, ast_variable::name, ast_channel::name, ast_channel::nativeformats, ast_variable::next, pbx_builtin_setvar_helper(), ast_channel::pickupgroup, sip_pvt::prefs, ast_channel::priority, ast_channel::rawreadformat, ast_channel::rawwriteformat, ast_channel::readformat, relaxdtmf, ast_channel::rings, SIP_DTMF, SIP_DTMF_INBAND, strdup, ast_channel::tech, ast_channel::tech_pvt, ast_channel::type, usecnt, usecnt_lock, ast_variable::value, and ast_channel::writeformat.

Referenced by handle_request_invite(), and sip_request_call().

02744 {
02745    struct ast_channel *tmp;
02746    struct ast_variable *v = NULL;
02747    int fmt;
02748 #ifdef OSP_SUPPORT
02749    char iabuf[INET_ADDRSTRLEN];
02750    char peer[MAXHOSTNAMELEN];
02751 #endif   
02752    
02753    ast_mutex_unlock(&i->lock);
02754    /* Don't hold a sip pvt lock while we allocate a channel */
02755    tmp = ast_channel_alloc(1);
02756    ast_mutex_lock(&i->lock);
02757    if (!tmp) {
02758       ast_log(LOG_WARNING, "Unable to allocate SIP channel structure\n");
02759       return NULL;
02760    }
02761    tmp->tech = &sip_tech;
02762    /* Select our native format based on codec preference until we receive
02763       something from another device to the contrary. */
02764    if (i->jointcapability)
02765       tmp->nativeformats = ast_codec_choose(&i->prefs, i->jointcapability, 1);
02766    else if (i->capability)
02767       tmp->nativeformats = ast_codec_choose(&i->prefs, i->capability, 1);
02768    else
02769       tmp->nativeformats = ast_codec_choose(&i->prefs, global_capability, 1);
02770    fmt = ast_best_codec(tmp->nativeformats);
02771 
02772    if (title)
02773       snprintf(tmp->name, sizeof(tmp->name), "SIP/%s-%08x", title, (int)(long) i);
02774    else if (strchr(i->fromdomain,':'))
02775       snprintf(tmp->name, sizeof(tmp->name), "SIP/%s-%08x", strchr(i->fromdomain,':') + 1, (int)(long) i);
02776    else
02777       snprintf(tmp->name, sizeof(tmp->name), "SIP/%s-%08x", i->fromdomain, (int)(long) i);
02778 
02779    tmp->type = channeltype;
02780    if (ast_test_flag(i, SIP_DTMF) ==  SIP_DTMF_INBAND) {
02781       i->vad = ast_dsp_new();
02782       ast_dsp_set_features(i->vad, DSP_FEATURE_DTMF_DETECT);
02783       if (relaxdtmf)
02784          ast_dsp_digitmode(i->vad, DSP_DIGITMODE_DTMF | DSP_DIGITMODE_RELAXDTMF);
02785    }
02786    if (i->rtp) {
02787       tmp->fds[0] = ast_rtp_fd(i->rtp);
02788       tmp->fds[1] = ast_rtcp_fd(i->rtp);
02789    }
02790    if (i->vrtp) {
02791       tmp->fds[2] = ast_rtp_fd(i->vrtp);
02792       tmp->fds[3] = ast_rtcp_fd(i->vrtp);
02793    }
02794    if (state == AST_STATE_RING)
02795       tmp->rings = 1;
02796    tmp->adsicpe = AST_ADSI_UNAVAILABLE;
02797    tmp->writeformat = fmt;
02798    tmp->rawwriteformat = fmt;
02799    tmp->readformat = fmt;
02800    tmp->rawreadformat = fmt;
02801    tmp->tech_pvt = i;
02802 
02803    tmp->callgroup = i->callgroup;
02804    tmp->pickupgroup = i->pickupgroup;
02805    tmp->cid.cid_pres = i->callingpres;
02806    if (!ast_strlen_zero(i->accountcode))
02807       ast_copy_string(tmp->accountcode, i->accountcode, sizeof(tmp->accountcode));
02808    if (i->amaflags)
02809       tmp->amaflags = i->amaflags;
02810    if (!ast_strlen_zero(i->language))
02811       ast_copy_string(tmp->language, i->language, sizeof(tmp->language));
02812    if (!ast_strlen_zero(i->musicclass))
02813       ast_copy_string(tmp->musicclass, i->musicclass, sizeof(tmp->musicclass));
02814    i->owner = tmp;
02815    ast_mutex_lock(&usecnt_lock);
02816    usecnt++;
02817    ast_mutex_unlock(&usecnt_lock);
02818    ast_copy_string(tmp->context, i->context, sizeof(tmp->context));
02819    ast_copy_string(tmp->exten, i->exten, sizeof(tmp->exten));
02820    ast_set_callerid(tmp, i->cid_num, i->cid_name, i->cid_num);
02821    if (!ast_strlen_zero(i->rdnis))
02822       tmp->cid.cid_rdnis = strdup(i->rdnis);
02823    if (!ast_strlen_zero(i->exten) && strcmp(i->exten, "s"))
02824       tmp->cid.cid_dnid = strdup(i->exten);
02825    tmp->priority = 1;
02826    if (!ast_strlen_zero(i->uri)) {
02827       pbx_builtin_setvar_helper(tmp, "SIPURI", i->uri);
02828    }
02829    if (!ast_strlen_zero(i->domain)) {
02830       pbx_builtin_setvar_helper(tmp, "SIPDOMAIN", i->domain);
02831    }
02832    if (!ast_strlen_zero(i->useragent)) {
02833       pbx_builtin_setvar_helper(tmp, "SIPUSERAGENT", i->useragent);
02834    }
02835    if (!ast_strlen_zero(i->callid)) {
02836       pbx_builtin_setvar_helper(tmp, "SIPCALLID", i->callid);
02837    }
02838 #ifdef OSP_SUPPORT
02839    snprintf(peer, sizeof(peer), "[%s]:%d", ast_inet_ntoa(iabuf, sizeof(iabuf), i->sa.sin_addr), ntohs(i->sa.sin_port));
02840    pbx_builtin_setvar_helper(tmp, "OSPPEER", peer);
02841 #endif
02842    ast_setstate(tmp, state);
02843    if (state != AST_STATE_DOWN) {
02844       if (ast_pbx_start(tmp)) {
02845          ast_log(LOG_WARNING, "Unable to start PBX on %s\n", tmp->name);
02846          ast_hangup(tmp);
02847          tmp = NULL;
02848       }
02849    }
02850    /* Set channel variables for this call from configuration */
02851    for (v = i->chanvars ; v ; v = v->next)
02852       pbx_builtin_setvar_helper(tmp,v->name,v->value);
02853             
02854    return tmp;
02855 }

static int sip_no_debug int  fd,
int  argc,
char *  argv[]
[static]
 

sip_no_debug: Disable SIP Debugging in CLI ---

Definition at line 8964 of file chan_sip.c.

References ast_cli(), RESULT_SHOWUSAGE, RESULT_SUCCESS, SIP_DEBUG_CONSOLE, and sipdebug.

08966 {
08967    if (argc != 3)
08968       return RESULT_SHOWUSAGE;
08969    sipdebug &= ~SIP_DEBUG_CONSOLE;
08970    ast_cli(fd, "SIP Debugging Disabled\n");
08971    return RESULT_SUCCESS;
08972 }

static int sip_no_history int  fd,
int  argc,
char *  argv[]
[static]
 

sip_no_history: Disable SIP History logging (CLI) ---

Definition at line 8953 of file chan_sip.c.

References ast_cli(), recordhistory, RESULT_SHOWUSAGE, and RESULT_SUCCESS.

08954 {
08955    if (argc != 3) {
08956       return RESULT_SHOWUSAGE;
08957    }
08958    recordhistory = 0;
08959    ast_cli(fd, "SIP History Recording Disabled\n");
08960    return RESULT_SUCCESS;
08961 }

static int sip_notify int  fd,
int  argc,
char *  argv[]
[static]
 

sip_notify: Send SIP notify to peer

Definition at line 8885 of file chan_sip.c.

References __ourip, add_blank_header(), add_header(), ast_cli(), ast_log(), ast_sip_ouraddrfor(), ast_variable_browse(), build_callid(), build_via(), sip_pvt::callid, create_addr(), sip_pvt::fromdomain, initreqprep(), LOG_WARNING, ast_variable::name, ast_variable::next, notify_config, notify_types, sip_pvt::ourip, RESULT_FAILURE, RESULT_SHOWUSAGE, RESULT_SUCCESS, sip_pvt::sa, sip_alloc(), sip_destroy(), SIP_NOTIFY, sip_scheddestroy(), transmit_sip_request(), ast_variable::value, var, and sip_pvt::via.

08886 {
08887    struct ast_variable *varlist;
08888    int i;
08889 
08890    if (argc < 4)
08891       return RESULT_SHOWUSAGE;
08892 
08893    if (!notify_types) {
08894       ast_cli(fd, "No %s file found, or no types listed there\n", notify_config);
08895       return RESULT_FAILURE;
08896    }
08897 
08898    varlist = ast_variable_browse(notify_types, argv[2]);
08899 
08900    if (!varlist) {
08901       ast_cli(fd, "Unable to find notify type '%s'\n", argv[2]);
08902       return RESULT_FAILURE;
08903    }
08904 
08905    for (i = 3; i < argc; i++) {
08906       struct sip_pvt *p;
08907       struct sip_request req;
08908       struct ast_variable *var;
08909 
08910       p = sip_alloc(NULL, NULL, 0, SIP_NOTIFY);
08911       if (!p) {
08912          ast_log(LOG_WARNING, "Unable to build sip pvt data for notify\n");
08913          return RESULT_FAILURE;
08914       }
08915 
08916       if (create_addr(p, argv[i])) {
08917          /* Maybe they're not registered, etc. */
08918          sip_destroy(p);
08919          ast_cli(fd, "Could not create address for '%s'\n", argv[i]);
08920          continue;
08921       }
08922 
08923       initreqprep(&req, p, SIP_NOTIFY);
08924 
08925       for (var = varlist; var; var = var->next)
08926          add_header(&req, var->name, var->value);
08927 
08928       add_blank_header(&req);
08929       /* Recalculate our side, and recalculate Call ID */
08930       if (ast_sip_ouraddrfor(&p->sa.sin_addr, &p->ourip))
08931          memcpy(&p->ourip, &__ourip, sizeof(p->ourip));
08932       build_via(p, p->via, sizeof(p->via));
08933       build_callid(p->callid, sizeof(p->callid), p->ourip, p->fromdomain);
08934       ast_cli(fd, "Sending NOTIFY of type '%s' to '%s'\n", argv[2], argv[i]);
08935       transmit_sip_request(p, &req);
08936       sip_scheddestroy(p, 15000);
08937    }
08938 
08939    return RESULT_SUCCESS;
08940 }

static int sip_park struct ast_channel chan1,
struct ast_channel chan2,
struct sip_request req
[static]
 

sip_park: Park a call ---

Definition at line 10206 of file chan_sip.c.

References ast_channel_alloc(), ast_channel_masquerade(), ast_do_masquerade(), ast_hangup(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_pthread_create, ast_channel::context, copy_request(), ast_channel::exten, free, ast_channel::lock, LOG_WARNING, malloc, ast_channel::name, ast_channel::priority, ast_channel::readformat, sip_park_thread(), and ast_channel::writeformat.

Referenced by handle_request_refer().

10207 {
10208    struct sip_dual *d;
10209    struct ast_channel *chan1m, *chan2m;
10210    pthread_t th;
10211    chan1m = ast_channel_alloc(0);
10212    chan2m = ast_channel_alloc(0);
10213    if ((!chan2m) || (!chan1m)) {
10214       if (chan1m)
10215          ast_hangup(chan1m);
10216       if (chan2m)
10217          ast_hangup(chan2m);
10218       return -1;
10219    }
10220    snprintf(chan1m->name, sizeof(chan1m->name), "Parking/%s", chan1->name);
10221    /* Make formats okay */
10222    chan1m->readformat = chan1->readformat;
10223    chan1m->writeformat = chan1->writeformat;
10224    ast_channel_masquerade(chan1m, chan1);
10225    /* Setup the extensions and such */
10226    ast_copy_string(chan1m->context, chan1->context, sizeof(chan1m->context));
10227    ast_copy_string(chan1m->exten, chan1->exten, sizeof(chan1m->exten));
10228    chan1m->priority = chan1->priority;
10229       
10230    /* We make a clone of the peer channel too, so we can play
10231       back the announcement */
10232    snprintf(chan2m->name, sizeof (chan2m->name), "SIPPeer/%s",chan2->name);
10233    /* Make formats okay */
10234    chan2m->readformat = chan2->readformat;
10235    chan2m->writeformat = chan2->writeformat;
10236    ast_channel_masquerade(chan2m, chan2);
10237    /* Setup the extensions and such */
10238    ast_copy_string(chan2m->context, chan2->context, sizeof(chan2m->context));
10239    ast_copy_string(chan2m->exten, chan2->exten, sizeof(chan2m->exten));
10240    chan2m->priority = chan2->priority;
10241    ast_mutex_lock(&chan2m->lock);
10242    if (ast_do_masquerade(chan2m)) {
10243       ast_log(LOG_WARNING, "Masquerade failed :(\n");
10244       ast_mutex_unlock(&chan2m->lock);
10245       ast_hangup(chan2m);
10246       return -1;
10247    }
10248    ast_mutex_unlock(&chan2m->lock);
10249    d = malloc(sizeof(struct sip_dual));
10250    if (d) {
10251       memset(d, 0, sizeof(*d));
10252       /* Save original request for followup */
10253       copy_request(&d->req, req);
10254       d->chan1 = chan1m;
10255       d->chan2 = chan2m;
10256       if (!ast_pthread_create(&th, NULL, sip_park_thread, d))
10257          return 0;
10258       free(d);
10259    }
10260    return -1;
10261 }

static void* sip_park_thread void *  stuff  )  [static]
 

sip_park_thread: Park SIP call support function

Definition at line 10183 of file chan_sip.c.

References ast_do_masquerade(), ast_hangup(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_park_call(), sip_dual::chan1, sip_dual::chan2, copy_request(), free, ast_channel::lock, LOG_DEBUG, and sip_dual::req.

Referenced by sip_park().

10184 {
10185    struct ast_channel *chan1, *chan2;
10186    struct sip_dual *d;
10187    struct sip_request req;
10188    int ext;
10189    int res;
10190    d = stuff;
10191    chan1 = d->chan1;
10192    chan2 = d->chan2;
10193    copy_request(&req, &d->req);
10194    free(d);
10195    ast_mutex_lock(&chan1->lock);
10196    ast_do_masquerade(chan1);
10197    ast_mutex_unlock(&chan1->lock);
10198    res = ast_park_call(chan1, chan2, 0, &ext);
10199    /* Then hangup */
10200    ast_hangup(chan2);
10201    ast_log(LOG_DEBUG, "Parked on extension '%d'\n", ext);
10202    return NULL;
10203 }

static void sip_poke_all_peers void   )  [static]
 

sip_poke_all_peers: Send a poke to all known peers

Definition at line 13199 of file chan_sip.c.

References ASTOBJ_CONTAINER_TRAVERSE, ASTOBJ_UNLOCK, ASTOBJ_WRLOCK, peerl, and sip_poke_peer().

Referenced by load_module().

13200 {
13201    ASTOBJ_CONTAINER_TRAVERSE(&peerl, 1, do {
13202       ASTOBJ_WRLOCK(iterator);
13203       sip_poke_peer(iterator);
13204       ASTOBJ_UNLOCK(iterator);
13205    } while (0)
13206    );
13207 }

static int sip_poke_noanswer void *  data  )  [static]
 

sip_poke_noanswer: No answer to Qualify poke ---

Definition at line 11558 of file chan_sip.c.

References ast_device_state_changed(), ast_log(), ast_sched_add(), sip_peer::call, DEFAULT_FREQ_NOTOK, EVENT_FLAG_SYSTEM, sip_peer::lastms, LOG_NOTICE, manager_event(), sip_peer::pokeexpire, sip_destroy(), and sip_poke_peer_s().

Referenced by sip_poke_peer().

11559 {
11560    struct sip_peer *peer = data;
11561    
11562    peer->pokeexpire = -1;
11563    if (peer->lastms > -1) {
11564       ast_log(LOG_NOTICE, "Peer '%s' is now UNREACHABLE!  Last qualify: %d\n", peer->name, peer->lastms);
11565       manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: SIP/%s\r\nPeerStatus: Unreachable\r\nTime: %d\r\n", peer->name, -1);
11566    }
11567    if (peer->call)
11568       sip_destroy(peer->call);
11569    peer->call = NULL;
11570    peer->lastms = -1;
11571    ast_device_state_changed("SIP/%s", peer->name);
11572    /* Try again quickly */
11573    peer->pokeexpire = ast_sched_add(sched, DEFAULT_FREQ_NOTOK, sip_poke_peer_s, peer);
11574    return 0;
11575 }

static int sip_poke_peer struct sip_peer peer  )  [static]
 

sip_poke_peer: Check availability of peer, also keep NAT open ---

Definition at line 11580 of file chan_sip.c.

References __ourip, sip_peer::addr, ast_copy_flags, ast_inet_ntoa(), ast_log(), ast_sched_add(), ast_sched_del(), ast_set_flag, ast_sip_ouraddrfor(), ast_strlen_zero(), build_callid(), build_via(), sip_peer::call, sip_pvt::callid, DEFAULT_MAXMS, sip_pvt::fromdomain, sip_pvt::fullcontact, sip_peer::fullcontact, sip_peer::lastms, LOG_NOTICE, LOG_WARNING, sip_peer::maxms, sip_pvt::ourip, sip_pvt::peerpoke, sip_peer::pokeexpire, sip_peer::ps, sip_pvt::recv, sip_pvt::sa, sip_alloc(), sip_destroy(), SIP_FLAGS_TO_COPY, SIP_INVITE, SIP_OPTIONS, SIP_OUTGOING, sip_poke_noanswer(), sipdebug, sip_pvt::tohost, sip_peer::tohost, transmit_invite(), sip_pvt::username, and sip_pvt::via.

Referenced by parse_register_contact(), reg_source_db(), sip_poke_all_peers(), and sip_poke_peer_s().

11581 {
11582    struct sip_pvt *p;
11583    if (!peer->maxms || !peer->addr.sin_addr.s_addr) {
11584       /* IF we have no IP, or this isn't to be monitored, return
11585         imeediately after clearing things out */
11586       if (peer->pokeexpire > -1)
11587          ast_sched_del(sched, peer->pokeexpire);
11588       peer->lastms = 0;
11589       peer->pokeexpire = -1;
11590       peer->call = NULL;
11591       return 0;
11592    }
11593    if (peer->call > 0) {
11594       if (sipdebug)
11595          ast_log(LOG_NOTICE, "Still have a QUALIFY dialog active, deleting\n");
11596       sip_destroy(peer->call);
11597    }
11598    p = peer->call = sip_alloc(NULL, NULL, 0, SIP_OPTIONS);
11599    if (!peer->call) {
11600       ast_log(LOG_WARNING, "Unable to allocate dialog for poking peer '%s'\n", peer->name);
11601       return -1;
11602    }
11603    memcpy(&p->sa, &peer->addr, sizeof(p->sa));
11604    memcpy(&p->recv, &peer->addr, sizeof(p->sa));
11605    ast_copy_flags(p, peer, SIP_FLAGS_TO_COPY);
11606 
11607    /* Send OPTIONs to peer's fullcontact */
11608    if (!ast_strlen_zero(peer->fullcontact)) {
11609       ast_copy_string (p->fullcontact, peer->fullcontact, sizeof(p->fullcontact));
11610    }
11611 
11612    if (!ast_strlen_zero(peer->tohost))
11613       ast_copy_string(p->tohost, peer->tohost, sizeof(p->tohost));
11614    else
11615       ast_inet_ntoa(p->tohost, sizeof(p->tohost), peer->addr.sin_addr);
11616 
11617    /* Recalculate our side, and recalculate Call ID */
11618    if (ast_sip_ouraddrfor(&p->sa.sin_addr,&p->ourip))
11619       memcpy(&p->ourip, &__ourip, sizeof(p->ourip));
11620    build_via(p, p->via, sizeof(p->via));
11621    build_callid(p->callid, sizeof(p->callid), p->ourip, p->fromdomain);
11622 
11623    if (peer->pokeexpire > -1)
11624       ast_sched_del(sched, peer->pokeexpire);
11625    p->peerpoke = peer;
11626    ast_set_flag(p, SIP_OUTGOING);
11627 #ifdef VOCAL_DATA_HACK
11628    ast_copy_string(p->username, "__VOCAL_DATA_SHOULD_READ_THE_SIP_SPEC__", sizeof(p->username));
11629    transmit_invite(p, SIP_INVITE, 0, 2);
11630 #else
11631    transmit_invite(p, SIP_OPTIONS, 0, 2);
11632 #endif
11633    gettimeofday(&peer->ps, NULL);
11634    peer->pokeexpire = ast_sched_add(sched, DEFAULT_MAXMS * 2, sip_poke_noanswer, peer);
11635 
11636    return 0;
11637 }

static int sip_poke_peer_s void *  data  )  [static]
 

Definition at line 5743 of file chan_sip.c.

References sip_peer::pokeexpire, and sip_poke_peer().

Referenced by handle_response_peerpoke(), reg_source_db(), and sip_poke_noanswer().

05744 {
05745    struct sip_peer *peer = data;
05746    peer->pokeexpire = -1;
05747    sip_poke_peer(peer);
05748    return 0;
05749 }

static int sip_prune_realtime int  fd,
int  argc,
char *  argv[]
[static]
 

sip_prune_realtime: Remove temporary realtime objects from memory (CLI) ---

Definition at line 7757 of file chan_sip.c.

References ast_cli(), ast_test_flag, ASTOBJ_CONTAINER_FIND_UNLINK, ASTOBJ_CONTAINER_LINK, ASTOBJ_CONTAINER_PRUNE_MARKED, ASTOBJ_CONTAINER_TRAVERSE, ASTOBJ_CONTAINER_UNLOCK, ASTOBJ_CONTAINER_WRLOCK, ASTOBJ_MARK, ASTOBJ_RDLOCK, ASTOBJ_UNLOCK, ASTOBJ_UNREF, sip_user::flags_page2, sip_peer::flags_page2, name, peerl, RESULT_SHOWUSAGE, RESULT_SUCCESS, sip_destroy_peer(), sip_destroy_user(), SIP_PAGE2_RTCACHEFRIENDS, user, and userl.

07758 {
07759    struct sip_peer *peer;
07760    struct sip_user *user;
07761    int pruneuser = 0;
07762    int prunepeer = 0;
07763    int multi = 0;
07764    char *name = NULL;
07765    regex_t regexbuf;
07766 
07767    switch (argc) {
07768    case 4:
07769       if (!strcasecmp(argv[3], "user"))
07770          return RESULT_SHOWUSAGE;
07771       if (!strcasecmp(argv[3], "peer"))
07772          return RESULT_SHOWUSAGE;
07773       if (!strcasecmp(argv[3], "like"))
07774          return RESULT_SHOWUSAGE;
07775       if (!strcasecmp(argv[3], "all")) {
07776          multi = 1;
07777          pruneuser = prunepeer = 1;
07778       } else {
07779          pruneuser = prunepeer = 1;
07780          name = argv[3];
07781       }
07782       break;
07783    case 5:
07784       if (!strcasecmp(argv[4], "like"))
07785          return RESULT_SHOWUSAGE;
07786       if (!strcasecmp(argv[3], "all"))
07787          return RESULT_SHOWUSAGE;
07788       if (!strcasecmp(argv[3], "like")) {
07789          multi = 1;
07790          name = argv[4];
07791          pruneuser = prunepeer = 1;
07792       } else if (!strcasecmp(argv[3], "user")) {
07793          pruneuser = 1;
07794          if (!strcasecmp(argv[4], "all"))
07795             multi = 1;
07796          else
07797             name = argv[4];
07798       } else if (!strcasecmp(argv[3], "peer")) {
07799          prunepeer = 1;
07800          if (!strcasecmp(argv[4], "all"))
07801             multi = 1;
07802          else
07803             name = argv[4];
07804       } else
07805          return RESULT_SHOWUSAGE;
07806       break;
07807    case 6:
07808       if (strcasecmp(argv[4], "like"))
07809          return RESULT_SHOWUSAGE;
07810       if (!strcasecmp(argv[3], "user")) {
07811          pruneuser = 1;
07812          name = argv[5];
07813       } else if (!strcasecmp(argv[3], "peer")) {
07814          prunepeer = 1;
07815          name = argv[5];
07816       } else
07817          return RESULT_SHOWUSAGE;
07818       break;
07819    default:
07820       return RESULT_SHOWUSAGE;
07821    }
07822 
07823    if (multi && name) {
07824       if (regcomp(&regexbuf, name, REG_EXTENDED | REG_NOSUB))
07825          return RESULT_SHOWUSAGE;
07826    }
07827 
07828    if (multi) {
07829       if (prunepeer) {
07830          int pruned = 0;
07831 
07832          ASTOBJ_CONTAINER_WRLOCK(&peerl);
07833          ASTOBJ_CONTAINER_TRAVERSE(&peerl, 1, do {
07834             ASTOBJ_RDLOCK(iterator);
07835             if (name && regexec(&regexbuf, iterator->name, 0, NULL, 0)) {
07836                ASTOBJ_UNLOCK(iterator);
07837                continue;
07838             };
07839             if (ast_test_flag((&iterator->flags_page2), SIP_PAGE2_RTCACHEFRIENDS)) {
07840                ASTOBJ_MARK(iterator);
07841                pruned++;
07842             }
07843             ASTOBJ_UNLOCK(iterator);
07844          } while (0) );
07845          if (pruned) {
07846             ASTOBJ_CONTAINER_PRUNE_MARKED(&peerl, sip_destroy_peer);
07847             ast_cli(fd, "%d peers pruned.\n", pruned);
07848          } else
07849             ast_cli(fd, "No peers found to prune.\n");
07850          ASTOBJ_CONTAINER_UNLOCK(&peerl);
07851       }
07852       if (pruneuser) {
07853          int pruned = 0;
07854 
07855          ASTOBJ_CONTAINER_WRLOCK(&userl);
07856          ASTOBJ_CONTAINER_TRAVERSE(&userl, 1, do {
07857             ASTOBJ_RDLOCK(iterator);
07858             if (name && regexec(&regexbuf, iterator->name, 0, NULL, 0)) {
07859                ASTOBJ_UNLOCK(iterator);
07860                continue;
07861             };
07862             if (ast_test_flag((&iterator->flags_page2), SIP_PAGE2_RTCACHEFRIENDS)) {
07863                ASTOBJ_MARK(iterator);
07864                pruned++;
07865             }
07866             ASTOBJ_UNLOCK(iterator);
07867          } while (0) );
07868          if (pruned) {
07869             ASTOBJ_CONTAINER_PRUNE_MARKED(&userl, sip_destroy_user);
07870             ast_cli(fd, "%d users pruned.\n", pruned);
07871          } else
07872             ast_cli(fd, "No users found to prune.\n");
07873          ASTOBJ_CONTAINER_UNLOCK(&userl);
07874       }
07875    } else {
07876       if (prunepeer) {
07877          if ((peer = ASTOBJ_CONTAINER_FIND_UNLINK(&peerl, name))) {
07878             if (!ast_test_flag((&peer->flags_page2), SIP_PAGE2_RTCACHEFRIENDS)) {
07879                ast_cli(fd, "Peer '%s' is not a Realtime peer, cannot be pruned.\n", name);
07880                ASTOBJ_CONTAINER_LINK(&peerl, peer);
07881             } else
07882                ast_cli(fd, "Peer '%s' pruned.\n", name);
07883             ASTOBJ_UNREF(peer, sip_destroy_peer);
07884          } else
07885             ast_cli(fd, "Peer '%s' not found.\n", name);
07886       }
07887       if (pruneuser) {
07888          if ((user = ASTOBJ_CONTAINER_FIND_UNLINK(&userl, name))) {
07889             if (!ast_test_flag((&user->flags_page2), SIP_PAGE2_RTCACHEFRIENDS)) {
07890                ast_cli(fd, "User '%s' is not a Realtime user, cannot be pruned.\n", name);
07891                ASTOBJ_CONTAINER_LINK(&userl, user);
07892             } else
07893                ast_cli(fd, "User '%s' pruned.\n", name);
07894             ASTOBJ_UNREF(user, sip_destroy_user);
07895          } else
07896             ast_cli(fd, "User '%s' not found.\n", name);
07897       }
07898    }
07899 
07900    return RESULT_SUCCESS;
07901 }

static struct ast_frame * sip_read struct ast_channel ast  )  [static]
 

sip_read: Read SIP RTP from channel

Definition at line 3017 of file chan_sip.c.

References ast_mutex_lock(), ast_mutex_unlock(), sip_pvt::lastrtprx, sip_pvt::lock, sip_rtp_read(), and ast_channel::tech_pvt.

03018 {
03019    struct ast_frame *fr;
03020    struct sip_pvt *p = ast->tech_pvt;
03021    ast_mutex_lock(&p->lock);
03022    fr = sip_rtp_read(ast, p);
03023    time(&p->lastrtprx);
03024    ast_mutex_unlock(&p->lock);
03025    return fr;
03026 }

static int sip_reg_timeout void *  data  )  [static]
 

sip_reg_timeout: Registration timeout, register again

Definition at line 5354 of file chan_sip.c.

References __sip_pretend_ack(), ast_log(), ast_set_flag, ASTOBJ_REF, ASTOBJ_UNREF, sip_registry::call, EVENT_FLAG_SYSTEM, global_regattempts_max, sip_registry::hostname, LOG_NOTICE, manager_event(), REG_STATE_FAILED, REG_STATE_UNREGISTERED, sip_registry::regattempts, sip_pvt::registry, sip_registry::regstate, regstate2str(), SIP_NEEDDESTROY, SIP_REGISTER, sip_registry_destroy(), sip_registry::timeout, transmit_register(), and sip_registry::username.

Referenced by transmit_register().

05355 {
05356 
05357    /* if we are here, our registration timed out, so we'll just do it over */
05358    struct sip_registry *r = ASTOBJ_REF((struct sip_registry *) data);
05359    struct sip_pvt *p;
05360    int res;
05361 
05362    /* if we couldn't get a reference to the registry object, punt */
05363    if (!r)
05364       return 0;
05365 
05366    ast_log(LOG_NOTICE, "   -- Registration for '%s@%s' timed out, trying again (Attempt #%d)\n", r->username, r->hostname, r->regattempts); 
05367    if (r->call) {
05368       /* Unlink us, destroy old call.  Locking is not relevant here because all this happens
05369          in the single SIP manager thread. */
05370       p = r->call;
05371       if (p->registry)
05372          ASTOBJ_UNREF(p->registry, sip_registry_destroy);
05373       r->call = NULL;
05374       ast_set_flag(p, SIP_NEEDDESTROY);   
05375       /* Pretend to ACK anything just in case */
05376       __sip_pretend_ack(p);
05377    }
05378    /* If we have a limit, stop registration and give up */
05379    if (global_regattempts_max && (r->regattempts > global_regattempts_max)) {
05380       /* Ok, enough is enough. Don't try any more */
05381       /* We could add an external notification here... 
05382          steal it from app_voicemail :-) */
05383       ast_log(LOG_NOTICE, "   -- Giving up forever trying to register '%s@%s'\n", r->username, r->hostname);
05384       r->regstate=REG_STATE_FAILED;
05385    } else {
05386       r->regstate=REG_STATE_UNREGISTERED;
05387       r->timeout = -1;
05388       res=transmit_register(r, SIP_REGISTER, NULL, NULL);
05389    }
05390    manager_event(EVENT_FLAG_SYSTEM, "Registry", "Channel: SIP\r\nUsername: %s\r\nDomain: %s\r\nStatus: %s\r\n", r->username, r->hostname, regstate2str(r->regstate));
05391    ASTOBJ_UNREF(r,sip_registry_destroy);
05392    return 0;
05393 }

static int sip_register char *  value,
int  lineno
[static]
 

sip_register: Parse register=> line in sip.conf and add to registry

Definition at line 3222 of file chan_sip.c.

References ast_log(), ast_strlen_zero(), ASTOBJ_CONTAINER_LINK, ASTOBJ_INIT, ASTOBJ_UNREF, sip_registry::authuser, sip_registry::callid_valid, sip_registry::contact, copy(), default_expiry, sip_registry::expire, sip_registry::hostname, hostname, LOG_ERROR, LOG_WARNING, malloc, sip_registry::ocseq, sip_registry::portno, sip_registry::refresh, regl, regobjs, sip_registry::secret, secret, sip_registry_destroy(), strsep(), sip_registry::timeout, sip_registry::username, and username.

Referenced by reload_config().

03223 {
03224    struct sip_registry *reg;
03225    char copy[256];
03226    char *username=NULL, *hostname=NULL, *secret=NULL, *authuser=NULL;
03227    char *porta=NULL;
03228    char *contact=NULL;
03229    char *stringp=NULL;
03230    
03231    if (!value)
03232       return -1;
03233    ast_copy_string(copy, value, sizeof(copy));
03234    stringp=copy;
03235    username = stringp;
03236    hostname = strrchr(stringp, '@');
03237    if (hostname) {
03238       *hostname = '\0';
03239       hostname++;
03240    }
03241    if (ast_strlen_zero(username) || ast_strlen_zero(hostname)) {
03242       ast_log(LOG_WARNING, "Format for registration is user[:secret[:authuser]]@host[:port][/contact] at line %d\n", lineno);
03243       return -1;
03244    }
03245    stringp=username;
03246    username = strsep(&stringp, ":");
03247    if (username) {
03248       secret = strsep(&stringp, ":");
03249       if (secret) 
03250          authuser = strsep(&stringp, ":");
03251    }
03252    stringp = hostname;
03253    hostname = strsep(&stringp, "/");
03254    if (hostname) 
03255       contact = strsep(&stringp, "/");
03256    if (ast_strlen_zero(contact))
03257       contact = "s";
03258    stringp=hostname;
03259    hostname = strsep(&stringp, ":");
03260    porta = strsep(&stringp, ":");
03261    
03262    if (porta && !atoi(porta)) {
03263       ast_log(LOG_WARNING, "%s is not a valid port number at line %d\n", porta, lineno);
03264       return -1;
03265    }
03266    reg = malloc(sizeof(struct sip_registry));
03267    if (!reg) {
03268       ast_log(LOG_ERROR, "Out of memory. Can't allocate SIP registry entry\n");
03269       return -1;
03270    }
03271    memset(reg, 0, sizeof(struct sip_registry));
03272    regobjs++;
03273    ASTOBJ_INIT(reg);
03274    ast_copy_string(reg->contact, contact, sizeof(reg->contact));
03275    if (username)
03276       ast_copy_string(reg->username, username, sizeof(reg->username));
03277    if (hostname)
03278       ast_copy_string(reg->hostname, hostname, sizeof(reg->hostname));
03279    if (authuser)
03280       ast_copy_string(reg->authuser, authuser, sizeof(reg->authuser));
03281    if (secret)
03282       ast_copy_string(reg->secret, secret, sizeof(reg->secret));
03283    reg->expire = -1;
03284    reg->timeout =  -1;
03285    reg->refresh = default_expiry;
03286    reg->portno = porta ? atoi(porta) : 0;
03287    reg->callid_valid = 0;
03288    reg->ocseq = 101;
03289    ASTOBJ_CONTAINER_LINK(&regl, reg);
03290    ASTOBJ_UNREF(reg,sip_registry_destroy);
03291    return 0;
03292 }

static void sip_registry_destroy struct sip_registry reg  )  [static]
 

sip_registry_destroy: Destroy registry object ---

Definition at line 2084 of file chan_sip.c.

References ast_sched_del(), sip_registry::call, sip_registry::expire, free, sip_pvt::registry, regobjs, sip_destroy(), and sip_registry::timeout.

Referenced by __sip_destroy(), handle_response_register(), sip_reg_timeout(), sip_register(), sip_reregister(), and unload_module().

02085 {
02086    /* Really delete */
02087    if (reg->call) {
02088       /* Clear registry before destroying to ensure
02089          we don't get reentered trying to grab the registry lock */
02090       reg->call->registry = NULL;
02091       sip_destroy(reg->call);
02092    }
02093    if (reg->expire > -1)
02094       ast_sched_del(sched, reg->expire);
02095    if (reg->timeout > -1)
02096       ast_sched_del(sched, reg->timeout);
02097    regobjs--;
02098    free(reg);
02099    
02100 }

static int sip_reload int  fd,
int  argc,
char *  argv[]
[static]
 

sip_reload: Force reload of module from cli ---

Definition at line 13265 of file chan_sip.c.

References ast_mutex_lock(), ast_mutex_unlock(), ast_verbose(), restart_monitor(), and sip_reloading.

Referenced by reload().

13266 {
13267 
13268    ast_mutex_lock(&sip_reload_lock);
13269    if (sip_reloading) {
13270       ast_verbose("Previous SIP reload not yet done\n");
13271    } else
13272       sip_reloading = 1;
13273    ast_mutex_unlock(&sip_reload_lock);
13274    restart_monitor();
13275 
13276    return 0;
13277 }

static struct ast_channel * sip_request_call const char *  type,
int  format,
void *  data,
int *  cause
[static]
 

sip_request: PBX interface function -build SIP pvt structure ---

Definition at line 11706 of file chan_sip.c.

References __ourip, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL, AST_CAUSE_SWITCH_CONGESTION, AST_CAUSE_UNREGISTERED, AST_FORMAT_MAX_AUDIO, ast_getformatname(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_sip_ouraddrfor(), AST_STATE_DOWN, ast_strlen_zero(), ast_update_use_count(), build_callid(), build_via(), calloc, create_addr(), global_capability, host, LOG_ERROR, LOG_NOTICE, sip_pvt::options, restart_monitor(), sip_alloc(), sip_destroy(), SIP_INVITE, and sip_new().

11707 {
11708    int oldformat;
11709    struct sip_pvt *p;
11710    struct ast_channel *tmpc = NULL;
11711    char *ext, *host;
11712    char tmp[256];
11713    char *dest = data;
11714 
11715    oldformat = format;
11716    format &= ((AST_FORMAT_MAX_AUDIO << 1) - 1);
11717    if (!format) {
11718       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));
11719       *cause = AST_CAUSE_BEARERCAPABILITY_NOTAVAIL;   /* Can't find codec to connect to host */
11720       return NULL;
11721    }
11722    p = sip_alloc(NULL, NULL, 0, SIP_INVITE);
11723    if (!p) {
11724       ast_log(LOG_ERROR, "Unable to build sip pvt data for '%s' (Out of memory)\n", (char *)data);
11725       *cause = AST_CAUSE_SWITCH_CONGESTION;
11726       return NULL;
11727    }
11728 
11729    p->options = calloc(1, sizeof(*p->options));
11730    if (!p->options) {
11731       sip_destroy(p);
11732       ast_log(LOG_ERROR, "Unable to build option SIP data structure - Out of memory\n");
11733       *cause = AST_CAUSE_SWITCH_CONGESTION;
11734       return NULL;
11735    }
11736 
11737    ast_copy_string(tmp, dest, sizeof(tmp));
11738    host = strchr(tmp, '@');
11739    if (host) {
11740       *host = '\0';
11741       host++;
11742       ext = tmp;
11743    } else {
11744       ext = strchr(tmp, '/');
11745       if (ext) {
11746          *ext++ = '\0';
11747          host = tmp;
11748       }
11749       else {
11750          host = tmp;
11751          ext = NULL;
11752       }
11753    }
11754 
11755    if (create_addr(p, host)) {
11756       *cause = AST_CAUSE_UNREGISTERED;
11757       sip_destroy(p);
11758       return NULL;
11759    }
11760    if (ast_strlen_zero(p->peername) && ext)
11761       ast_copy_string(p->peername, ext, sizeof(p->peername));
11762    /* Recalculate our side, and recalculate Call ID */
11763    if (ast_sip_ouraddrfor(&p->sa.sin_addr,&p->ourip))
11764       memcpy(&p->ourip, &__ourip, sizeof(p->ourip));
11765    build_via(p, p->via, sizeof(p->via));
11766    build_callid(p->callid, sizeof(p->callid), p->ourip, p->fromdomain);
11767    
11768    /* We have an extension to call, don't use the full contact here */
11769    /* This to enable dialling registered peers with extension dialling,
11770       like SIP/peername/extension   
11771       SIP/peername will still use the full contact */
11772    if (ext) {
11773       ast_copy_string(p->username, ext, sizeof(p->username));
11774       p->fullcontact[0] = 0;  
11775    }
11776 #if 0
11777    printf("Setting up to call extension '%s' at '%s'\n", ext ? ext : "<none>", host);
11778 #endif
11779    p->prefcodec = format;
11780    ast_mutex_lock(&p->lock);
11781    tmpc = sip_new(p, AST_STATE_DOWN, host);  /* Place the call */
11782    ast_mutex_unlock(&p->lock);
11783    if (!tmpc)
11784       sip_destroy(p);
11785    ast_update_use_count();
11786    restart_monitor();
11787    return tmpc;
11788 }

static int sip_reregister void *  data  )  [static]
 

sip_reregister: Update registration with SIP Proxy---

Definition at line 5319 of file chan_sip.c.

References __sip_do_register(), append_history(), ast_log(), ASTOBJ_REF, ASTOBJ_UNREF, sip_registry::call, sip_registry::expire, sip_registry::hostname, LOG_NOTICE, recordhistory, sip_registry_destroy(), sipdebug, and sip_registry::username.

Referenced by handle_response_register(), and sip_send_all_registers().

05320 {
05321    /* if we are here, we know that we need to reregister. */
05322    struct sip_registry *r= ASTOBJ_REF((struct sip_registry *) data);
05323 
05324    /* if we couldn't get a reference to the registry object, punt */
05325    if (!r)
05326       return 0;
05327 
05328    if (r->call && recordhistory) {
05329       char tmp[80];
05330       snprintf(tmp, sizeof(tmp), "Account: %s@%s", r->username, r->hostname);
05331       append_history(r->call, "RegistryRenew", tmp);
05332    }
05333    /* Since registry's are only added/removed by the the monitor thread, this
05334       may be overkill to reference/dereference at all here */
05335    if (sipdebug)
05336       ast_log(LOG_NOTICE, "   -- Re-registration for  %s@%s\n", r->username, r->hostname);
05337 
05338    r->expire = -1;
05339    __sip_do_register(r);
05340    ASTOBJ_UNREF(r, sip_registry_destroy);
05341    return 0;
05342 }

static struct ast_frame* sip_rtp_read struct ast_channel ast,
struct sip_pvt p
[static]
 

sip_rtp_read: Read RTP from network ---

Definition at line 2967 of file chan_sip.c.

References ast_dsp_process(), AST_FRAME_DTMF, AST_FRAME_NULL, AST_FRAME_VOICE, ast_log(), ast_rtcp_read(), ast_rtp_read(), ast_set_read_format(), ast_set_write_format(), ast_test_flag, ast_channel::fdno, ast_frame::frametype, LOG_DEBUG, ast_channel::nativeformats, sip_pvt::owner, ast_channel::readformat, sip_pvt::rtp, SIP_DTMF, SIP_DTMF_INBAND, SIP_DTMF_RFC2833, ast_frame::subclass, sip_pvt::vad, sip_pvt::vrtp, and ast_channel::writeformat.

Referenced by sip_read().

02968 {
02969    /* Retrieve audio/etc from channel.  Assumes p->lock is already held. */
02970    struct ast_frame *f;
02971    static struct ast_frame null_frame = { AST_FRAME_NULL, };
02972    
02973    if (!p->rtp) {
02974       /* We have no RTP allocated for this channel */
02975       return &null_frame;
02976    }
02977 
02978    switch(ast->fdno) {
02979    case 0:
02980       f = ast_rtp_read(p->rtp);  /* RTP Audio */
02981       break;
02982    case 1:
02983       f = ast_rtcp_read(p->rtp); /* RTCP Control Channel */
02984       break;
02985    case 2:
02986       f = ast_rtp_read(p->vrtp); /* RTP Video */
02987       break;
02988    case 3:
02989       f = ast_rtcp_read(p->vrtp);   /* RTCP Control Channel for video */
02990       break;
02991    default:
02992       f = &null_frame;
02993    }
02994    /* Don't forward RFC2833 if we're not supposed to */
02995    if (f && (f->frametype == AST_FRAME_DTMF) && (ast_test_flag(p, SIP_DTMF) != SIP_DTMF_RFC2833))
02996       return &null_frame;
02997    if (p->owner) {
02998       /* We already hold the channel lock */
02999       if (f->frametype == AST_FRAME_VOICE) {
03000          if (f->subclass != p->owner->nativeformats) {
03001             ast_log(LOG_DEBUG, "Oooh, format changed to %d\n", f->subclass);
03002             p->owner->nativeformats = f->subclass;
03003             ast_set_read_format(p->owner, p->owner->readformat);
03004             ast_set_write_format(p->owner, p->owner->writeformat);
03005          }
03006          if ((ast_test_flag(p, SIP_DTMF) == SIP_DTMF_INBAND) && p->vad) {
03007             f = ast_dsp_process(p->owner, p->vad, f);
03008             if (f && (f->frametype == AST_FRAME_DTMF)) 
03009                ast_log(LOG_DEBUG, "* Detected inband DTMF '%c'\n", f->subclass);
03010          }
03011       }
03012    }
03013    return f;
03014 }

static int sip_scheddestroy struct sip_pvt p,
int  ms
[static]
 

sip_scheddestroy: Schedule destruction of SIP call ---

Definition at line 1335 of file chan_sip.c.

References __sip_autodestruct(), append_history(), ast_sched_add(), ast_sched_del(), ast_verbose(), sip_pvt::autokillid, sip_pvt::callid, recordhistory, and sip_debug_test_pvt().

Referenced by cb_extensionstate(), check_auth(), check_pendings(), handle_request_register(), handle_request_subscribe(), handle_response_register(), sip_hangup(), sip_notify(), and sip_send_mwi_to_peer().

01336 {
01337    char tmp[80];
01338    if (sip_debug_test_pvt(p))
01339       ast_verbose("Scheduling destruction of call '%s' in %d ms\n", p->callid, ms);
01340    if (recordhistory) {
01341       snprintf(tmp, sizeof(tmp), "%d ms", ms);
01342       append_history(p, "SchedDestroy", tmp);
01343    }
01344 
01345    if (p->autokillid > -1)
01346       ast_sched_del(sched, p->autokillid);
01347    p->autokillid = ast_sched_add(sched, ms, __sip_autodestruct, p);
01348    return 0;
01349 }

static void sip_send_all_registers void   )  [static]
 

sip_send_all_registers: Send all known registrations

Definition at line 13210 of file chan_sip.c.

References ast_sched_add(), ast_sched_del(), ASTOBJ_CONTAINER_TRAVERSE, ASTOBJ_UNLOCK, ASTOBJ_WRLOCK, default_expiry, regl, regobjs, and sip_reregister().

Referenced by load_module().

13211 {
13212    int ms;
13213    int regspacing;
13214    if (!regobjs)
13215       return;
13216    regspacing = default_expiry * 1000/regobjs;
13217    if (regspacing > 100)
13218       regspacing = 100;
13219    ms = regspacing;
13220    ASTOBJ_CONTAINER_TRAVERSE(&regl, 1, do {
13221       ASTOBJ_WRLOCK(iterator);
13222       if (iterator->expire > -1)
13223          ast_sched_del(sched, iterator->expire);
13224       ms += regspacing;
13225       iterator->expire = ast_sched_add(sched, ms, sip_reregister, iterator);
13226       ASTOBJ_UNLOCK(iterator);
13227    } while (0)
13228    );
13229 }

static int sip_send_mwi_to_peer struct sip_peer peer  )  [static]
 

sip_send_mwi_to_peer: Send message waiting indication ---

Definition at line 11355 of file chan_sip.c.

References __ourip, ast_app_messagecount(), ast_log(), ast_set_flag, ast_sip_ouraddrfor(), build_callid(), build_via(), sip_pvt::callid, create_addr_from_peer(), sip_pvt::fromdomain, sip_peer::lastmsgcheck, sip_peer::lastmsgssent, LOG_WARNING, sip_peer::mailbox, sip_pvt::ourip, sip_pvt::sa, sip_alloc(), sip_destroy(), SIP_NOTIFY, SIP_OUTGOING, sip_scheddestroy(), transmit_notify_with_mwi(), sip_pvt::via, and sip_peer::vmexten.

Referenced by do_monitor().

11356 {
11357    /* Called with peerl lock, but releases it */
11358    struct sip_pvt *p;
11359    int newmsgs, oldmsgs;
11360 
11361    /* Check for messages */
11362    ast_app_messagecount(peer->mailbox, &newmsgs, &oldmsgs);
11363    
11364    time(&peer->lastmsgcheck);
11365    
11366    /* Return now if it's the same thing we told them last time */
11367    if (((newmsgs << 8) | (oldmsgs)) == peer->lastmsgssent) {
11368       return 0;
11369    }
11370    
11371    p = sip_alloc(NULL, NULL, 0, SIP_NOTIFY);
11372    if (!p) {
11373       ast_log(LOG_WARNING, "Unable to build sip pvt data for MWI\n");
11374       return -1;
11375    }
11376    peer->lastmsgssent = ((newmsgs << 8) | (oldmsgs));
11377    if (create_addr_from_peer(p, peer)) {
11378       /* Maybe they're not registered, etc. */
11379       sip_destroy(p);
11380       return 0;
11381    }
11382    /* Recalculate our side, and recalculate Call ID */
11383    if (ast_sip_ouraddrfor(&p->sa.sin_addr,&p->ourip))
11384       memcpy(&p->ourip, &__ourip, sizeof(p->ourip));
11385    build_via(p, p->via, sizeof(p->via));
11386    build_callid(p->callid, sizeof(p->callid), p->ourip, p->fromdomain);
11387    /* Send MWI */
11388    ast_set_flag(p, SIP_OUTGOING);
11389    transmit_notify_with_mwi(p, newmsgs, oldmsgs, peer->vmexten);
11390    sip_scheddestroy(p, 15000);
11391    return 0;
11392 }

static int sip_senddigit struct ast_channel ast,
char  digit
[static]
 

sip_senddigit: Send DTMF character on SIP channel

Definition at line 2614 of file chan_sip.c.

References ast_mutex_lock(), ast_mutex_unlock(), ast_rtp_senddigit(), ast_test_flag, sip_pvt::lock, SIP_DTMF, SIP_DTMF_INBAND, SIP_DTMF_INFO, SIP_DTMF_RFC2833, ast_channel::tech_pvt, and transmit_info_with_digit().

02615 {
02616    struct sip_pvt *p = ast->tech_pvt;
02617    int res = 0;
02618    ast_mutex_lock(&p->lock);
02619    switch (ast_test_flag(p, SIP_DTMF)) {
02620    case SIP_DTMF_INFO:
02621       transmit_info_with_digit(p, digit);
02622       break;
02623    case SIP_DTMF_RFC2833:
02624       if (p->rtp)
02625          ast_rtp_senddigit(p->rtp, digit);
02626       break;
02627    case SIP_DTMF_INBAND:
02628       res = -1;
02629       break;
02630    }
02631    ast_mutex_unlock(&p->lock);
02632    return res;
02633 }

static int sip_sendtext struct ast_channel ast,
const char *  text
[static]
 

sip_sendtext: Send SIP MESSAGE text within a call ---

Definition at line 1581 of file chan_sip.c.

References ast_strlen_zero(), ast_verbose(), debug, ast_channel::name, sip_debug_test_pvt(), ast_channel::tech_pvt, and transmit_message_with_text().

01582 {
01583    struct sip_pvt *p = ast->tech_pvt;
01584    int debug=sip_debug_test_pvt(p);
01585 
01586    if (debug)
01587       ast_verbose("Sending text %s on %s\n", text, ast->name);
01588    if (!p)
01589       return -1;
01590    if (ast_strlen_zero(text))
01591       return 0;
01592    if (debug)
01593       ast_verbose("Really sending text %s on %s\n", text, ast->name);
01594    transmit_message_with_text(p, text);
01595    return 0;   
01596 }

static int sip_set_rtp_peer struct ast_channel chan,
struct ast_rtp rtp,
struct ast_rtp vrtp,
int  codecs,
int  nat_active
[static]
 

sip_set_rtp_peer: Set the RTP peer for this call ---

Definition at line 12899 of file chan_sip.c.

References ast_inet_ntoa(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_rtp_get_peer(), ast_set_flag, ast_test_flag, sip_pvt::callid, sip_pvt::lastrtprx, sip_pvt::lastrtptx, sip_pvt::lock, LOG_DEBUG, option_debug, sip_pvt::ourip, sip_pvt::pendinginvite, sip_pvt::redircodecs, sip_pvt::redirip, SIP_GOTREFER, SIP_NEEDREINVITE, SIP_PENDINGBYE, ast_channel::tech_pvt, transmit_reinvite_with_sdp(), and sip_pvt::vredirip.

12900 {
12901    struct sip_pvt *p;
12902 
12903    p = chan->tech_pvt;
12904    if (!p) 
12905       return -1;
12906    ast_mutex_lock(&p->lock);
12907    if (rtp)
12908       ast_rtp_get_peer(rtp, &p->redirip);
12909    else
12910       memset(&p->redirip, 0, sizeof(p->redirip));
12911    if (vrtp)
12912       ast_rtp_get_peer(vrtp, &p->vredirip);
12913    else
12914       memset(&p->vredirip, 0, sizeof(p->vredirip));
12915    p->redircodecs = codecs;
12916    if (codecs && !ast_test_flag(p, SIP_GOTREFER)) {
12917       if (!p->pendinginvite) {
12918          if (option_debug > 2) {
12919             char iabuf[INET_ADDRSTRLEN];
12920             ast_log(LOG_DEBUG, "Sending reinvite on SIP '%s' - It's audio soon redirected to IP %s\n", p->callid, ast_inet_ntoa(iabuf, sizeof(iabuf), rtp ? p->redirip.sin_addr : p->ourip));
12921          }
12922          transmit_reinvite_with_sdp(p);
12923       } else if (!ast_test_flag(p, SIP_PENDINGBYE)) {
12924          if (option_debug > 2) {
12925             char iabuf[INET_ADDRSTRLEN];
12926             ast_log(LOG_DEBUG, "Deferring reinvite on SIP '%s' - It's audio will be redirected to IP %s\n", p->callid, ast_inet_ntoa(iabuf, sizeof(iabuf), rtp ? p->redirip.sin_addr : p->ourip));
12927          }
12928          ast_set_flag(p, SIP_NEEDREINVITE);  
12929       }
12930    }
12931    /* Reset lastrtprx timer */
12932    time(&p->lastrtprx);
12933    time(&p->lastrtptx);
12934    ast_mutex_unlock(&p->lock);
12935    return 0;
12936 }

static int sip_show_channel int  fd,
int  argc,
char *  argv[]
[static]
 

sip_show_channel: Show details of one call ---

Definition at line 8578 of file chan_sip.c.

References ast_cli(), ast_getformatname(), ast_inet_ntoa(), ast_mutex_lock(), ast_mutex_unlock(), ast_strlen_zero(), ast_test_flag, sip_pvt::callid, sip_pvt::capability, sip_pvt::cid_num, dtmfmode2str(), sip_route::hop, iflist, sip_pvt::jointcapability, sip_pvt::lastmsg, nat2str(), ast_channel::nativeformats, sip_pvt::next, sip_pvt::noncodeccapability, NONE, sip_pvt::ourip, sip_pvt::owner, sip_pvt::peercapability, sip_pvt::peername, sip_pvt::recv, sip_pvt::redirip, RESULT_SHOWUSAGE, RESULT_SUCCESS, sip_pvt::route, sip_pvt::sa, SIP_DTMF, SIP_NAT, SIP_NEEDDESTROY, sip_options, SIP_OUTGOING, SIP_PROMISCREDIR, sip_pvt::sipoptions, sip_pvt::subscribed, subscription_type2str(), sip_pvt::tag, text, sip_pvt::theirtag, sip_pvt::uri, sip_pvt::useragent, and sip_pvt::username.

08579 {
08580    struct sip_pvt *cur;
08581    char iabuf[INET_ADDRSTRLEN];
08582    size_t len;
08583    int found = 0;
08584 
08585    if (argc != 4)
08586       return RESULT_SHOWUSAGE;
08587    len = strlen(argv[3]);
08588    ast_mutex_lock(&iflock);
08589    cur = iflist;
08590    while(cur) {
08591       if (!strncasecmp(cur->callid, argv[3],len)) {
08592          ast_cli(fd,"\n");
08593          if (cur->subscribed != NONE)
08594             ast_cli(fd, "  * Subscription (type: %s)\n", subscription_type2str(cur->subscribed));
08595          else
08596             ast_cli(fd, "  * SIP Call\n");
08597          ast_cli(fd, "  Direction:              %s\n", ast_test_flag(cur, SIP_OUTGOING)?"Outgoing":"Incoming");
08598          ast_cli(fd, "  Call-ID:                %s\n", cur->callid);
08599          ast_cli(fd, "  Our Codec Capability:   %d\n", cur->capability);
08600          ast_cli(fd, "  Non-Codec Capability:   %d\n", cur->noncodeccapability);
08601          ast_cli(fd, "  Their Codec Capability:   %d\n", cur->peercapability);
08602          ast_cli(fd, "  Joint Codec Capability:   %d\n", cur->jointcapability);
08603          ast_cli(fd, "  Format                  %s\n", ast_getformatname(cur->owner ? cur->owner->nativeformats : 0) );
08604          ast_cli(fd, "  Theoretical Address:    %s:%d\n", ast_inet_ntoa(iabuf, sizeof(iabuf), cur->sa.sin_addr), ntohs(cur->sa.sin_port));
08605          ast_cli(fd, "  Received Address:       %s:%d\n", ast_inet_ntoa(iabuf, sizeof(iabuf), cur->recv.sin_addr), ntohs(cur->recv.sin_port));
08606          ast_cli(fd, "  NAT Support:            %s\n", nat2str(ast_test_flag(cur, SIP_NAT)));
08607          ast_cli(fd, "  Audio IP:               %s %s\n", ast_inet_ntoa(iabuf, sizeof(iabuf), cur->redirip.sin_addr.s_addr ? cur->redirip.sin_addr : cur->ourip), cur->redirip.sin_addr.s_addr ? "(Outside bridge)" : "(local)" );
08608          ast_cli(fd, "  Our Tag:                %s\n", cur->tag);
08609          ast_cli(fd, "  Their Tag:              %s\n", cur->theirtag);
08610          ast_cli(fd, "  SIP User agent:         %s\n", cur->useragent);
08611          if (!ast_strlen_zero(cur->username))
08612             ast_cli(fd, "  Username:               %s\n", cur->username);
08613          if (!ast_strlen_zero(cur->peername))
08614             ast_cli(fd, "  Peername:               %s\n", cur->peername);
08615          if (!ast_strlen_zero(cur->uri))
08616             ast_cli(fd, "  Original uri:           %s\n", cur->uri);
08617          if (!ast_strlen_zero(cur->cid_num))
08618             ast_cli(fd, "  Caller-ID:              %s\n", cur->cid_num);
08619          ast_cli(fd, "  Need Destroy:           %d\n", ast_test_flag(cur, SIP_NEEDDESTROY));
08620          ast_cli(fd, "  Last Message:           %s\n", cur->lastmsg);
08621          ast_cli(fd, "  Promiscuous Redir:      %s\n", ast_test_flag(cur, SIP_PROMISCREDIR) ? "Yes" : "No");
08622          ast_cli(fd, "  Route:                  %s\n", cur->route ? cur->route->hop : "N/A");
08623          ast_cli(fd, "  DTMF Mode:              %s\n", dtmfmode2str(ast_test_flag(cur, SIP_DTMF)));
08624          ast_cli(fd, "  SIP Options:            ");
08625          if (cur->sipoptions) {
08626             int x;
08627             for (x=0 ; (x < (sizeof(sip_options) / sizeof(sip_options[0]))); x++) {
08628                if (cur->sipoptions & sip_options[x].id)
08629                   ast_cli(fd, "%s ", sip_options[x].text);
08630             }
08631          } else
08632             ast_cli(fd, "(none)\n");
08633          ast_cli(fd, "\n\n");
08634          found++;
08635       }
08636       cur = cur->next;
08637    }
08638    ast_mutex_unlock(&iflock);
08639    if (!found) 
08640       ast_cli(fd, "No such SIP Call ID starting with '%s'\n", argv[3]);
08641    return RESULT_SUCCESS;
08642 }

static int sip_show_channels int  fd,
int  argc,
char *  argv[]
[static]
 

sip_show_channels: Show active SIP channels ---

Definition at line 8379 of file chan_sip.c.

References __sip_show_channels().

08380 {
08381         return __sip_show_channels(fd, argc, argv, 0);
08382 }

static int sip_show_domains int  fd,
int  argc,
char *  argv[]
[static]
 

Definition at line 7934 of file chan_sip.c.

References ast_cli(), AST_LIST_EMPTY, AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_strlen_zero(), domain::context, domain::domain, domain_mode_to_text(), FORMAT, list, domain::mode, and RESULT_SUCCESS.

07935 {
07936    struct domain *d;
07937 
07938    if (AST_LIST_EMPTY(&domain_list)) {
07939       ast_cli(fd, "SIP Domain support not enabled.\n\n");
07940       return RESULT_SUCCESS;
07941    } else {
07942       ast_cli(fd, FORMAT, "Our local SIP domains:", "Context", "Set by");
07943       AST_LIST_LOCK(&domain_list);
07944       AST_LIST_TRAVERSE(&domain_list, d, list)
07945          ast_cli(fd, FORMAT, d->domain, ast_strlen_zero(d->context) ? "(default)": d->context,
07946             domain_mode_to_text(d->mode));
07947       AST_LIST_UNLOCK(&domain_list);
07948       ast_cli(fd, "\n");
07949       return RESULT_SUCCESS;
07950    }
07951 }

static int sip_show_history int  fd,
int  argc,
char *  argv[]
[static]
 

sip_show_history: Show history details of one call ---

Definition at line 8645 of file chan_sip.c.

References ast_cli(), ast_mutex_lock(), ast_mutex_unlock(), sip_pvt::callid, sip_history::event, sip_pvt::history, iflist, sip_pvt::next, sip_history::next, NONE, recordhistory, RESULT_SHOWUSAGE, RESULT_SUCCESS, and sip_pvt::subscribed.

08646 {
08647    struct sip_pvt *cur;
08648    struct sip_history *hist;
08649    size_t len;
08650    int x;
08651    int found = 0;
08652 
08653    if (argc != 4)
08654       return RESULT_SHOWUSAGE;
08655    if (!recordhistory)
08656       ast_cli(fd, "\n***Note: History recording is currently DISABLED.  Use 'sip history' to ENABLE.\n");
08657    len = strlen(argv[3]);
08658    ast_mutex_lock(&iflock);
08659    cur = iflist;
08660    while(cur) {
08661       if (!strncasecmp(cur->callid, argv[3], len)) {
08662          ast_cli(fd,"\n");
08663          if (cur->subscribed != NONE)
08664             ast_cli(fd, "  * Subscription\n");
08665          else
08666             ast_cli(fd, "  * SIP Call\n");
08667          x = 0;
08668          hist = cur->history;
08669          while(hist) {
08670             x++;
08671             ast_cli(fd, "%d. %s\n", x, hist->event);
08672             hist = hist->next;
08673          }
08674          if (!x)
08675             ast_cli(fd, "Call '%s' has no history\n", cur->callid);
08676          found++;
08677       }
08678       cur = cur->next;
08679    }
08680    ast_mutex_unlock(&iflock);
08681    if (!found) 
08682       ast_cli(fd, "No such SIP Call ID starting with '%s'\n", argv[3]);
08683    return RESULT_SUCCESS;
08684 }

static int sip_show_inuse int  fd,
int  argc,
char *  argv[]
[static]
 

sip_show_inuse: CLI Command to show calls within limits set by call_limit ---

Definition at line 7401 of file chan_sip.c.

References ast_cli(), ASTOBJ_CONTAINER_TRAVERSE, ASTOBJ_RDLOCK, ASTOBJ_UNLOCK, FORMAT, FORMAT2, peerl, RESULT_SHOWUSAGE, RESULT_SUCCESS, and userl.

07401                                                           {
07402 #define FORMAT  "%-25.25s %-15.15s %-15.15s \n"
07403 #define FORMAT2 "%-25.25s %-15.15s %-15.15s \n"
07404    char ilimits[40];
07405    char iused[40];
07406    int showall = 0;
07407 
07408    if (argc < 3) 
07409       return RESULT_SHOWUSAGE;
07410 
07411    if (argc == 4 && !strcmp(argv[3],"all")) 
07412          showall = 1;
07413    
07414    ast_cli(fd, FORMAT, "* User name", "In use", "Limit");
07415    ASTOBJ_CONTAINER_TRAVERSE(&userl, 1, do {
07416       ASTOBJ_RDLOCK(iterator);
07417       if (iterator->call_limit)
07418          snprintf(ilimits, sizeof(ilimits), "%d", iterator->call_limit);
07419       else 
07420          ast_copy_string(ilimits, "N/A", sizeof(ilimits));
07421       snprintf(iused, sizeof(iused), "%d", iterator->inUse);
07422       if (showall || iterator->call_limit)
07423          ast_cli(fd, FORMAT2, iterator->name, iused, ilimits);
07424       ASTOBJ_UNLOCK(iterator);
07425    } while (0) );
07426 
07427    ast_cli(fd, FORMAT, "* Peer name", "In use", "Limit");
07428 
07429    ASTOBJ_CONTAINER_TRAVERSE(&peerl, 1, do {
07430       ASTOBJ_RDLOCK(iterator);
07431       if (iterator->call_limit)
07432          snprintf(ilimits, sizeof(ilimits), "%d", iterator->call_limit);
07433       else 
07434          ast_copy_string(ilimits, "N/A", sizeof(ilimits));
07435       snprintf(iused, sizeof(iused), "%d", iterator->inUse);
07436       if (showall || iterator->call_limit)
07437          ast_cli(fd, FORMAT2, iterator->name, iused, ilimits);
07438       ASTOBJ_UNLOCK(iterator);
07439    } while (0) );
07440 
07441    return RESULT_SUCCESS;
07442 #undef FORMAT
07443 #undef FORMAT2
07444 }

static int sip_show_objects int  fd,
int  argc,
char *  argv[]
[static]
 

sip_show_objects: List all allocated SIP Objects ---

Definition at line 7707 of file chan_sip.c.

References apeerobjs, ast_cli(), ASTOBJ_CONTAINER_DUMP, peerl, regl, regobjs, RESULT_SHOWUSAGE, RESULT_SUCCESS, rpeerobjs, ruserobjs, speerobjs, suserobjs, and userl.

07708 {
07709    char tmp[256];
07710    if (argc != 3)
07711       return RESULT_SHOWUSAGE;
07712    ast_cli(fd, "-= User objects: %d static, %d realtime =-\n\n", suserobjs, ruserobjs);
07713    ASTOBJ_CONTAINER_DUMP(fd, tmp, sizeof(tmp), &userl);
07714    ast_cli(fd, "-= Peer objects: %d static, %d realtime, %d autocreate =-\n\n", speerobjs, rpeerobjs, apeerobjs);
07715    ASTOBJ_CONTAINER_DUMP(fd, tmp, sizeof(tmp), &peerl);
07716    ast_cli(fd, "-= Registry objects: %d =-\n\n", regobjs);
07717    ASTOBJ_CONTAINER_DUMP(fd, tmp, sizeof(tmp), &regl);
07718    return RESULT_SUCCESS;
07719 }

static int sip_show_peer int  fd,
int  argc,
char *  argv[]
[static]
 

sip_show_peer: Show one peer in detail ---

Definition at line 7991 of file chan_sip.c.

References _sip_show_peer().

07992 {
07993    return _sip_show_peer(0, fd, NULL, NULL, argc, argv);
07994 }

static int sip_show_peers int  fd,
int  argc,
char *  argv[]
[static]
 

sip_show_peers: CLI Show Peers command

Definition at line 7568 of file chan_sip.c.

References _sip_show_peers().

07569 {
07570    return _sip_show_peers(fd, NULL, NULL, NULL, argc, argv);
07571 }

static int sip_show_registry int  fd,
int  argc,
char *  argv[]
[static]
 

sip_show_registry: Show SIP Registry (registrations with other SIP proxies ---

Definition at line 8243 of file chan_sip.c.

References ast_cli(), ASTOBJ_CONTAINER_TRAVERSE, ASTOBJ_RDLOCK, ASTOBJ_UNLOCK, DEFAULT_SIP_PORT, FORMAT, FORMAT2, host, regl, regstate2str(), RESULT_SHOWUSAGE, and RESULT_SUCCESS.

08244 {
08245 #define FORMAT2 "%-30.30s  %-12.12s  %8.8s %-20.20s\n"
08246 #define FORMAT  "%-30.30s  %-12.12s  %8d %-20.20s\n"
08247    char host[80];
08248 
08249    if (argc != 3)
08250       return RESULT_SHOWUSAGE;
08251    ast_cli(fd, FORMAT2, "Host", "Username", "Refresh", "State");
08252    ASTOBJ_CONTAINER_TRAVERSE(&regl, 1, do {
08253       ASTOBJ_RDLOCK(iterator);
08254       snprintf(host, sizeof(host), "%s:%d", iterator->hostname, iterator->portno ? iterator->portno : DEFAULT_SIP_PORT);
08255       ast_cli(fd, FORMAT, host, iterator->username, iterator->refresh, regstate2str(iterator->regstate));
08256       ASTOBJ_UNLOCK(iterator);
08257    } while(0));
08258    return RESULT_SUCCESS;
08259 #undef FORMAT
08260 #undef FORMAT2
08261 }

static int sip_show_settings int  fd,
int  argc,
char *  argv[]
[static]
 

sip_show_settings: List global settings for the SIP channel ---

Definition at line 8264 of file chan_sip.c.

References allow_external_domains, ast_check_realtime(), ast_cli(), ast_inet_ntoa(), AST_LIST_EMPTY, ast_strlen_zero(), ast_test_flag, authl, autocreatepeer, bindaddr, callevents, compactheaders, default_callerid, default_context, default_expiry, default_fromdomain, default_language, default_notifymime, default_qualify, default_useragent, dtmfmode2str(), global_allowguest, global_alwaysauthreject, global_musicclass, global_mwitime, global_notifyringing, global_realm, global_reg_timeout, global_regattempts_max, global_rtautoclear, global_rtpholdtimeout, global_rtptimeout, global_vmexten, max_expiry, nat2str(), pedanticsipchecking, print_codec_to_cli(), recordhistory, regcontext, relaxdtmf, RESULT_SHOWUSAGE, RESULT_SUCCESS, SIP_DTMF, SIP_NAT, SIP_PAGE2_IGNOREREGEXPIRE, SIP_PAGE2_RTCACHEFRIENDS, SIP_PAGE2_RTUPDATE, SIP_PROG_INBAND, SIP_PROG_INBAND_NEVER, SIP_PROG_INBAND_NO, SIP_PROMISCREDIR, SIP_USECLIENTCODE, SIP_USEREQPHONE, srvlookup, tos, and videosupport.

08265 {
08266    char tmp[BUFSIZ];
08267    int realtimepeers = 0;
08268    int realtimeusers = 0;
08269 
08270    realtimepeers = ast_check_realtime("sippeers");
08271    realtimeusers = ast_check_realtime("sipusers");
08272 
08273    if (argc != 3)
08274       return RESULT_SHOWUSAGE;
08275    ast_cli(fd, "\n\nGlobal Settings:\n");
08276    ast_cli(fd, "----------------\n");
08277    ast_cli(fd, "  SIP Port:               %d\n", ntohs(bindaddr.sin_port));
08278    ast_cli(fd, "  Bindaddress:            %s\n", ast_inet_ntoa(tmp, sizeof(tmp), bindaddr.sin_addr));
08279    ast_cli(fd, "  Videosupport:           %s\n", videosupport ? "Yes" : "No");
08280    ast_cli(fd, "  AutoCreatePeer:         %s\n", autocreatepeer ? "Yes" : "No");
08281    ast_cli(fd, "  Allow unknown access:   %s\n", global_allowguest ? "Yes" : "No");
08282    ast_cli(fd, "  Promsic. redir:         %s\n", ast_test_flag(&global_flags, SIP_PROMISCREDIR) ? "Yes" : "No");
08283    ast_cli(fd, "  SIP domain support:     %s\n", AST_LIST_EMPTY(&domain_list) ? "No" : "Yes");
08284    ast_cli(fd, "  Call to non-local dom.: %s\n", allow_external_domains ? "Yes" : "No");
08285    ast_cli(fd, "  URI user is phone no:   %s\n", ast_test_flag(&global_flags, SIP_USEREQPHONE) ? "Yes" : "No");
08286    ast_cli(fd, "  Our auth realm          %s\n", global_realm);
08287    ast_cli(fd, "  Realm. auth:            %s\n", authl ? "Yes": "No");
08288    ast_cli(fd, "  Always auth rejects:    %s\n", global_alwaysauthreject ? "Yes" : "No");
08289    ast_cli(fd, "  User Agent:             %s\n", default_useragent);
08290    ast_cli(fd, "  MWI checking interval:  %d secs\n", global_mwitime);
08291    ast_cli(fd, "  Reg. context:           %s\n", ast_strlen_zero(regcontext) ? "(not set)" : regcontext);
08292    ast_cli(fd, "  Caller ID:              %s\n", default_callerid);
08293    ast_cli(fd, "  From: Domain:           %s\n", default_fromdomain);
08294    ast_cli(fd, "  Record SIP history:     %s\n", recordhistory ? "On" : "Off");
08295    ast_cli(fd, "  Call Events:            %s\n", callevents ? "On" : "Off");
08296    ast_cli(fd, "  IP ToS:                 0x%x\n", tos);
08297 #ifdef OSP_SUPPORT
08298    ast_cli(fd, "  OSP Support:            Yes\n");
08299 #else
08300    ast_cli(fd, "  OSP Support:            No\n");
08301 #endif
08302    if (!realtimepeers && !realtimeusers)
08303       ast_cli(fd, "  SIP realtime:           Disabled\n" );
08304    else
08305       ast_cli(fd, "  SIP realtime:           Enabled\n" );
08306 
08307    ast_cli(fd, "\nGlobal Signalling Settings:\n");
08308    ast_cli(fd, "---------------------------\n");
08309    ast_cli(fd, "  Codecs:                 ");
08310    print_codec_to_cli(fd, &prefs);
08311    ast_cli(fd, "\n");
08312    ast_cli(fd, "  Relax DTMF:             %s\n", relaxdtmf ? "Yes" : "No");
08313    ast_cli(fd, "  Compact SIP headers:    %s\n", compactheaders ? "Yes" : "No");
08314    ast_cli(fd, "  RTP Timeout:            %d %s\n", global_rtptimeout, global_rtptimeout ? "" : "(Disabled)" );
08315    ast_cli(fd, "  RTP Hold Timeout:       %d %s\n", global_rtpholdtimeout, global_rtpholdtimeout ? "" : "(Disabled)");
08316    ast_cli(fd, "  MWI NOTIFY mime type:   %s\n", default_notifymime);
08317    ast_cli(fd, "  DNS SRV lookup:         %s\n", srvlookup ? "Yes" : "No");
08318    ast_cli(fd, "  Pedantic SIP support:   %s\n", pedanticsipchecking ? "Yes" : "No");
08319    ast_cli(fd, "  Reg. max duration:      %d secs\n", max_expiry);
08320    ast_cli(fd, "  Reg. default duration:  %d secs\n", default_expiry);
08321    ast_cli(fd, "  Outbound reg. timeout:  %d secs\n", global_reg_timeout);
08322    ast_cli(fd, "  Outbound reg. attempts: %d\n", global_regattempts_max);
08323    ast_cli(fd, "  Notify ringing state:   %s\n", global_notifyringing ? "Yes" : "No");
08324    ast_cli(fd, "\nDefault Settings:\n");
08325    ast_cli(fd, "-----------------\n");
08326    ast_cli(fd, "  Context:                %s\n", default_context);
08327    ast_cli(fd, "  Nat:                    %s\n", nat2str(ast_test_flag(&global_flags, SIP_NAT)));
08328    ast_cli(fd, "  DTMF:                   %s\n", dtmfmode2str(ast_test_flag(&global_flags, SIP_DTMF)));
08329    ast_cli(fd, "  Qualify:                %d\n", default_qualify);
08330    ast_cli(fd, "  Use ClientCode:         %s\n", ast_test_flag(&global_flags, SIP_USECLIENTCODE) ? "Yes" : "No");
08331    ast_cli(fd, "  Progress inband:        %s\n", (ast_test_flag(&global_flags, SIP_PROG_INBAND) == SIP_PROG_INBAND_NEVER) ? "Never" : (ast_test_flag(&global_flags, SIP_PROG_INBAND) == SIP_PROG_INBAND_NO) ? "No" : "Yes" );
08332    ast_cli(fd, "  Language:               %s\n", ast_strlen_zero(default_language) ? "(Defaults to English)" : default_language);
08333    ast_cli(fd, "  Musicclass:             %s\n", global_musicclass);
08334    ast_cli(fd, "  Voice Mail Extension:   %s\n", global_vmexten);
08335 
08336    
08337    if (realtimepeers || realtimeusers) {
08338       ast_cli(fd, "\nRealtime SIP Settings:\n");
08339       ast_cli(fd, "----------------------\n");
08340       ast_cli(fd, "  Realtime Peers:         %s\n", realtimepeers ? "Yes" : "No");
08341       ast_cli(fd, "  Realtime Users:         %s\n", realtimeusers ? "Yes" : "No");
08342       ast_cli(fd, "  Cache Friends:          %s\n", ast_test_flag(&global_flags_page2, SIP_PAGE2_RTCACHEFRIENDS) ? "Yes" : "No");
08343       ast_cli(fd, "  Update:                 %s\n", ast_test_flag(&global_flags_page2, SIP_PAGE2_RTUPDATE) ? "Yes" : "No");
08344       ast_cli(fd, "  Ignore Reg. Expire:     %s\n", ast_test_flag(&global_flags_page2, SIP_PAGE2_IGNOREREGEXPIRE) ? "Yes" : "No");
08345       ast_cli(fd, "  Auto Clear:             %d\n", global_rtautoclear);
08346    }
08347    ast_cli(fd, "\n----\n");
08348    return RESULT_SUCCESS;
08349 }

static int sip_show_subscriptions int  fd,
int  argc,
char *  argv[]
[static]
 

sip_show_subscriptions: Show active SIP subscriptions ---

Definition at line 8385 of file chan_sip.c.

References __sip_show_channels().

08386 {
08387         return __sip_show_channels(fd, argc, argv, 1);
08388 }

static int sip_show_user int  fd,
int  argc,
char *  argv[]
[static]
 

sip_show_user: Show one user in detail ---

Definition at line 8179 of file chan_sip.c.

References sip_user::accountcode, sip_user::amaflags, ast_callerid_merge(), ast_cdr_flags2str(), ast_cli(), ast_codec_pref_index(), ast_describe_caller_presentation(), ast_getformatname(), ast_strlen_zero(), ASTOBJ_UNREF, sip_user::call_limit, sip_user::callgroup, sip_user::callingpres, sip_user::chanvars, sip_user::cid_name, sip_user::cid_num, sip_user::context, find_user(), sip_user::ha, sip_user::language, sip_user::md5secret, ast_variable::name, ast_variable::next, sip_user::pickupgroup, sip_user::prefs, print_group(), RESULT_SHOWUSAGE, RESULT_SUCCESS, sip_user::secret, sip_destroy_user(), user, and ast_variable::value.

08180 {
08181    char cbuf[256];
08182    struct sip_user *user;
08183    struct ast_codec_pref *pref;
08184    struct ast_variable *v;
08185    int x = 0, codec = 0, load_realtime = 0;
08186 
08187    if (argc < 4)
08188       return RESULT_SHOWUSAGE;
08189 
08190    /* Load from realtime storage? */
08191    load_realtime = (argc == 5 && !strcmp(argv[4], "load")) ? 1 : 0;
08192 
08193    user = find_user(argv[3], load_realtime);
08194    if (user) {
08195       ast_cli(fd,"\n\n");
08196       ast_cli(fd, "  * Name       : %s\n", user->name);
08197       ast_cli(fd, "  Secret       : %s\n", ast_strlen_zero(user->secret)?"<Not set>":"<Set>");
08198       ast_cli(fd, "  MD5Secret    : %s\n", ast_strlen_zero(user->md5secret)?"<Not set>":"<Set>");
08199       ast_cli(fd, "  Context      : %s\n", user->context);
08200       ast_cli(fd, "  Language     : %s\n", user->language);
08201       if (!ast_strlen_zero(user->accountcode))
08202          ast_cli(fd, "  Accountcode  : %s\n", user->accountcode);
08203       ast_cli(fd, "  AMA flags    : %s\n", ast_cdr_flags2str(user->amaflags));
08204       ast_cli(fd, "  CallingPres  : %s\n", ast_describe_caller_presentation(user->callingpres));
08205       ast_cli(fd, "  Call limit   : %d\n", user->call_limit);
08206       ast_cli(fd, "  Callgroup    : ");
08207       print_group(fd, user->callgroup, 0);
08208       ast_cli(fd, "  Pickupgroup  : ");
08209       print_group(fd, user->pickupgroup, 0);
08210       ast_cli(fd, "  Callerid     : %s\n", ast_callerid_merge(cbuf, sizeof(cbuf), user->cid_name, user->cid_num, "<unspecified>"));
08211       ast_cli(fd, "  ACL          : %s\n", (user->ha?"Yes":"No"));
08212       ast_cli(fd, "  Codec Order  : (");
08213       pref = &user->prefs;
08214       for(x = 0; x < 32 ; x++) {
08215          codec = ast_codec_pref_index(pref,x);
08216          if (!codec)
08217             break;
08218          ast_cli(fd, "%s", ast_getformatname(codec));
08219          if (x < 31 && ast_codec_pref_index(pref,x+1))
08220             ast_cli(fd, "|");
08221       }
08222 
08223       if (!x)
08224          ast_cli(fd, "none");
08225       ast_cli(fd, ")\n");
08226 
08227       if (user->chanvars) {
08228          ast_cli(fd, "  Variables    :\n");
08229          for (v = user->chanvars ; v ; v = v->next)
08230             ast_cli(fd, "                 %s = %s\n", v->name, v->value);
08231       }
08232       ast_cli(fd,"\n");
08233       ASTOBJ_UNREF(user,sip_destroy_user);
08234    } else {
08235       ast_cli(fd,"User %s not found.\n", argv[3]);
08236       ast_cli(fd,"\n");
08237    }
08238 
08239    return RESULT_SUCCESS;
08240 }

static int sip_show_users int  fd,
int  argc,
char *  argv[]
[static]
 

sip_show_users: CLI Command 'SIP Show Users' ---

Definition at line 7489 of file chan_sip.c.

References ast_cli(), ast_test_flag, ASTOBJ_CONTAINER_TRAVERSE, ASTOBJ_RDLOCK, ASTOBJ_UNLOCK, FORMAT, nat2str(), RESULT_SHOWUSAGE, RESULT_SUCCESS, SIP_NAT, and userl.

07490 {
07491    regex_t regexbuf;
07492    int havepattern = 0;
07493 
07494 #define FORMAT  "%-25.25s  %-15.15s  %-15.15s  %-15.15s  %-5.5s%-10.10s\n"
07495 
07496    switch (argc) {
07497    case 5:
07498       if (!strcasecmp(argv[3], "like")) {
07499          if (regcomp(&regexbuf, argv[4], REG_EXTENDED | REG_NOSUB))
07500             return RESULT_SHOWUSAGE;
07501          havepattern = 1;
07502       } else
07503          return RESULT_SHOWUSAGE;
07504    case 3:
07505       break;
07506    default:
07507       return RESULT_SHOWUSAGE;
07508    }
07509 
07510    ast_cli(fd, FORMAT, "Username", "Secret", "Accountcode", "Def.Context", "ACL", "NAT");
07511    ASTOBJ_CONTAINER_TRAVERSE(&userl, 1, do {
07512       ASTOBJ_RDLOCK(iterator);
07513 
07514       if (havepattern && regexec(&regexbuf, iterator->name, 0, NULL, 0)) {
07515          ASTOBJ_UNLOCK(iterator);
07516          continue;
07517       }
07518 
07519       ast_cli(fd, FORMAT, iterator->name, 
07520          iterator->secret, 
07521          iterator->accountcode,
07522          iterator->context,
07523          iterator->ha ? "Yes" : "No",
07524          nat2str(ast_test_flag(iterator, SIP_NAT)));
07525       ASTOBJ_UNLOCK(iterator);
07526    } while (0)
07527    );
07528 
07529    if (havepattern)
07530       regfree(&regexbuf);
07531 
07532    return RESULT_SUCCESS;
07533 #undef FORMAT
07534 }

static int sip_sipredirect struct sip_pvt p,
const char *  dest
[static]
 

sip_sipredirect: Transfer call before connect with a 302 redirect ---

Definition at line 13119 of file chan_sip.c.

References ast_log(), ast_set_flag, ast_strdupa, ast_strlen_zero(), get_header(), host, sip_pvt::initreq, LOG_ERROR, sip_pvt::our_contact, SIP_ALREADYGONE, strsep(), and transmit_response_reliable().

Referenced by sip_transfer().

13120 {
13121    char *cdest;
13122    char *extension, *host, *port;
13123    char tmp[80];
13124    
13125    cdest = ast_strdupa(dest);
13126    if (!cdest) {
13127       ast_log(LOG_ERROR, "Problem allocating the memory\n");
13128       return 0;
13129    }
13130    extension = strsep(&cdest, "@");
13131    host = strsep(&cdest, ":");
13132    port = strsep(&cdest, ":");
13133    if (!extension) {
13134       ast_log(LOG_ERROR, "Missing mandatory argument: extension\n");
13135       return 0;
13136    }
13137 
13138    /* we'll issue the redirect message here */
13139    if (!host) {
13140       char *localtmp;
13141       ast_copy_string(tmp, get_header(&p->initreq, "To"), sizeof(tmp));
13142       if (!strlen(tmp)) {
13143          ast_log(LOG_ERROR, "Cannot retrieve the 'To' header from the original SIP request!\n");
13144          return 0;
13145       }
13146       if ((localtmp = strstr(tmp, "sip:")) && (localtmp = strchr(localtmp, '@'))) {
13147          char lhost[80], lport[80];
13148          memset(lhost, 0, sizeof(lhost));
13149          memset(lport, 0, sizeof(lport));
13150          localtmp++;
13151          /* This is okey because lhost and lport are as big as tmp */
13152          sscanf(localtmp, "%[^<>:; ]:%[^<>:; ]", lhost, lport);
13153          if (!strlen(lhost)) {
13154             ast_log(LOG_ERROR, "Can't find the host address\n");
13155             return 0;
13156          }
13157          host = ast_strdupa(lhost);
13158          if (!host) {
13159             ast_log(LOG_ERROR, "Problem allocating the memory\n");
13160             return 0;
13161          }
13162          if (!ast_strlen_zero(lport)) {
13163             port = ast_strdupa(lport);
13164             if (!port) {
13165                ast_log(LOG_ERROR, "Problem allocating the memory\n");
13166                return 0;
13167             }
13168          }
13169       }
13170    }
13171 
13172    snprintf(p->our_contact, sizeof(p->our_contact), "Transfer <sip:%s@%s%s%s>", extension, host, port ? ":" : "", port ? port : "");
13173    transmit_response_reliable(p, "302 Moved Temporarily", &p->initreq, 1);
13174 
13175    /* this is all that we want to send to that SIP device */
13176    ast_set_flag(p, SIP_ALREADYGONE);
13177 
13178    /* hangup here */
13179    return -1;
13180 }

static int sip_transfer struct ast_channel ast,
const char *  dest
[static]
 

sip_transfer: Transfer SIP call

Definition at line 2638 of file chan_sip.c.

References ast_channel::_state, ast_mutex_lock(), ast_mutex_unlock(), AST_STATE_RING, sip_pvt::lock, sip_sipredirect(), ast_channel::tech_pvt, and transmit_refer().

02639 {
02640    struct sip_pvt *p = ast->tech_pvt;
02641    int res;
02642 
02643    ast_mutex_lock(&p->lock);
02644    if (ast->_state == AST_STATE_RING)
02645       res = sip_sipredirect(p, dest);
02646    else
02647       res = transmit_refer(p, dest);
02648    ast_mutex_unlock(&p->lock);
02649    return res;
02650 }

static int sip_write struct ast_channel ast,
struct ast_frame frame
[static]
 

sip_write: Send frame to media channel (rtp) ---

Definition at line 2545 of file chan_sip.c.

References ast_channel::_state, AST_FRAME_IMAGE, AST_FRAME_VIDEO, AST_FRAME_VOICE, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_rtp_write(), ast_set_flag, AST_STATE_UP, ast_test_flag, ast_frame::frametype, sip_pvt::initreq, sip_pvt::lastrtptx, sip_pvt::lock, LOG_WARNING, ast_channel::nativeformats, ast_channel::readformat, sip_pvt::rtp, SIP_OUTGOING, SIP_PROGRESS_SENT, ast_frame::subclass, ast_channel::tech_pvt, transmit_response_with_sdp(), sip_pvt::vrtp, and ast_channel::writeformat.

02546 {
02547    struct sip_pvt *p = ast->tech_pvt;
02548    int res = 0;
02549    switch (frame->frametype) {
02550    case AST_FRAME_VOICE:
02551       if (!(frame->subclass & ast->nativeformats)) {
02552          ast_log(LOG_WARNING, "Asked to transmit frame type %d, while native formats is %d (read/write = %d/%d)\n",
02553             frame->subclass, ast->nativeformats, ast->readformat, ast->writeformat);
02554          return 0;
02555       }
02556       if (p) {
02557          ast_mutex_lock(&p->lock);
02558          if (p->rtp) {
02559             /* If channel is not up, activate early media session */
02560             if ((ast->_state != AST_STATE_UP) && !ast_test_flag(p, SIP_PROGRESS_SENT) && !ast_test_flag(p, SIP_OUTGOING)) {
02561                transmit_response_with_sdp(p, "183 Session Progress", &p->initreq, 0);
02562                ast_set_flag(p, SIP_PROGRESS_SENT); 
02563             }
02564             time(&p->lastrtptx);
02565             res =  ast_rtp_write(p->rtp, frame);
02566          }
02567          ast_mutex_unlock(&p->lock);
02568       }
02569       break;
02570    case AST_FRAME_VIDEO:
02571       if (p) {
02572          ast_mutex_lock(&p->lock);
02573          if (p->vrtp) {
02574             /* Activate video early media */
02575             if ((ast->_state != AST_STATE_UP) && !ast_test_flag(p, SIP_PROGRESS_SENT) && !ast_test_flag(p, SIP_OUTGOING)) {
02576                transmit_response_with_sdp(p, "183 Session Progress", &p->initreq, 0);
02577                ast_set_flag(p, SIP_PROGRESS_SENT); 
02578             }
02579             time(&p->lastrtptx);
02580             res =  ast_rtp_write(p->vrtp, frame);
02581          }
02582          ast_mutex_unlock(&p->lock);
02583       }
02584       break;
02585    case AST_FRAME_IMAGE:
02586       return 0;
02587       break;
02588    default: 
02589       ast_log(LOG_WARNING, "Can't send %d type frames with SIP write\n", frame->frametype);
02590       return 0;
02591    }
02592 
02593    return res;
02594 }

static int sipsock_read int *  id,
int  fd,
short  events,
void *  ignore
[static]
 

sipsock_read: Read data from SIP socket ---

Definition at line 11256 of file chan_sip.c.

References append_history(), ast_inet_ntoa(), ast_log(), ast_mutex_lock(), ast_mutex_trylock(), ast_mutex_unlock(), ast_set_flag, ast_test_flag, ast_update_use_count(), ast_verbose(), sip_pvt::callid, find_call(), find_sip_method(), get_header(), handle_request(), sip_pvt::lock, ast_channel::lock, LOG_DEBUG, LOG_ERROR, LOG_NOTICE, LOG_WARNING, lws2sws(), ast_channel::name, sip_pvt::owner, parse_request(), pedanticsipchecking, recordhistory, sip_pvt::recv, sip_debug_test_addr(), SIP_PKT_DEBUG, and sipsock.

Referenced by do_monitor().

11257 {
11258    struct sip_request req;
11259    struct sockaddr_in sin = { 0, };
11260    struct sip_pvt *p;
11261    int res;
11262    socklen_t len;
11263    int nounlock;
11264    int recount = 0;
11265    char iabuf[INET_ADDRSTRLEN];
11266    unsigned int lockretry = 100;
11267 
11268    len = sizeof(sin);
11269    memset(&req, 0, sizeof(req));
11270    res = recvfrom(sipsock, req.data, sizeof(req.data) - 1, 0, (struct sockaddr *)&sin, &len);
11271    if (res < 0) {
11272 #if !defined(__FreeBSD__)
11273       if (errno == EAGAIN)
11274          ast_log(LOG_NOTICE, "SIP: Received packet with bad UDP checksum\n");
11275       else 
11276 #endif
11277       if (errno != ECONNREFUSED)
11278          ast_log(LOG_WARNING, "Recv error: %s\n", strerror(errno));
11279       return 1;
11280    }
11281    if (res == sizeof(req.data)) {
11282       ast_log(LOG_DEBUG, "Received packet exceeds buffer. Data is possibly lost\n");
11283       req.data[sizeof(req.data) - 1] = '\0';
11284    } else
11285       req.data[res] = '\0';
11286    req.len = res;
11287    if(sip_debug_test_addr(&sin))
11288       ast_set_flag(&req, SIP_PKT_DEBUG);
11289    if (pedanticsipchecking)
11290       req.len = lws2sws(req.data, req.len);  /* Fix multiline headers */
11291    if (ast_test_flag(&req, SIP_PKT_DEBUG)) {
11292       ast_verbose("\n<-- SIP read from %s:%d: \n%s\n", ast_inet_ntoa(iabuf, sizeof(iabuf), sin.sin_addr), ntohs(sin.sin_port), req.data);
11293    }
11294    parse_request(&req);
11295    req.method = find_sip_method(req.rlPart1);
11296    if (ast_test_flag(&req, SIP_PKT_DEBUG)) {
11297       ast_verbose("--- (%d headers %d lines)", req.headers, req.lines);
11298       if (req.headers + req.lines == 0) 
11299          ast_verbose(" Nat keepalive ");
11300       ast_verbose("---\n");
11301    }
11302 
11303    if (req.headers < 2) {
11304       /* Must have at least two headers */
11305       return 1;
11306    }
11307 
11308 
11309    /* Process request, with netlock held */
11310 retrylock:
11311    ast_mutex_lock(&netlock);
11312    p = find_call(&req, &sin, req.method);
11313    if (p) {
11314       /* Go ahead and lock the owner if it has one -- we may need it */
11315       if (p->owner && ast_mutex_trylock(&p->owner->lock)) {
11316          ast_log(LOG_DEBUG, "Failed to grab lock, trying again...\n");
11317          ast_mutex_unlock(&p->lock);
11318          ast_mutex_unlock(&netlock);
11319          /* Sleep for a very short amount of time */
11320          usleep(1);
11321          if (--lockretry)
11322             goto retrylock;
11323       }
11324       if (!lockretry) {
11325          ast_log(LOG_ERROR, "We could NOT get the channel lock for %s! \n", p->owner->name);
11326          ast_log(LOG_ERROR, "SIP MESSAGE JUST IGNORED: %s \n", req.data);
11327          ast_log(LOG_ERROR, "BAD! BAD! BAD!\n");
11328          return 1;
11329       }
11330       memcpy(&p->recv, &sin, sizeof(p->recv));
11331       if (recordhistory) {
11332          char tmp[80];
11333          /* This is a response, note what it was for */
11334          snprintf(tmp, sizeof(tmp), "%s / %s /%s", req.data, get_header(&req, "CSeq"), req.rlPart2);
11335          append_history(p, "Rx", tmp);
11336       }
11337       nounlock = 0;
11338       if (handle_request(p, &req, &sin, &recount, &nounlock) == -1) {
11339          /* Request failed */
11340          ast_log(LOG_DEBUG, "SIP message could not be handled, bad request: %-70.70s\n", p->callid[0] ? p->callid : "<no callid>");
11341       }
11342       
11343       if (p->owner && !nounlock)
11344          ast_mutex_unlock(&p->owner->lock);
11345       ast_mutex_unlock(&p->lock);
11346    }
11347    ast_mutex_unlock(&netlock);
11348    if (recount)
11349       ast_update_use_count();
11350 
11351    return 1;
11352 }

static const char* subscription_type2str enum subscriptiontype  subtype  )  [static]
 

subscription_type2str: Show subscription type in string format

Definition at line 8352 of file chan_sip.c.

References subscription_types, and type.

Referenced by __sip_show_channels(), and sip_show_channel().

08352                                                                         {
08353    int i;
08354 
08355    for (i = 1; (i < (sizeof(subscription_types) / sizeof(subscription_types[0]))); i++) {
08356       if (subscription_types[i].type == subtype) {
08357          return subscription_types[i].text;
08358       }
08359    }
08360    return subscription_types[0].text;
08361 }

static struct sip_peer * temp_peer const char *  name  )  [static]
 

temp_peer: Create temporary peer (used in autocreatepeer mode) ---

Definition at line 12162 of file chan_sip.c.

References apeerobjs, ast_copy_flags, ast_set_flag, ASTOBJ_INIT, default_context, default_language, DEFAULT_SIP_PORT, default_subscribecontext, global_capability, global_musicclass, global_rtpholdtimeout, global_rtpkeepalive, global_rtptimeout, malloc, reg_source_db(), SIP_FLAGS_TO_COPY, SIP_PAGE2_DYNAMIC, and SIP_SELFDESTRUCT.

Referenced by register_verify().

12163 {
12164    struct sip_peer *peer;
12165 
12166    peer = malloc(sizeof(*peer));
12167    if (!peer)
12168       return NULL;
12169 
12170    memset(peer, 0, sizeof(*peer));
12171    apeerobjs++;
12172    ASTOBJ_INIT(peer);
12173 
12174    peer->expire = -1;
12175    peer->pokeexpire = -1;
12176    ast_copy_string(peer->name, name, sizeof(peer->name));
12177    ast_copy_flags(peer, &global_flags, SIP_FLAGS_TO_COPY);
12178    strcpy(peer->context, default_context);
12179    strcpy(peer->subscribecontext, default_subscribecontext);
12180    strcpy(peer->language, default_language);
12181    strcpy(peer->musicclass, global_musicclass);
12182    peer->addr.sin_port = htons(DEFAULT_SIP_PORT);
12183    peer->addr.sin_family = AF_INET;
12184    peer->capability = global_capability;
12185    peer->rtptimeout = global_rtptimeout;
12186    peer->rtpholdtimeout = global_rtpholdtimeout;
12187    peer->rtpkeepalive = global_rtpkeepalive;
12188    ast_set_flag(peer, SIP_SELFDESTRUCT);
12189    ast_set_flag(&peer->flags_page2, SIP_PAGE2_DYNAMIC);
12190    peer->prefs = prefs;
12191    reg_source_db(peer);
12192 
12193    return peer;
12194 }

static force_inline int thread_safe_rand void   )  [static]
 

Thread-safe random number generator.

Returns:
a random number
This function uses a mutex lock to guarantee that no two threads will receive the same random number.

Definition at line 963 of file chan_sip.c.

References ast_mutex_lock(), and ast_mutex_unlock().

Referenced by build_callid(), build_reply_digest(), check_auth(), make_our_tag(), reg_source_db(), reqprep(), sip_alloc(), transmit_fake_auth_response(), transmit_invite(), and transmit_register().

00964 {
00965    int val;
00966 
00967    ast_mutex_lock(&rand_lock);
00968    val = rand();
00969    ast_mutex_unlock(&rand_lock);
00970    
00971    return val;
00972 }

static void transmit_fake_auth_response struct sip_pvt p,
struct sip_request req,
char *  randdata,
int  randlen,
int  reliable
[static]
 

Send a fake 401 Unauthorized response when the administrator wants to hide the names of local users/peers from fishers.

Definition at line 6437 of file chan_sip.c.

References thread_safe_rand(), and transmit_response_with_auth().

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

06438 {
06439    snprintf(randdata, randlen, "%08x", thread_safe_rand());
06440    transmit_response_with_auth(p, "401 Unauthorized", req, randdata, reliable, "WWW-Authenticate", 0);
06441 }

static int transmit_info_with_digit struct sip_pvt p,
char  digit
[static]
 

transmit_info_with_digit: Send SIP INFO dtmf message, see Cisco documentation on cisco.co m ---

Definition at line 5642 of file chan_sip.c.

References add_digit(), sip_pvt::ocseq, reqprep(), send_request(), and SIP_INFO.

Referenced by sip_senddigit().

05643 {
05644    struct sip_request req;
05645    reqprep(&req, p, SIP_INFO, 0, 1);
05646    add_digit(&req, digit);
05647    return send_request(p, &req, 1, p->ocseq);
05648 }

static int transmit_info_with_vidupdate struct sip_pvt p  )  [static]
 

transmit_info_with_vidupdate: Send SIP INFO with video update request ---

Definition at line 5651 of file chan_sip.c.

References add_vidupdate(), sip_pvt::ocseq, reqprep(), send_request(), and SIP_INFO.

Referenced by sip_indicate().

05652 {
05653    struct sip_request req;
05654    reqprep(&req, p, SIP_INFO, 0, 1);
05655    add_vidupdate(&req);
05656    return send_request(p, &req, 1, p->ocseq);
05657 }

static int transmit_invite struct sip_pvt p,
int  sipmethod,
int  sendsdp,
int  init
[static]
 

transmit_invite: Build REFER/INVITE/OPTIONS message and transmit it ---

Definition at line 4942 of file chan_sip.c.

References add_blank_header(), add_header(), add_header_contentLength(), add_sdp(), sip_invite_param::addsipheaders, ALLOWED_METHODS, append_date(), AST_LIST_TRAVERSE, ast_log(), ast_rtp_offered_from_local(), ast_strdupa, ast_strlen_zero(), ast_var_name(), ast_var_value(), ast_verbose(), sip_invite_param::auth, sip_invite_param::authheader, sip_pvt::branch, build_via(), copy_request(), sip_invite_param::distinctive_ring, sip_request::headers, sip_pvt::initreq, initreqprep(), sip_pvt::lastinvite, sip_request::lines, LOG_DEBUG, LOG_WARNING, sip_request::method, sip_pvt::ocseq, sip_pvt::options, sip_invite_param::osptoken, sip_pvt::owner, parse_request(), sip_pvt::refer_to, sip_pvt::referred_by, reqprep(), sip_pvt::rtp, send_request(), sip_debug_test_pvt(), SIP_OPTIONS, SIP_REFER, sipdebug, thread_safe_rand(), ast_channel::varshead, and sip_pvt::via.

Referenced by do_proxy_auth(), sip_call(), and sip_poke_peer().

04943 {
04944    struct sip_request req;
04945    
04946    req.method = sipmethod;
04947    if (init) {
04948       /* Bump branch even on initial requests */
04949       p->branch ^= thread_safe_rand();
04950       build_via(p, p->via, sizeof(p->via));
04951       if (init > 1)
04952          initreqprep(&req, p, sipmethod);
04953       else
04954          reqprep(&req, p, sipmethod, 0, 1);
04955    } else
04956       reqprep(&req, p, sipmethod, 0, 1);
04957       
04958    if (p->options && p->options->auth)
04959       add_header(&req, p->options->authheader, p->options->auth);
04960    append_date(&req);
04961    if (sipmethod == SIP_REFER) { /* Call transfer */
04962       if (!ast_strlen_zero(p->refer_to))
04963          add_header(&req, "Refer-To", p->refer_to);
04964       if (!ast_strlen_zero(p->referred_by))
04965          add_header(&req, "Referred-By", p->referred_by);
04966    }
04967 #ifdef OSP_SUPPORT
04968    if ((req.method != SIP_OPTIONS) && p->options && !ast_strlen_zero(p->options->osptoken)) {
04969       ast_log(LOG_DEBUG,"Adding OSP Token: %s\n", p->options->osptoken);
04970       add_header(&req, "P-OSP-Auth-Token", p->options->osptoken);
04971    }
04972 #endif
04973    if (p->options && !ast_strlen_zero(p->options->distinctive_ring))
04974    {
04975       add_header(&req, "Alert-Info", p->options->distinctive_ring);
04976    }
04977    add_header(&req, "Allow", ALLOWED_METHODS);
04978    if (p->options && p->options->addsipheaders ) {
04979       struct ast_channel *ast;
04980       char *header = (char *) NULL;
04981       char *content = (char *) NULL;
04982       char *end = (char *) NULL;
04983       struct varshead *headp = (struct varshead *) NULL;
04984       struct ast_var_t *current;
04985 
04986       ast = p->owner;   /* The owner channel */
04987       if (ast) {
04988          char *headdup;
04989          headp = &ast->varshead;
04990          if (!headp)
04991             ast_log(LOG_WARNING,"No Headp for the channel...ooops!\n");
04992          else {
04993             AST_LIST_TRAVERSE(headp, current, entries) {  
04994                /* SIPADDHEADER: Add SIP header to outgoing call        */
04995                if (!strncasecmp(ast_var_name(current), "SIPADDHEADER", strlen("SIPADDHEADER"))) {
04996                   header = ast_var_value(current);
04997                   headdup = ast_strdupa(header);
04998                   /* Strip of the starting " (if it's there) */
04999                   if (*headdup == '"')
05000                      headdup++;
05001                   if ((content = strchr(headdup, ':'))) {
05002                      *content = '\0';
05003                      content++;  /* Move pointer ahead */
05004                      /* Skip white space */
05005                      while (*content == ' ')
05006                         content++;
05007                      /* Strip the ending " (if it's there) */
05008                      end = content + strlen(content) -1; 
05009                      if (*end == '"')
05010                         *end = '\0';
05011                   
05012                      add_header(&req, headdup, content);
05013                      if (sipdebug)
05014                         ast_log(LOG_DEBUG, "Adding SIP Header \"%s\" with content :%s: \n", headdup, content);
05015                   }
05016                }
05017             }
05018          }
05019       }
05020    }
05021    if (sdp && p->rtp) {
05022       ast_rtp_offered_from_local(p->rtp, 1);
05023       add_sdp(&req, p);
05024    } else {
05025       add_header_contentLength(&req, 0);
05026       add_blank_header(&req);
05027    }
05028 
05029    if (!p->initreq.headers) {
05030       /* Use this as the basis */
05031       copy_request(&p->initreq, &req);
05032       parse_request(&p->initreq);
05033       if (sip_debug_test_pvt(p))
05034          ast_verbose("%d headers, %d lines\n", p->initreq.headers, p->initreq.lines);
05035    }
05036    p->lastinvite = p->ocseq;
05037    return send_request(p, &req, init ? 2 : 1, p->ocseq);
05038 }

static int transmit_message_with_text struct sip_pvt p,
const char *  text
[static]
 

transmit_message_with_text: Transmit text with SIP MESSAGE method ---

Definition at line 5588 of file chan_sip.c.

References add_text(), sip_pvt::ocseq, reqprep(), send_request(), and SIP_MESSAGE.

Referenced by sip_sendtext().

05589 {
05590    struct sip_request req;
05591    reqprep(&req, p, SIP_MESSAGE, 0, 1);
05592    add_text(&req, text);
05593    return send_request(p, &req, 1, p->ocseq);
05594 }

static int transmit_notify_with_mwi struct sip_pvt p,
int  newmsgs,
int  oldmsgs,
char *  vmexten
[static]
 

transmit_notify_with_mwi: Notify user of messages waiting in voicemail ---

Definition at line 5213 of file chan_sip.c.

References add_header(), add_header_contentLength(), add_line(), ast_build_string(), ast_inet_ntoa(), ast_log(), ast_strlen_zero(), ast_verbose(), copy_request(), default_notifymime, determine_firstline_parts(), sip_pvt::fromdomain, global_vmexten, sip_request::headers, sip_pvt::initreq, initreqprep(), sip_request::lines, LOG_WARNING, sip_pvt::ocseq, sip_pvt::ourip, parse_request(), send_request(), sip_debug_test_pvt(), SIP_NOTIFY, and t.

Referenced by sip_send_mwi_to_peer().

05214 {
05215    struct sip_request req;
05216    char tmp[500];
05217    char *t = tmp;
05218    size_t maxbytes = sizeof(tmp);
05219    char iabuf[INET_ADDRSTRLEN];
05220 
05221    initreqprep(&req, p, SIP_NOTIFY);
05222    add_header(&req, "Event", "message-summary");
05223    add_header(&req, "Content-Type", default_notifymime);
05224 
05225    ast_build_string(&t, &maxbytes, "Messages-Waiting: %s\r\n", newmsgs ? "yes" : "no");
05226    ast_build_string(&t, &maxbytes, "Message-Account: sip:%s@%s\r\n", !ast_strlen_zero(vmexten) ? vmexten : global_vmexten, ast_strlen_zero(p->fromdomain) ? ast_inet_ntoa(iabuf, sizeof(iabuf), p->ourip) : p->fromdomain);
05227    ast_build_string(&t, &maxbytes, "Voice-Message: %d/%d (0/0)\r\n", newmsgs, oldmsgs);
05228 
05229    if (t > tmp + sizeof(tmp))
05230       ast_log(LOG_WARNING, "Buffer overflow detected!!  (Please file a bug report)\n");
05231 
05232    add_header_contentLength(&req, strlen(tmp));
05233    add_line(&req, tmp);
05234 
05235    if (!p->initreq.headers) { /* Use this as the basis */
05236       copy_request(&p->initreq, &req);
05237       parse_request(&p->initreq);
05238       if (sip_debug_test_pvt(p))
05239          ast_verbose("%d headers, %d lines\n", p->initreq.headers, p->initreq.lines);
05240       determine_firstline_parts(&p->initreq);
05241    }
05242 
05243    return send_request(p, &req, 1, p->ocseq);
05244 }

static int transmit_notify_with_sipfrag struct sip_pvt p,
int  cseq
[static]
 

transmit_notify_with_sipfrag: Notify a transferring party of the status of trasnfer ---

Definition at line 5266 of file chan_sip.c.

References add_header(), add_header_contentLength(), add_line(), ast_verbose(), copy_request(), determine_firstline_parts(), sip_request::headers, sip_pvt::initreq, sip_request::lines, sip_pvt::ocseq, parse_request(), reqprep(), send_request(), sip_debug_test_pvt(), and SIP_NOTIFY.

Referenced by handle_request_refer().

05267 {
05268    struct sip_request req;
05269    char tmp[20];
05270    reqprep(&req, p, SIP_NOTIFY, 0, 1);
05271    snprintf(tmp, sizeof(tmp), "refer;id=%d", cseq);
05272    add_header(&req, "Event", tmp);
05273    add_header(&req, "Subscription-state", "terminated;reason=noresource");
05274    add_header(&req, "Content-Type", "message/sipfrag;version=2.0");
05275 
05276    strcpy(tmp, "SIP/2.0 200 OK");
05277    add_header_contentLength(&req, strlen(tmp));
05278    add_line(&req, tmp);
05279 
05280    if (!p->initreq.headers) {
05281       /* Use this as the basis */
05282       copy_request(&p->initreq, &req);
05283       parse_request(&p->initreq);
05284       if (sip_debug_test_pvt(p))
05285          ast_verbose("%d headers, %d lines\n", p->initreq.headers, p->initreq.lines);
05286       determine_firstline_parts(&p->initreq);
05287    }
05288 
05289    return send_request(p, &req, 1, p->ocseq);
05290 }

static int transmit_refer struct sip_pvt p,
const char *  dest
[static]
 

transmit_refer: Transmit SIP REFER message ---

Definition at line 5597 of file chan_sip.c.

References add_blank_header(), add_header(), ast_log(), ast_strlen_zero(), ast_test_flag, sip_pvt::from, get_header(), get_in_brackets(), sip_pvt::initreq, LOG_NOTICE, sip_pvt::ocseq, sip_pvt::our_contact, sip_pvt::refer_to, sip_pvt::referred_by, reqprep(), send_request(), SIP_OUTGOING, and SIP_REFER.

Referenced by sip_transfer().

05598 {
05599    struct sip_request req;
05600    char from[256];
05601    char *of, *c;
05602    char referto[256];
05603 
05604    if (ast_test_flag(p, SIP_OUTGOING)) 
05605       of = get_header(&p->initreq, "To");
05606    else
05607       of = get_header(&p->initreq, "From");
05608    ast_copy_string(from, of, sizeof(from));
05609    of = get_in_brackets(from);
05610    ast_copy_string(p->from,of,sizeof(p->from));
05611    if (strncmp(of, "sip:", 4)) {
05612       ast_log(LOG_NOTICE, "From address missing 'sip:', using it anyway\n");
05613    } else
05614       of += 4;
05615    /* Get just the username part */
05616    if ((c = strchr(dest, '@'))) {
05617       c = NULL;
05618    } else if ((c = strchr(of, '@'))) {
05619       *c = '\0';
05620       c++;
05621    }
05622    if (c) {
05623       snprintf(referto, sizeof(referto), "<sip:%s@%s>", dest, c);
05624    } else {
05625       snprintf(referto, sizeof(referto), "<sip:%s>", dest);
05626    }
05627 
05628    /* save in case we get 407 challenge */
05629    ast_copy_string(p->refer_to, referto, sizeof(p->refer_to));
05630    ast_copy_string(p->referred_by, p->our_contact, sizeof(p->referred_by));
05631 
05632    reqprep(&req, p, SIP_REFER, 0, 1);
05633    add_header(&req, "Refer-To", referto);
05634    if (!ast_strlen_zero(p->our_contact))
05635       add_header(&req, "Referred-By", p->our_contact);
05636    add_blank_header(&req);
05637    return send_request(p, &req, 1, p->ocseq);
05638 }

static int transmit_register struct sip_registry r,
int  sipmethod,
char *  auth,
char *  authheader
[static]
 

transmit_register: Transmit register to SIP proxy or UA ---

Definition at line 5396 of file chan_sip.c.

References __ourip, add_blank_header(), add_header(), add_header_contentLength(), append_history(), ast_log(), ast_sched_add(), ast_sched_del(), ast_set_flag, ast_sip_ouraddrfor(), ast_strlen_zero(), ast_verbose(), ASTOBJ_REF, sip_pvt::authname, sip_registry::authuser, sip_pvt::branch, build_callid(), build_contact(), build_reply_digest(), build_via(), sip_registry::call, sip_pvt::callid, sip_registry::callid, sip_registry::callid_valid, sip_registry::contact, copy_request(), create_addr(), default_expiry, default_fromdomain, DEFAULT_MAX_FORWARDS, default_useragent, determine_firstline_parts(), sip_registry::domain, sip_pvt::domain, sip_pvt::exten, sip_pvt::fromdomain, sip_pvt::fromuser, global_reg_timeout, sip_request::headers, sip_registry::hostname, init_req(), sip_pvt::initreq, sip_request::lines, LOG_DEBUG, LOG_NOTICE, LOG_WARNING, make_our_tag(), sip_registry::md5secret, sip_pvt::nonce, sip_registry::nonce, sip_registry::noncecount, sip_pvt::noncecount, sip_pvt::ocseq, sip_registry::ocseq, sip_registry::opaque, sip_pvt::opaque, option_debug, sip_pvt::our_contact, sip_pvt::ourip, parse_request(), sip_pvt::peermd5secret, sip_pvt::peername, sip_pvt::peersecret, sip_registry::portno, sip_registry::qop, sip_pvt::qop, sip_registry::realm, sip_pvt::realm, recordhistory, REG_STATE_AUTHSENT, REG_STATE_REGSENT, sip_registry::regattempts, sip_pvt::registry, sip_registry::regstate, sip_pvt::sa, sip_registry::secret, send_request(), sip_alloc(), sip_debug_test_pvt(), sip_destroy(), sip_methods, SIP_OUTGOING, sip_reg_timeout(), SIP_REGISTER, sipdebug, sip_pvt::tag, cfsip_methods::text, sip_pvt::theirtag, thread_safe_rand(), sip_registry::timeout, sip_pvt::tohost, sip_pvt::uri, sip_pvt::username, and sip_registry::username.

Referenced by __sip_do_register(), do_register_auth(), and sip_reg_timeout().

05397 {
05398    struct sip_request req;
05399    char from[256];
05400    char to[256];
05401    char tmp[80];
05402    char via[80];
05403    char addr[80];
05404    struct sip_pvt *p;
05405 
05406    /* exit if we are already in process with this registrar ?*/
05407    if ( r == NULL || ((auth==NULL) && (r->regstate==REG_STATE_REGSENT || r->regstate==REG_STATE_AUTHSENT))) {
05408       ast_log(LOG_NOTICE, "Strange, trying to register %s@%s when registration already pending\n", r->username, r->hostname);
05409       return 0;
05410    }
05411 
05412    if (r->call) { /* We have a registration */
05413       if (!auth) {
05414          ast_log(LOG_WARNING, "Already have a REGISTER going on to %s@%s?? \n", r->username, r->hostname);
05415          return 0;
05416       } else {
05417          p = r->call;
05418          make_our_tag(p->tag, sizeof(p->tag));  /* create a new local tag for every register attempt */
05419          p->theirtag[0]='\0'; /* forget their old tag, so we don't match tags when getting response */
05420       }
05421    } else {
05422       /* Build callid for registration if we haven't registered before */
05423       if (!r->callid_valid) {
05424          build_callid(r->callid, sizeof(r->callid), __ourip, default_fromdomain);
05425          r->callid_valid = 1;
05426       }
05427       /* Allocate SIP packet for registration */
05428       p=sip_alloc( r->callid, NULL, 0, SIP_REGISTER);
05429       if (!p) {
05430          ast_log(LOG_WARNING, "Unable to allocate registration call\n");
05431          return 0;
05432       }
05433       if (recordhistory) {
05434          char tmp[80];
05435          snprintf(tmp, sizeof(tmp), "Account: %s@%s", r->username, r->hostname);
05436          append_history(p, "RegistryInit", tmp);
05437       }
05438       /* Find address to hostname */
05439       if (create_addr(p, r->hostname)) {
05440          /* we have what we hope is a temporary network error,
05441           * probably DNS.  We need to reschedule a registration try */
05442          sip_destroy(p);
05443          if (r->timeout > -1) {
05444             ast_sched_del(sched, r->timeout);
05445             r->timeout = ast_sched_add(sched, global_reg_timeout*1000, sip_reg_timeout, r);
05446             ast_log(LOG_WARNING, "Still have a registration timeout for %s@%s (create_addr() error), %d\n", r->username, r->hostname, r->timeout);
05447          } else {
05448             r->timeout = ast_sched_add(sched, global_reg_timeout*1000, sip_reg_timeout, r);
05449             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);
05450          }
05451          r->regattempts++;
05452          return 0;
05453       }
05454       /* Copy back Call-ID in case create_addr changed it */
05455       ast_copy_string(r->callid, p->callid, sizeof(r->callid));
05456       if (r->portno)
05457          p->sa.sin_port = htons(r->portno);
05458       else  /* Set registry port to the port set from the peer definition/srv or default */
05459          r->portno = ntohs(p->sa.sin_port);
05460       ast_set_flag(p, SIP_OUTGOING);   /* Registration is outgoing call */
05461       r->call=p;        /* Save pointer to SIP packet */
05462       p->registry=ASTOBJ_REF(r); /* Add pointer to registry in packet */
05463       if (!ast_strlen_zero(r->secret)) /* Secret (password) */
05464          ast_copy_string(p->peersecret, r->secret, sizeof(p->peersecret));
05465       if (!ast_strlen_zero(r->md5secret))
05466          ast_copy_string(p->peermd5secret, r->md5secret, sizeof(p->peermd5secret));
05467       /* User name in this realm  
05468       - if authuser is set, use that, otherwise use username */
05469       if (!ast_strlen_zero(r->authuser)) {   
05470          ast_copy_string(p->peername, r->authuser, sizeof(p->peername));
05471          ast_copy_string(p->authname, r->authuser, sizeof(p->authname));
05472       } else {
05473          if (!ast_strlen_zero(r->username)) {
05474             ast_copy_string(p->peername, r->username, sizeof(p->peername));
05475             ast_copy_string(p->authname, r->username, sizeof(p->authname));
05476             ast_copy_string(p->fromuser, r->username, sizeof(p->fromuser));
05477          }
05478       }
05479       if (!ast_strlen_zero(r->username))
05480          ast_copy_string(p->username, r->username, sizeof(p->username));
05481       /* Save extension in packet */
05482       ast_copy_string(p->exten, r->contact, sizeof(p->exten));
05483 
05484       /*
05485         check which address we should use in our contact header 
05486         based on whether the remote host is on the external or
05487         internal network so we can register through nat
05488        */
05489       if (ast_sip_ouraddrfor(&p->sa.sin_addr, &p->ourip))
05490          memcpy(&p->ourip, &bindaddr.sin_addr, sizeof(p->ourip));
05491       build_contact(p);
05492    }
05493 
05494    /* set up a timeout */
05495    if (auth == NULL)  {
05496       if (r->timeout > -1) {
05497          ast_log(LOG_WARNING, "Still have a registration timeout, #%d - deleting it\n", r->timeout);
05498          ast_sched_del(sched, r->timeout);
05499       }
05500       r->timeout = ast_sched_add(sched, global_reg_timeout * 1000, sip_reg_timeout, r);
05501       ast_log(LOG_DEBUG, "Scheduled a registration timeout for %s id  #%d \n", r->hostname, r->timeout);
05502    }
05503 
05504    if (strchr(r->username, '@')) {
05505       snprintf(from, sizeof(from), "<sip:%s>;tag=%s", r->username, p->tag);
05506       if (!ast_strlen_zero(p->theirtag))
05507          snprintf(to, sizeof(to), "<sip:%s>;tag=%s", r->username, p->theirtag);
05508       else
05509          snprintf(to, sizeof(to), "<sip:%s>", r->username);
05510    } else {
05511       snprintf(from, sizeof(from), "<sip:%s@%s>;tag=%s", r->username, p->tohost, p->tag);
05512       if (!ast_strlen_zero(p->theirtag))
05513          snprintf(to, sizeof(to), "<sip:%s@%s>;tag=%s", r->username, p->tohost, p->theirtag);
05514       else
05515          snprintf(to, sizeof(to), "<sip:%s@%s>", r->username, p->tohost);
05516    }
05517    
05518    /* Fromdomain is what we are registering to, regardless of actual
05519       host name from SRV */
05520    if (!ast_strlen_zero(p->fromdomain))
05521       snprintf(addr, sizeof(addr), "sip:%s", p->fromdomain);
05522    else
05523       snprintf(addr, sizeof(addr), "sip:%s", r->hostname);
05524    ast_copy_string(p->uri, addr, sizeof(p->uri));
05525 
05526    p->branch ^= thread_safe_rand();
05527 
05528    memset(&req, 0, sizeof(req));
05529    init_req(&req, sipmethod, addr);
05530 
05531    /* Add to CSEQ */
05532    snprintf(tmp, sizeof(tmp), "%u %s", ++r->ocseq, sip_methods[sipmethod].text);
05533    p->ocseq = r->ocseq;
05534 
05535    build_via(p, via, sizeof(via));
05536    add_header(&req, "Via", via);
05537    add_header(&req, "From", from);
05538    add_header(&req, "To", to);
05539    add_header(&req, "Call-ID", p->callid);
05540    add_header(&req, "CSeq", tmp);
05541    add_header(&req, "User-Agent", default_useragent);
05542    add_header(&req, "Max-Forwards", DEFAULT_MAX_FORWARDS);
05543 
05544    
05545    if (auth)   /* Add auth header */
05546       add_header(&req, authheader, auth);
05547    else if (!ast_strlen_zero(r->nonce)) {
05548       char digest[1024];
05549 
05550       /* We have auth data to reuse, build a digest header! */
05551       if (sipdebug)
05552          ast_log(LOG_DEBUG, "   >>> Re-using Auth data for %s@%s\n", r->username, r->hostname);
05553       ast_copy_string(p->realm, r->realm, sizeof(p->realm));
05554       ast_copy_string(p->nonce, r->nonce, sizeof(p->nonce));
05555       ast_copy_string(p->domain, r->domain, sizeof(p->domain));
05556       ast_copy_string(p->opaque, r->opaque, sizeof(p->opaque));
05557       ast_copy_string(p->qop, r->qop, sizeof(p->qop));
05558       p->noncecount = r->noncecount++;
05559 
05560       memset(digest,0,sizeof(digest));
05561       if(!build_reply_digest(p, sipmethod, digest, sizeof(digest)))
05562          add_header(&req, "Authorization", digest);
05563       else
05564          ast_log(LOG_NOTICE, "No authorization available for authentication of registration to %s@%s\n", r->username, r->hostname);
05565    
05566    }
05567 
05568    snprintf(tmp, sizeof(tmp), "%d", default_expiry);
05569    add_header(&req, "Expires", tmp);
05570    add_header(&req, "Contact", p->our_contact);
05571    add_header(&req, "Event", "registration");
05572    add_header_contentLength(&req, 0);
05573    add_blank_header(&req);
05574    copy_request(&p->initreq, &req);
05575    parse_request(&p->initreq);
05576    if (sip_debug_test_pvt(p)) {
05577       ast_verbose("REGISTER %d headers, %d lines\n", p->initreq.headers, p->initreq.lines);
05578    }
05579    determine_firstline_parts(&p->initreq);
05580    r->regstate=auth?REG_STATE_AUTHSENT:REG_STATE_REGSENT;
05581    r->regattempts++; /* Another attempt */
05582    if (option_debug > 3)
05583       ast_verbose("REGISTER attempt %d to %s@%s\n", r->regattempts, r->username, r->hostname);
05584    return send_request(p, &req, 2, p->ocseq);
05585 }

static int transmit_reinvite_with_sdp struct sip_pvt p  )  [static]
 

transmit_reinvite_with_sdp: Transmit reinvite with SDP :-) ---

Definition at line 4669 of file chan_sip.c.

References add_header(), add_sdp(), ALLOWED_METHODS, ast_rtp_offered_from_local(), ast_set_flag, ast_test_flag, ast_verbose(), copy_request(), sip_request::headers, sip_pvt::initreq, sip_pvt::lastinvite, sip_request::lines, sip_pvt::ocseq, parse_request(), reqprep(), sip_pvt::rtp, send_request(), sip_debug_test_pvt(), SIP_INVITE, SIP_OUTGOING, SIP_REINVITE_UPDATE, SIP_UPDATE, and sipdebug.

Referenced by check_pendings(), and sip_set_rtp_peer().

04670 {
04671    struct sip_request req;
04672    if (ast_test_flag(p, SIP_REINVITE_UPDATE))
04673       reqprep(&req, p, SIP_UPDATE, 0, 1);
04674    else 
04675       reqprep(&req, p, SIP_INVITE, 0, 1);
04676    
04677    add_header(&req, "Allow", ALLOWED_METHODS);
04678    if (sipdebug)
04679       add_header(&req, "X-asterisk-info", "SIP re-invite (RTP bridge)");
04680    ast_rtp_offered_from_local(p->rtp, 1);
04681    add_sdp(&req, p);
04682    /* Use this as the basis */
04683    copy_request(&p->initreq, &req);
04684    parse_request(&p->initreq);
04685    if (sip_debug_test_pvt(p))
04686       ast_verbose("%d headers, %d lines\n", p->initreq.headers, p->initreq.lines);
04687    p->lastinvite = p->ocseq;
04688    ast_set_flag(p, SIP_OUTGOING);
04689    return send_request(p, &req, 1, p->ocseq);
04690 }

static int transmit_request struct sip_pvt p,
int  sipmethod,
int  inc,
int  reliable,
int  newbranch
[static]
 

transmit_request: transmit generic SIP request ---

Definition at line 5660 of file chan_sip.c.

References add_blank_header(), add_header_contentLength(), sip_pvt::ocseq, reqprep(), and send_request().

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

05661 {
05662    struct sip_request resp;
05663    reqprep(&resp, p, sipmethod, seqno, newbranch);
05664    add_header_contentLength(&resp, 0);
05665    add_blank_header(&resp);
05666    return send_request(p, &resp, reliable, seqno ? seqno : p->ocseq);
05667 }

static int transmit_request_with_auth struct sip_pvt p,
int  sipmethod,
int  inc,
int  reliable,
int  newbranch
[static]
 

transmit_request_with_auth: Transmit SIP request, auth added ---

Definition at line 5670 of file chan_sip.c.

References add_blank_header(), add_header(), add_header_contentLength(), ast_cause2str(), ast_log(), sip_invite_param::auth_type, build_reply_digest(), sip_pvt::callid, ast_channel::hangupcause, LOG_WARNING, sip_pvt::ocseq, sip_pvt::options, sip_pvt::owner, PROXY_AUTH, sip_pvt::realm, reqprep(), send_request(), SIP_BYE, and WWW_AUTH.

Referenced by check_pendings(), handle_request_refer(), and sip_hangup().

05671 {
05672    struct sip_request resp;
05673 
05674    reqprep(&resp, p, sipmethod, seqno, newbranch);
05675    if (*p->realm) {
05676       char digest[1024];
05677 
05678       memset(digest, 0, sizeof(digest));
05679       if(!build_reply_digest(p, sipmethod, digest, sizeof(digest))) {
05680          if (p->options && p->options->auth_type == PROXY_AUTH)
05681             add_header(&resp, "Proxy-Authorization", digest);
05682          else if (p->options && p->options->auth_type == WWW_AUTH)
05683             add_header(&resp, "Authorization", digest);
05684          else  /* Default, to be backwards compatible (maybe being too careful, but leaving it for now) */
05685             add_header(&resp, "Proxy-Authorization", digest);
05686       } else
05687          ast_log(LOG_WARNING, "No authentication available for call %s\n", p->callid);
05688    }
05689    /* If we are hanging up and know a cause for that, send it in clear text to make
05690       debugging easier. */
05691    if (sipmethod == SIP_BYE) {
05692       if (p->owner && p->owner->hangupcause) {
05693          add_header(&resp, "X-Asterisk-HangupCause", ast_cause2str(p->owner->hangupcause));
05694       }
05695    }
05696 
05697    add_header_contentLength(&resp, 0);
05698    add_blank_header(&resp);
05699    return send_request(p, &resp, reliable, seqno ? seqno : p->ocseq);   
05700 }

static int transmit_response struct sip_pvt p,
char *  msg,
struct sip_request req
[static]
 

transmit_response: Transmit response, no retransmits

Definition at line 4229 of file chan_sip.c.

References __transmit_response().

04230 {
04231    return __transmit_response(p, msg, req, 0);
04232 }

static int transmit_response_reliable struct sip_pvt p,
char *  msg,
struct sip_request req,
int  fatal
[static]
 

transmit_response_reliable: Transmit response, Make sure you get a reply

Definition at line 4245 of file chan_sip.c.

References __transmit_response().

Referenced by handle_request(), handle_request_bye(), handle_request_cancel(), handle_request_invite(), handle_request_subscribe(), sip_hangup(), and sip_sipredirect().

04246 {
04247    return __transmit_response(p, msg, req, fatal ? 2 : 1);
04248 }

static int transmit_response_with_allow struct sip_pvt p,
char *  msg,
struct sip_request req,
int  reliable
[static]
 

transmit_response_with_allow: Append Accept header, content length before transmitting response ---

Definition at line 4275 of file chan_sip.c.

References add_blank_header(), add_header(), add_header_contentLength(), respprep(), and send_response().

Referenced by handle_request(), and handle_request_options().

04276 {
04277    struct sip_request resp;
04278    respprep(&resp, p, msg, req);
04279    add_header(&resp, "Accept", "application/sdp");
04280    add_header_contentLength(&resp, 0);
04281    add_blank_header(&resp);
04282    return send_response(p, &resp, reliable, 0);
04283 }

static int transmit_response_with_auth struct sip_pvt p,
char *  msg,
struct sip_request req,
char *  rand,
int  reliable,
char *  header,
int  stale
[static]
 

Definition at line 4286 of file chan_sip.c.

References add_blank_header(), add_header(), add_header_contentLength(), ast_log(), get_header(), global_realm, LOG_WARNING, respprep(), and send_response().

Referenced by check_auth(), and transmit_fake_auth_response().

04287 {
04288    struct sip_request resp;
04289    char tmp[512];
04290    int seqno = 0;
04291 
04292    if (reliable && (sscanf(get_header(req, "CSeq"), "%d ", &seqno) != 1)) {
04293       ast_log(LOG_WARNING, "Unable to determine sequence number from '%s'\n", get_header(req, "CSeq"));
04294       return -1;
04295    }
04296    /* Stale means that they sent us correct authentication, but 
04297       based it on an old challenge (nonce) */
04298    snprintf(tmp, sizeof(tmp), "Digest algorithm=MD5, realm=\"%s\", nonce=\"%s\"%s", global_realm, randdata, stale ? ", stale=true" : "");
04299    respprep(&resp, p, msg, req);
04300    add_header(&resp, header, tmp);
04301    add_header_contentLength(&resp, 0);
04302    add_blank_header(&resp);
04303    return send_response(p, &resp, reliable, seqno);
04304 }

static int transmit_response_with_date struct sip_pvt p,
char *  msg,
struct sip_request req
[static]
 

transmit_response_with_date: Append date and content length before transmitting response ---

Definition at line 4264 of file chan_sip.c.

References add_blank_header(), add_header_contentLength(), append_date(), respprep(), and send_response().

Referenced by register_verify().

04265 {
04266    struct sip_request resp;
04267    respprep(&resp, p, msg, req);
04268    append_date(&resp);
04269    add_header_contentLength(&resp, 0);
04270    add_blank_header(&resp);
04271    return send_response(p, &resp, 0, 0);
04272 }

static int transmit_response_with_sdp struct sip_pvt p,
char *  msg,
struct sip_request req,
int  retrans
[static]
 

transmit_response_with_sdp: Used for 200 OK and 183 early media ---

Definition at line 4595 of file chan_sip.c.

References add_sdp(), ast_log(), ast_rtp_offered_from_local(), sip_pvt::callid, get_header(), LOG_ERROR, LOG_WARNING, respprep(), sip_pvt::rtp, send_response(), and try_suggested_sip_codec().

Referenced by handle_request_invite(), sip_answer(), sip_indicate(), and sip_write().

04596 {
04597    struct sip_request resp;
04598    int seqno;
04599    if (sscanf(get_header(req, "CSeq"), "%d ", &seqno) != 1) {
04600       ast_log(LOG_WARNING, "Unable to get seqno from '%s'\n", get_header(req, "CSeq"));
04601       return -1;
04602    }
04603    respprep(&resp, p, msg, req);
04604    if (p->rtp) {
04605       ast_rtp_offered_from_local(p->rtp, 0);
04606       try_suggested_sip_codec(p);   
04607       add_sdp(&resp, p);
04608    } else {
04609       ast_log(LOG_ERROR, "Can't add SDP to response, since we have no RTP session allocated. Call-ID %s\n", p->callid);
04610    }
04611    return send_response(p, &resp, retrans, seqno);
04612 }

static int transmit_response_with_unsupported struct sip_pvt p,
char *  msg,
struct sip_request req,
char *  unsupported
[static]
 

transmit_response_with_unsupported: Transmit response, no retransmits

Definition at line 4235 of file chan_sip.c.

References add_header(), append_date(), respprep(), and send_response().

Referenced by handle_request_invite().

04236 {
04237    struct sip_request resp;
04238    respprep(&resp, p, msg, req);
04239    append_date(&resp);
04240    add_header(&resp, "Unsupported", unsupported);
04241    return send_response(p, &resp, 0, 0);
04242 }

static int transmit_sip_request struct sip_pvt p,
struct sip_request req
[static]
 

transmit_sip_request: Transmit SIP request

Definition at line 5247 of file chan_sip.c.

References ast_verbose(), copy_request(), determine_firstline_parts(), sip_request::headers, sip_pvt::initreq, sip_request::lines, sip_pvt::ocseq, parse_request(), send_request(), and sip_debug_test_pvt().

Referenced by sip_notify().

05248 {
05249    if (!p->initreq.headers) {
05250       /* Use this as the basis */
05251       copy_request(&p->initreq, req);
05252       parse_request(&p->initreq);
05253       if (sip_debug_test_pvt(p))
05254          ast_verbose("%d headers, %d lines\n", p->initreq.headers, p->initreq.lines);
05255       determine_firstline_parts(&p->initreq);
05256    }
05257 
05258    return send_request(p, req, 0, p->ocseq);
05259 }

static int transmit_state_notify struct sip_pvt p,
int  state,
int  full,
int  substate
[static]
 

transmit_state_notify: Used in the SUBSCRIBE notification subsystem ----

Definition at line 5041 of file chan_sip.c.

References add_header(), add_header_contentLength(), add_line(), ast_build_string(), ast_device_state(), AST_DEVICE_UNAVAILABLE, AST_EXTENSION_BUSY, AST_EXTENSION_DEACTIVATED, AST_EXTENSION_INUSE, AST_EXTENSION_NOT_INUSE, AST_EXTENSION_REMOVED, AST_EXTENSION_RINGING, AST_EXTENSION_UNAVAILABLE, ast_get_hint(), ast_log(), AST_MAX_EXTENSION, sip_pvt::context, CPIM_PIDF_XML, DIALOG_INFO_XML, sip_pvt::dialogver, cfsubscription_types::event, sip_pvt::expiry, sip_pvt::exten, find_subscription_type(), get_header(), get_in_brackets(), global_notifyringing, sip_pvt::initreq, LOG_WARNING, cfsubscription_types::mediatype, NONE, sip_pvt::ocseq, PIDF_XML, reqprep(), send_request(), SIP_NOTIFY, sip_pvt::subscribed, t, TIMEOUT, and XPIDF_XML.

Referenced by __sip_autodestruct(), cb_extensionstate(), and handle_request_subscribe().

05042 {
05043    char tmp[4000], from[256], to[256];
05044    char *t = tmp, *c, *a, *mfrom, *mto;
05045    size_t maxbytes = sizeof(tmp);
05046    struct sip_request req;
05047    char hint[AST_MAX_EXTENSION];
05048    char *statestring = "terminated";
05049    const struct cfsubscription_types *subscriptiontype;
05050    enum state { NOTIFY_OPEN, NOTIFY_INUSE, NOTIFY_CLOSED } local_state = NOTIFY_OPEN;
05051    char *pidfstate = "--";
05052    char *pidfnote= "Ready";
05053 
05054    memset(from, 0, sizeof(from));
05055    memset(to, 0, sizeof(to));
05056    memset(tmp, 0, sizeof(tmp));
05057 
05058    switch (state) {
05059    case (AST_EXTENSION_RINGING | AST_EXTENSION_INUSE):
05060       if (global_notifyringing)
05061          statestring = "early";
05062       else
05063          statestring = "confirmed";
05064       local_state = NOTIFY_INUSE;
05065       pidfstate = "busy";
05066       pidfnote = "Ringing";
05067       break;
05068    case AST_EXTENSION_RINGING:
05069       statestring = "early";
05070       local_state = NOTIFY_INUSE;
05071       pidfstate = "busy";
05072       pidfnote = "Ringing";
05073       break;
05074    case AST_EXTENSION_INUSE:
05075       statestring = "confirmed";
05076       local_state = NOTIFY_INUSE;
05077       pidfstate = "busy";
05078       pidfnote = "On the phone";
05079       break;
05080    case AST_EXTENSION_BUSY:
05081       statestring = "confirmed";
05082       local_state = NOTIFY_CLOSED;
05083       pidfstate = "busy";
05084       pidfnote = "On the phone";
05085       break;
05086    case AST_EXTENSION_UNAVAILABLE:
05087       statestring = "confirmed";
05088       local_state = NOTIFY_CLOSED;
05089       pidfstate = "away";
05090       pidfnote = "Unavailable";
05091       break;
05092    case AST_EXTENSION_NOT_INUSE:
05093    default:
05094       /* Default setting */
05095       break;
05096    }
05097 
05098    subscriptiontype = find_subscription_type(p->subscribed);
05099    
05100    /* Check which device/devices we are watching  and if they are registered */
05101    if (ast_get_hint(hint, sizeof(hint), NULL, 0, NULL, p->context, p->exten)) {
05102       /* If they are not registered, we will override notification and show no availability */
05103       if (ast_device_state(hint) == AST_DEVICE_UNAVAILABLE) {
05104          local_state = NOTIFY_CLOSED;
05105          pidfstate = "away";
05106          pidfnote = "Not online";
05107       }
05108    }
05109 
05110    ast_copy_string(from, get_header(&p->initreq, "From"), sizeof(from));
05111    c = get_in_brackets(from);
05112    if (strncmp(c, "sip:", 4)) {
05113       ast_log(LOG_WARNING, "Huh?  Not a SIP header (%s)?\n", c);
05114       return -1;
05115    }
05116    if ((a = strchr(c, ';')))
05117       *a = '\0';
05118    mfrom = c;
05119 
05120    ast_copy_string(to, get_header(&p->initreq, "To"), sizeof(to));
05121    c = get_in_brackets(to);
05122    if (strncmp(c, "sip:", 4)) {
05123       ast_log(LOG_WARNING, "Huh?  Not a SIP header (%s)?\n", c);
05124       return -1;
05125    }
05126    if ((a = strchr(c, ';')))
05127       *a = '\0';
05128    mto = c;
05129 
05130    reqprep(&req, p, SIP_NOTIFY, 0, 1);
05131 
05132    
05133    add_header(&req, "Event", subscriptiontype->event);
05134    add_header(&req, "Content-Type", subscriptiontype->mediatype);
05135    switch(state) {
05136    case AST_EXTENSION_DEACTIVATED:
05137       if (p->subscribed == TIMEOUT)
05138          add_header(&req, "Subscription-State", "terminated;reason=timeout");
05139       else {
05140          add_header(&req, "Subscription-State", "terminated;reason=probation");
05141          add_header(&req, "Retry-After", "60");
05142       }
05143       break;
05144    case AST_EXTENSION_REMOVED:
05145       add_header(&req, "Subscription-State", "terminated;reason=noresource");
05146       break;
05147       break;
05148    default:
05149       if (p->expiry)
05150          add_header(&req, "Subscription-State", "active");
05151       else  /* Expired */
05152          add_header(&req, "Subscription-State", "terminated;reason=timeout");
05153    }
05154    switch (p->subscribed) {
05155    case XPIDF_XML:
05156    case CPIM_PIDF_XML:
05157       ast_build_string(&t, &maxbytes, "<?xml version=\"1.0\"?>\n");
05158       ast_build_string(&t, &maxbytes, "<!DOCTYPE presence PUBLIC \"-//IETF//DTD RFCxxxx XPIDF 1.0//EN\" \"xpidf.dtd\">\n");
05159       ast_build_string(&t, &maxbytes, "<presence>\n");
05160       ast_build_string(&t, &maxbytes, "<presentity uri=\"%s;method=SUBSCRIBE\" />\n", mfrom);
05161       ast_build_string(&t, &maxbytes, "<atom id=\"%s\">\n", p->exten);
05162       ast_build_string(&t, &maxbytes, "<address uri=\"%s;user=ip\" priority=\"0.800000\">\n", mto);
05163       ast_build_string(&t, &maxbytes, "<status status=\"%s\" />\n", (local_state ==  NOTIFY_OPEN) ? "open" : (local_state == NOTIFY_INUSE) ? "inuse" : "closed");
05164       ast_build_string(&t, &maxbytes, "<msnsubstatus substatus=\"%s\" />\n", (local_state == NOTIFY_OPEN) ? "online" : (local_state == NOTIFY_INUSE) ? "onthephone" : "offline");
05165       ast_build_string(&t, &maxbytes, "</address>\n</atom>\n</presence>\n");
05166       break;
05167    case PIDF_XML: /* Eyebeam supports this format */
05168       ast_build_string(&t, &maxbytes, "<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>\n");
05169       ast_build_string(&t, &maxbytes, "<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);
05170       ast_build_string(&t, &maxbytes, "<pp:person><status>\n");
05171       if (pidfstate[0] != '-')
05172          ast_build_string(&t, &maxbytes, "<ep:activities><ep:%s/></ep:activities>\n", pidfstate);
05173       ast_build_string(&t, &maxbytes, "</status></pp:person>\n");
05174       ast_build_string(&t, &maxbytes, "<note>%s</note>\n", pidfnote); /* Note */
05175       ast_build_string(&t, &maxbytes, "<tuple id=\"%s\">\n", p->exten); /* Tuple start */
05176       ast_build_string(&t, &maxbytes, "<contact priority=\"1\">%s</contact>\n", mto);
05177       if (pidfstate[0] == 'b') /* Busy? Still open ... */
05178          ast_build_string(&t, &maxbytes, "<status><basic>open</basic></status>\n");
05179       else
05180          ast_build_string(&t, &maxbytes, "<status><basic>%s</basic></status>\n", (local_state != NOTIFY_CLOSED) ? "open" : "closed");
05181       ast_build_string(&t, &maxbytes, "</tuple>\n</presence>\n");
05182       break;
05183    case DIALOG_INFO_XML: /* SNOM subscribes in this format */
05184       ast_build_string(&t, &maxbytes, "<?xml version=\"1.0\"?>\n");
05185       ast_build_string(&t, &maxbytes, "<dialog-info xmlns=\"urn:ietf:params:xml:ns:dialog-info\" version=\"%d\" state=\"%s\" entity=\"%s\">\n", p->dialogver++, full ? "full":"partial", mto);
05186       if ((state & AST_EXTENSION_RINGING) && global_notifyringing)
05187          ast_build_string(&t, &maxbytes, "<dialog id=\"%s\" direction=\"recipient\">\n", p->exten);
05188       else
05189          ast_build_string(&t, &maxbytes, "<dialog id=\"%s\">\n", p->exten);
05190       ast_build_string(&t, &maxbytes, "<state>%s</state>\n", statestring);
05191       ast_build_string(&t, &maxbytes, "</dialog>\n</dialog-info>\n");
05192       break;
05193    case NONE:
05194    default:
05195       break;
05196    }
05197 
05198    if (t > tmp + sizeof(tmp))
05199       ast_log(LOG_WARNING, "Buffer overflow detected!!  (Please file a bug report)\n");
05200 
05201    add_header_contentLength(&req, strlen(tmp));
05202    add_line(&req, tmp);
05203 
05204    return send_request(p, &req, 1, p->ocseq);
05205 }

static void try_suggested_sip_codec struct sip_pvt p  )  [static]
 

Try setting codec suggested by the SIP_CODEC channel variable.

Definition at line 2499 of file chan_sip.c.

References ast_getformatbyname(), ast_log(), sip_pvt::capability, fmt, sip_pvt::jointcapability, LOG_NOTICE, sip_pvt::owner, and pbx_builtin_getvar_helper().

Referenced by sip_answer(), and transmit_response_with_sdp().

02500 {
02501    int fmt;
02502    char *codec;
02503 
02504    codec = pbx_builtin_getvar_helper(p->owner, "SIP_CODEC");
02505    if (!codec) 
02506       return;
02507 
02508    fmt = ast_getformatbyname(codec);
02509    if (fmt) {
02510       ast_log(LOG_NOTICE, "Changing codec to '%s' for this call because of ${SIP_CODEC) variable\n",codec);
02511       if (p->jointcapability & fmt) {
02512          p->jointcapability &= fmt;
02513          p->capability &= fmt;
02514       } else
02515          ast_log(LOG_NOTICE, "Ignoring ${SIP_CODEC} variable because it is not shared by both ends.\n");
02516    } else
02517       ast_log(LOG_NOTICE, "Ignoring ${SIP_CODEC} variable because of unrecognized/not configured codec (check allow/disallow in sip.conf): %s\n",codec);
02518    return;  
02519 }

int unload_module void   ) 
 

Cleanup all module structures, sockets, etc.

This is called at exit. Any registrations and memory allocations need to be unregistered and free'd here. Nothing else will do these for you (until exit).

Returns:
Zero on success, or non-zero on error.

Definition at line 13374 of file chan_sip.c.

References app_dtmfmode, app_sipaddheader, app_sipgetheader, ast_channel_unregister(), ast_cli_unregister_multiple(), ast_custom_function_unregister(), ast_free_ha(), ast_log(), ast_manager_unregister(), ast_mutex_destroy(), ast_mutex_lock(), ast_mutex_unlock(), AST_PTHREADT_STOP, ast_rtp_proto_unregister(), ast_softhangup(), AST_SOFTHANGUP_APPUNLOAD, ast_unregister_application(), ast_variables_destroy(), ASTOBJ_CONTAINER_DESTROY, ASTOBJ_CONTAINER_DESTROYALL, authl, sip_pvt::chanvars, checksipdomain_function, clear_realm_authentication(), clear_sip_domains(), free, iflist, localaddr, sip_pvt::lock, LOG_WARNING, monitor_thread, sip_pvt::next, peerl, regl, sched_context_destroy(), sip_destroy_peer(), sip_destroy_user(), sip_header_function, sip_registry_destroy(), sip_rtp, sip_tech, sipchaninfo_function, sippeer_function, sipsock, and userl.

13375 {
13376    struct sip_pvt *p, *pl;
13377    
13378    /* First, take us out of the channel type list */
13379    ast_channel_unregister(&sip_tech);
13380 
13381    ast_custom_function_unregister(&sipchaninfo_function);
13382    ast_custom_function_unregister(&sippeer_function);
13383    ast_custom_function_unregister(&sip_header_function);
13384    ast_custom_function_unregister(&checksipdomain_function);
13385 
13386    ast_unregister_application(app_dtmfmode);
13387    ast_unregister_application(app_sipaddheader);
13388    ast_unregister_application(app_sipgetheader);
13389 
13390    ast_cli_unregister_multiple(my_clis, sizeof(my_clis) / sizeof(my_clis[0]));
13391 
13392    ast_rtp_proto_unregister(&sip_rtp);
13393 
13394    ast_manager_unregister("SIPpeers");
13395    ast_manager_unregister("SIPshowpeer");
13396 
13397    if (!ast_mutex_lock(&iflock)) {
13398       /* Hangup all interfaces if they have an owner */
13399       p = iflist;
13400       while (p) {
13401          if (p->owner)
13402             ast_softhangup(p->owner, AST_SOFTHANGUP_APPUNLOAD);
13403          p = p->next;
13404       }
13405       ast_mutex_unlock(&iflock);
13406    } else {
13407       ast_log(LOG_WARNING, "Unable to lock the interface list\n");
13408       return -1;
13409    }
13410 
13411    if (!ast_mutex_lock(&monlock)) {
13412       if (monitor_thread && (monitor_thread != AST_PTHREADT_STOP)) {
13413          pthread_cancel(monitor_thread);
13414          pthread_kill(monitor_thread, SIGURG);
13415          pthread_join(monitor_thread, NULL);
13416       }
13417       monitor_thread = AST_PTHREADT_STOP;
13418       ast_mutex_unlock(&monlock);
13419    } else {
13420       ast_log(LOG_WARNING, "Unable to lock the monitor\n");
13421       return -1;
13422    }
13423 
13424    if (!ast_mutex_lock(&iflock)) {
13425       /* Destroy all the interfaces and free their memory */
13426       p = iflist;
13427       while (p) {
13428          pl = p;
13429          p = p->next;
13430          /* Free associated memory */
13431          ast_mutex_destroy(&pl->lock);
13432          if (pl->chanvars) {
13433             ast_variables_destroy(pl->chanvars);
13434             pl->chanvars = NULL;
13435          }
13436          free(pl);
13437       }
13438       iflist = NULL;
13439       ast_mutex_unlock(&iflock);
13440    } else {
13441       ast_log(LOG_WARNING, "Unable to lock the interface list\n");
13442       return -1;
13443    }
13444 
13445    /* Free memory for local network address mask */
13446    ast_free_ha(localaddr);
13447 
13448    ASTOBJ_CONTAINER_DESTROYALL(&userl, sip_destroy_user);
13449    ASTOBJ_CONTAINER_DESTROY(&userl);
13450    ASTOBJ_CONTAINER_DESTROYALL(&peerl, sip_destroy_peer);
13451    ASTOBJ_CONTAINER_DESTROY(&peerl);
13452    ASTOBJ_CONTAINER_DESTROYALL(&regl, sip_registry_destroy);
13453    ASTOBJ_CONTAINER_DESTROY(&regl);
13454 
13455    clear_realm_authentication(authl);
13456    clear_sip_domains();
13457    close(sipsock);
13458    sched_context_destroy(sched);
13459       
13460    return 0;
13461 }

static int update_call_counter struct sip_pvt fup,
int  event
[static]
 

update_call_counter: Handle call_limit for SIP users Note: This is going to be replaced by app_groupcount Thought: For realtime, we should propably update storage with inuse counter...

Definition at line 2197 of file chan_sip.c.

References ast_log(), ast_set_flag, ast_test_flag, ASTOBJ_UNREF, sip_peer::call_limit, sip_user::call_limit, DEC_CALL_LIMIT, find_peer(), find_user(), INC_CALL_LIMIT, sip_peer::inUse, sip_user::inUse, inuse, LOG_DEBUG, LOG_ERROR, name, option_debug, sip_pvt::peername, SIP_CALL_LIMIT, sip_destroy_peer(), sip_destroy_user(), SIP_INC_COUNT, SIP_OUTGOING, sipdebug, and sip_pvt::username.

Referenced by handle_request_invite(), handle_response(), sip_call(), and sip_hangup().

02198 {
02199    char name[256];
02200    int *inuse, *call_limit;
02201    int outgoing = ast_test_flag(fup, SIP_OUTGOING);
02202    struct sip_user *u = NULL;
02203    struct sip_peer *p = NULL;
02204 
02205    if (option_debug > 2)
02206       ast_log(LOG_DEBUG, "Updating call counter for %s call\n", outgoing ? "outgoing" : "incoming");
02207    /* Test if we need to check call limits, in order to avoid 
02208       realtime lookups if we do not need it */
02209    if (!ast_test_flag(fup, SIP_CALL_LIMIT))
02210       return 0;
02211 
02212    ast_copy_string(name, fup->username, sizeof(name));
02213 
02214    /* Check the list of users */
02215    u = find_user(name, 1);
02216    if (u) {
02217       inuse = &u->inUse;
02218       call_limit = &u->call_limit;
02219       p = NULL;
02220    } else {
02221       /* Try to find peer */
02222       if (!p)
02223          p = find_peer(fup->peername, NULL, 1);
02224       if (p) {
02225          inuse = &p->inUse;
02226          call_limit = &p->call_limit;
02227          ast_copy_string(name, fup->peername, sizeof(name));
02228       } else {
02229          if (option_debug > 1)
02230             ast_log(LOG_DEBUG, "%s is not a local user, no call limit\n", name);
02231          return 0;
02232       }
02233    }
02234    switch(event) {
02235       /* incoming and outgoing affects the inUse counter */
02236       case DEC_CALL_LIMIT:
02237          if ( *inuse > 0 ) {
02238                   if (ast_test_flag(fup,SIP_INC_COUNT))
02239                      (*inuse)--;
02240          } else {
02241             *inuse = 0;
02242          }
02243          if (option_debug > 1 || sipdebug) {
02244             ast_log(LOG_DEBUG, "Call %s %s '%s' removed from call limit %d\n", outgoing ? "to" : "from", u ? "user":"peer", name, *call_limit);
02245          }
02246          break;
02247       case INC_CALL_LIMIT:
02248          if (*call_limit > 0 ) {
02249             if (*inuse >= *call_limit) {
02250                ast_log(LOG_ERROR, "Call %s %s '%s' rejected due to usage limit of %d\n", outgoing ? "to" : "from", u ? "user":"peer", name, *call_limit);
02251                if (u)
02252                   ASTOBJ_UNREF(u,sip_destroy_user);
02253                else
02254                   ASTOBJ_UNREF(p,sip_destroy_peer);
02255                return -1; 
02256             }
02257          }
02258          (*inuse)++;
02259                    ast_set_flag(fup,SIP_INC_COUNT);
02260          if (option_debug > 1 || sipdebug) {
02261             ast_log(LOG_DEBUG, "Call %s %s '%s' is %d out of %d\n", outgoing ? "to" : "from", u ? "user":"peer", name, *inuse, *call_limit);
02262          }
02263          break;
02264       default:
02265          ast_log(LOG_ERROR, "update_call_counter(%s, %d) called with no event!\n", name, event);
02266    }
02267    if (u)
02268       ASTOBJ_UNREF(u,sip_destroy_user);
02269    else
02270       ASTOBJ_UNREF(p,sip_destroy_peer);
02271    return 0;
02272 }

static void update_peer struct sip_peer p,
int  expiry
[static]
 

update_peer: Update peer data in database (if used) ---

Definition at line 1665 of file chan_sip.c.

References sip_peer::addr, ast_test_flag, sip_peer::flags_page2, sip_peer::fullcontact, realtime_update_peer(), SIP_PAGE2_RTCACHEFRIENDS, SIP_PAGE2_RTUPDATE, SIP_REALTIME, and sip_peer::username.

Referenced by register_verify().

01666 {
01667    int rtcachefriends = ast_test_flag(&(p->flags_page2), SIP_PAGE2_RTCACHEFRIENDS);
01668    if (ast_test_flag((&global_flags_page2), SIP_PAGE2_RTUPDATE) &&
01669       (ast_test_flag(p, SIP_REALTIME) || rtcachefriends)) {
01670       realtime_update_peer(p->name, &p->addr, p->username, rtcachefriends ? p->fullcontact : NULL, expiry);
01671    }
01672 }

int usecount void   ) 
 

Provides a usecount.

This function will be called by various parts of asterisk. Basically, all it has to do is to return a usecount when called. You will need to maintain your usecount within the module somewhere. The usecount should be how many channels provided by this module are in use.

Returns:
The module's usecount.

Definition at line 13463 of file chan_sip.c.

References usecnt.

13464 {
13465    return usecnt;
13466 }


Variable Documentation

struct in_addr __ourip [static]
 

Definition at line 413 of file chan_sip.c.

const struct cfalias aliases[] [static]
 

Structure for conversion between compressed SIP and "normal" SIP.

int allow_external_domains
 

Accept calls to external SIP domains?

Definition at line 501 of file chan_sip.c.

Referenced by get_destination(), reload_config(), and sip_show_settings().

int apeerobjs = 0 [static]
 

Definition at line 381 of file chan_sip.c.

Referenced by sip_destroy_peer(), sip_show_objects(), and temp_peer().

char* app_dtmfmode = "SIPDtmfMode" [static]
 

Definition at line 12940 of file chan_sip.c.

Referenced by load_module(), and unload_module().

char* app_sipaddheader = "SIPAddHeader" [static]
 

Definition at line 12942 of file chan_sip.c.

Referenced by load_module(), and unload_module().

char* app_sipgetheader = "SIPGetHeader" [static]
 

Definition at line 12954 of file chan_sip.c.

Referenced by load_module(), and unload_module().

struct sip_auth* authl [static]
 

Authentication list

Definition at line 884 of file chan_sip.c.

Referenced by build_reply_digest(), reload_config(), sip_do_reload(), sip_show_settings(), and unload_module().

int autocreatepeer = 0 [static]
 

Auto creation of peers at registration? Default off.

Definition at line 363 of file chan_sip.c.

Referenced by register_verify(), reload_config(), and sip_show_settings().

struct sockaddr_in bindaddr = { 0, } [static]
 

Definition at line 874 of file chan_sip.c.

int callevents = 0 [static]
 

Definition at line 909 of file chan_sip.c.

Referenced by process_sdp(), reload_config(), and sip_show_settings().

const char channeltype[] = "SIP" [static]
 

Definition at line 145 of file chan_sip.c.

struct ast_custom_function checksipdomain_function [static]
 

Definition at line 9331 of file chan_sip.c.

Referenced by load_module(), and unload_module().

int compactheaders = 0 [static]
 

send compact sip headers

Definition at line 426 of file chan_sip.c.

Referenced by add_header(), reload_config(), and sip_show_settings().

const char config[] = "sip.conf" [static]
 

Definition at line 146 of file chan_sip.c.

char debug_usage[] [static]
 

Definition at line 9230 of file chan_sip.c.

struct sockaddr_in debugaddr [static]
 

Definition at line 420 of file chan_sip.c.

Referenced by sip_debug_test_addr(), sip_do_debug(), sip_do_debug_ip(), and sip_do_debug_peer().

char default_callerid[AST_MAX_EXTENSION] = DEFAULT_CALLERID [static]
 

Definition at line 343 of file chan_sip.c.

Referenced by build_rpid(), initreqprep(), reload_config(), and sip_show_settings().

char default_context[AST_MAX_CONTEXT] = DEFAULT_CONTEXT [static]
 

Definition at line 334 of file chan_sip.c.

int default_expiry = DEFAULT_DEFAULT_EXPIRY [static]
 

Definition at line 121 of file chan_sip.c.

Referenced by handle_response_register(), parse_register_contact(), reload_config(), sip_register(), sip_send_all_registers(), sip_show_settings(), and transmit_register().

char default_fromdomain[AST_MAX_EXTENSION] = "" [static]
 

Definition at line 345 of file chan_sip.c.

Referenced by reload_config(), sip_alloc(), sip_show_settings(), and transmit_register().

char default_language[MAX_LANGUAGE] = "" [static]
 

Definition at line 340 of file chan_sip.c.

Referenced by build_peer(), build_user(), reload_config(), sip_show_settings(), and temp_peer().

char default_notifymime[AST_MAX_EXTENSION] = DEFAULT_NOTIFYMIME [static]
 

Definition at line 348 of file chan_sip.c.

Referenced by reload_config(), sip_show_settings(), and transmit_notify_with_mwi().

int default_qualify = 0 [static]
 

Default Qualify= setting

Definition at line 354 of file chan_sip.c.

Referenced by build_peer(), reload_config(), and sip_show_settings().

char default_subscribecontext[AST_MAX_CONTEXT] [static]
 

Definition at line 335 of file chan_sip.c.

Referenced by build_peer(), reload_config(), and temp_peer().

char default_useragent[AST_MAX_EXTENSION] = DEFAULT_USERAGENT [static]
 

Definition at line 331 of file chan_sip.c.

Referenced by initreqprep(), reload_config(), reqprep(), respprep(), sip_show_settings(), and transmit_register().

const char desc[] = "Session Initiation Protocol (SIP)" [static]
 

Definition at line 144 of file chan_sip.c.

char* descrip_dtmfmode = "SIPDtmfMode(inband|info|rfc2833): Changes the dtmfmode for a SIP call\n" [static]
 

Definition at line 12939 of file chan_sip.c.

Referenced by load_module().

char* descrip_sipaddheader [static]
 

Definition at line 12946 of file chan_sip.c.

Referenced by load_module().

char* descrip_sipgetheader [static]
 

Definition at line 12957 of file chan_sip.c.

Referenced by load_module().

int dumphistory = 0 [static]
 

Dump history to verbose before destroying SIP dialog

Definition at line 429 of file chan_sip.c.

Referenced by __sip_destroy(), and reload_config().

int expiry = DEFAULT_EXPIRY [static]
 

Definition at line 437 of file chan_sip.c.

Referenced by complete_dpreply(), parse_register_contact(), reg_source_db(), register_verify(), and reload_config().

time_t externexpire = 0 [static]
 

Definition at line 877 of file chan_sip.c.

Referenced by ast_sip_ouraddrfor(), and reload_config().

char externhost[MAXHOSTNAMELEN] = "" [static]
 

Definition at line 876 of file chan_sip.c.

Referenced by ast_sip_ouraddrfor(), and reload_config().

struct sockaddr_in externip [static]
 

Definition at line 875 of file chan_sip.c.

Referenced by reload_config().

int externrefresh = 10 [static]
 

Definition at line 878 of file chan_sip.c.

Referenced by ast_sip_ouraddrfor(), and reload_config().

int global_allowguest = 1 [static]
 

allow unauthenticated users/peers to connect?

Definition at line 384 of file chan_sip.c.

Referenced by check_auth(), check_user_full(), handle_common_options(), reload_config(), and sip_show_settings().

int global_alwaysauthreject = 0 [static]
 

Send 401 Unauthorized for all failing requests

Definition at line 352 of file chan_sip.c.

Referenced by check_user_full(), register_verify(), reload_config(), and sip_show_settings().

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 410 of file chan_sip.c.

Referenced by build_peer(), build_user(), reload_config(), sip_alloc(), sip_new(), sip_request_call(), and temp_peer().

struct ast_flags global_flags = {0} [static]
 

global SIP_ flags

Definition at line 356 of file chan_sip.c.

struct ast_flags global_flags_page2 = {0} [static]
 

more global SIP_ flags

Definition at line 357 of file chan_sip.c.

char global_musicclass[MAX_MUSICCLASS] = "" [static]
 

Global music on hold class

Definition at line 431 of file chan_sip.c.

Referenced by build_peer(), build_user(), reload_config(), sip_alloc(), sip_show_settings(), and temp_peer().

int global_mwitime = DEFAULT_MWITIME [static]
 

Time between MWI checks for peers

Definition at line 387 of file chan_sip.c.

Referenced by do_monitor(), reload_config(), and sip_show_settings().

int global_notifyringing = 1 [static]
 

Send notifications on ringing

Definition at line 350 of file chan_sip.c.

Referenced by reload_config(), sip_show_settings(), and transmit_state_notify().

char global_realm[MAXHOSTNAMELEN] = DEFAULT_REALM [static]
 

Default realm

Definition at line 433 of file chan_sip.c.

Referenced by check_auth(), reload_config(), sip_show_settings(), and transmit_response_with_auth().

int global_reg_timeout = DEFAULT_REGISTRATION_TIMEOUT [static]
 

Definition at line 373 of file chan_sip.c.

Referenced by reload_config(), sip_show_settings(), and transmit_register().

int global_regattempts_max = 0 [static]
 

Definition at line 374 of file chan_sip.c.

Referenced by handle_response_register(), reload_config(), sip_reg_timeout(), and sip_show_settings().

int global_rtautoclear [static]
 

Definition at line 589 of file chan_sip.c.

int global_rtpholdtimeout = 0 [static]
 

Definition at line 369 of file chan_sip.c.

Referenced by build_peer(), reload_config(), sip_alloc(), sip_show_settings(), and temp_peer().

int global_rtpkeepalive = 0 [static]
 

Definition at line 371 of file chan_sip.c.

Referenced by build_peer(), reload_config(), sip_alloc(), and temp_peer().

int global_rtptimeout = 0 [static]
 

Definition at line 367 of file chan_sip.c.

Referenced by build_peer(), reload_config(), sip_alloc(), sip_show_settings(), and temp_peer().

char global_vmexten[AST_MAX_EXTENSION] = DEFAULT_VMEXTEN [static]
 

Definition at line 338 of file chan_sip.c.

Referenced by build_peer(), reload_config(), sip_show_settings(), and transmit_notify_with_mwi().

char history_usage[] [static]
 

Initial value:

 
"Usage: sip history\n"
"       Enables recording of SIP dialog history for debugging purposes.\n"
"Use 'sip show history' to view the history of a call number.\n"

Definition at line 9247 of file chan_sip.c.

struct sip_pvt * iflist [static]
 

sip_pvt: PVT structures are used for each SIP conversation, ie. a call

struct io_context* io [static]
 

Definition at line 440 of file chan_sip.c.

struct ast_ha* localaddr [static]
 

Definition at line 879 of file chan_sip.c.

Referenced by ast_sip_ouraddrfor(), reload_config(), and unload_module().

char mandescr_show_peer[] [static]
 

Definition at line 7954 of file chan_sip.c.

Referenced by load_module().

char mandescr_show_peers[] [static]
 

Initial value:

 
"Description: Lists SIP peers in text format with details on current status.\n"
"Variables: \n"
"  ActionID: <id> Action ID for this transaction. Will be returned.\n"

Definition at line 7536 of file chan_sip.c.

Referenced by load_module().

int max_expiry = DEFAULT_MAX_EXPIRY [static]
 

Definition at line 120 of file chan_sip.c.

Referenced by handle_request_subscribe(), parse_register_contact(), reload_config(), and sip_show_settings().

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 405 of file chan_sip.c.

struct ast_cli_entry my_clis[] [static]
 

Definition at line 13285 of file chan_sip.c.

char no_debug_usage[] [static]
 

Initial value:

 
"Usage: sip no debug\n"
"       Disables dumping of SIP packets for debugging purposes\n"

Definition at line 9239 of file chan_sip.c.

char no_history_usage[] [static]
 

Initial value:

 
"Usage: sip no history\n"
"       Disables recording of SIP dialog history for debugging purposes\n"

Definition at line 9243 of file chan_sip.c.

int noncodeccapability = AST_RTP_DTMF [static]
 

Definition at line 411 of file chan_sip.c.

Referenced by process_sdp().

const char notify_config[] = "sip_notify.conf" [static]
 

Definition at line 147 of file chan_sip.c.

Referenced by reload_config(), and sip_notify().

struct ast_config* notify_types
 

Definition at line 882 of file chan_sip.c.

Referenced by complete_sipnotify(), reload_config(), and sip_notify().

char notify_usage[] [static]
 

Initial value:

"Usage: sip notify <type> <peer> [<peer>...]\n"
"       Send a NOTIFY message to a SIP peer or peers\n"
"       Message types are defined in sip_notify.conf\n"

Definition at line 9179 of file chan_sip.c.

int ourport [static]
 

Definition at line 415 of file chan_sip.c.

struct sockaddr_in outboundproxyip [static]
 

Definition at line 414 of file chan_sip.c.

Referenced by reload_config().

int pedanticsipchecking = 0 [static]
 

Extra checking ? Default off

Definition at line 361 of file chan_sip.c.

Referenced by __get_header(), check_user_full(), find_call(), get_destination(), get_refer_info(), handle_request(), initreqprep(), process_sdp(), register_verify(), reload_config(), sip_show_settings(), and sipsock_read().

struct ast_peer_list peerl [static]
 

The peer list: Peers and Friends ---.

struct ast_codec_pref prefs [static]
 

Definition at line 448 of file chan_sip.c.

char prune_realtime_usage[] [static]
 

Initial value:

"Usage: sip prune realtime [peer|user] [<name>|all|like <pattern>]\n"
"       Prunes object(s) from the cache.\n"
"       Optional regular expression pattern is used to filter the objects.\n"

Definition at line 9221 of file chan_sip.c.

int recordhistory = 0 [static]
 

Record SIP history. Off by default

Definition at line 428 of file chan_sip.c.

Referenced by append_history(), do_register_auth(), reload_config(), send_request(), send_response(), sip_do_history(), sip_no_history(), sip_reregister(), sip_scheddestroy(), sip_show_history(), sip_show_settings(), sipsock_read(), and transmit_register().

char regcontext[AST_MAX_CONTEXT] = "" [static]
 

Context for auto-extensions

Definition at line 434 of file chan_sip.c.

struct ast_register_list regl [static]
 

The register list: Other SIP proxys we register with and call ---.

Referenced by delete_users(), load_module(), sip_do_reload(), sip_register(), sip_send_all_registers(), sip_show_objects(), sip_show_registry(), and unload_module().

int regobjs = 0 [static]
 

Definition at line 382 of file chan_sip.c.

Referenced by sip_register(), sip_registry_destroy(), sip_send_all_registers(), and sip_show_objects().

int relaxdtmf = 0 [static]
 

Definition at line 365 of file chan_sip.c.

Referenced by mkintf(), reload_config(), setup_zap(), sip_new(), and sip_show_settings().

int rpeerobjs = 0 [static]
 

Definition at line 380 of file chan_sip.c.

Referenced by build_peer(), sip_destroy_peer(), and sip_show_objects().

int ruserobjs = 0 [static]
 

Definition at line 378 of file chan_sip.c.

Referenced by realtime_user(), sip_destroy_user(), and sip_show_objects().

struct sched_context* sched [static]
 

Definition at line 439 of file chan_sip.c.

char show_channel_usage[] [static]
 

Initial value:

 
"Usage: sip show channel <channel>\n"
"       Provides detailed status on a given SIP channel.\n"

Definition at line 9203 of file chan_sip.c.

char show_channels_usage[] [static]
 

Initial value:

 
"Usage: sip show channels\n"
"       Lists all currently active SIP channels.\n"

Definition at line 9199 of file chan_sip.c.

char show_domains_usage[] [static]
 

Initial value:

 
"Usage: sip show domains\n"
"       Lists all configured SIP local domains.\n"
"       Asterisk only responds to SIP messages to local domains.\n"

Definition at line 9174 of file chan_sip.c.

char show_history_usage[] [static]
 

Initial value:

 
"Usage: sip show history <channel>\n"
"       Provides detailed dialog history on a given SIP channel.\n"

Definition at line 9207 of file chan_sip.c.

char show_inuse_usage[] [static]
 

Initial value:

 
"Usage: sip show inuse [all]\n"
"       List all SIP users and peers usage counters and limits.\n"
"       Add option \"all\" to show all devices, not only those with a limit.\n"

Definition at line 9194 of file chan_sip.c.

char show_objects_usage[] [static]
 

Initial value:

"Usage: sip show objects\n" 
"       Shows status of known SIP objects\n"

Definition at line 9260 of file chan_sip.c.

char show_peer_usage[] [static]
 

Initial value:

"Usage: sip show peer <name> [load]\n"
"       Lists all details on one SIP peer and the current status.\n"
"       Option \"load\" forces lookup of peer in realtime storage.\n"

Definition at line 9216 of file chan_sip.c.

char show_peers_usage[] [static]
 

Initial value:

 
"Usage: sip show peers [like <pattern>]\n"
"       Lists all known SIP peers.\n"
"       Optional regular expression pattern is used to filter the peer list.\n"

Definition at line 9211 of file chan_sip.c.

char show_reg_usage[] [static]
 

Initial value:

"Usage: sip show registry\n"
"       Lists all registration requests and status.\n"

Definition at line 9226 of file chan_sip.c.

char show_settings_usage[] [static]
 

Initial value:

 
"Usage: sip show settings\n"
"       Provides detailed list of the configuration of the SIP channel.\n"

Definition at line 9264 of file chan_sip.c.

char show_subscriptions_usage[] [static]
 

Initial value:

"Usage: sip show subscriptions\n" 
"       Shows active SIP subscriptions for extension states\n"

Definition at line 9256 of file chan_sip.c.

char show_user_usage[] [static]
 

Initial value:

"Usage: sip show user <name> [load]\n"
"       Lists all details on one SIP user and the current status.\n"
"       Option \"load\" forces lookup of peer in realtime storage.\n"

Definition at line 9189 of file chan_sip.c.

char show_users_usage[] [static]
 

Initial value:

 
"Usage: sip show users [like <pattern>]\n"
"       Lists all known SIP users.\n"
"       Optional regular expression pattern is used to filter the user list.\n"

Definition at line 9184 of file chan_sip.c.

struct ast_custom_function sip_header_function [static]
 

Definition at line 9310 of file chan_sip.c.

Referenced by load_module(), and unload_module().

enum sipmethod sip_method_list
 

const struct cfsip_methods sip_methods[] [static]
 

XXX Note that sip_methods[i].id == i must hold or the code breaks

Referenced by __sip_ack(), __sip_pretend_ack(), __sip_semi_ack(), build_reply_digest(), check_auth(), do_proxy_auth(), find_call(), find_sip_method(), get_destination(), handle_request(), handle_request_subscribe(), handle_response(), init_req(), initreqprep(), reqprep(), retrans_pkt(), sip_alloc(), and transmit_register().

const 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().

char sip_reload_usage[] [static]
 

Initial value:

"Usage: sip reload\n"
"       Reloads SIP configuration from sip.conf\n"

Definition at line 9252 of file chan_sip.c.

int sip_reloading = 0 [static]
 

Definition at line 806 of file chan_sip.c.

Referenced by do_monitor(), and sip_reload().

struct ast_rtp_protocol sip_rtp [static]
 

sip_rtp: Interface structure with callbacks used to connect to rtp module --

Definition at line 13190 of file chan_sip.c.

Referenced by load_module(), and unload_module().

const struct ast_channel_tech sip_tech [static]
 

Definition of this channel for PBX channel registration.

Definition at line 935 of file chan_sip.c.

Referenced by load_module(), and unload_module().

struct ast_custom_function sipchaninfo_function [static]
 

Definition at line 9495 of file chan_sip.c.

Referenced by load_module(), and unload_module().

int sipdebug = 0 [static]
 

Definition at line 419 of file chan_sip.c.

Referenced by __sip_ack(), __sip_reliable_xmit(), __sip_semi_ack(), add_sip_domain(), build_reply_digest(), check_auth(), handle_request_info(), handle_request_invite(), handle_request_subscribe(), handle_response_register(), parse_request(), parse_sip_options(), reload_config(), retrans_pkt(), sip_addheader(), sip_debug_test_addr(), sip_debug_test_pvt(), sip_do_debug(), sip_do_debug_ip(), sip_do_debug_peer(), sip_indicate(), sip_no_debug(), sip_poke_peer(), sip_reregister(), transmit_invite(), transmit_register(), transmit_reinvite_with_sdp(), and update_call_counter().

struct ast_custom_function sippeer_function
 

Definition at line 9418 of file chan_sip.c.

Referenced by load_module(), and unload_module().

int sipsock = -1 [static]
 

Definition at line 871 of file chan_sip.c.

Referenced by __sip_xmit(), do_monitor(), reg_source_db(), reload_config(), sipsock_read(), and unload_module().

int speerobjs = 0 [static]
 

Definition at line 379 of file chan_sip.c.

Referenced by build_peer(), sip_destroy_peer(), and sip_show_objects().

int srvlookup = 0 [static]
 

SRV Lookup on or off. Default is off, RFC behavior is on

Definition at line 359 of file chan_sip.c.

Referenced by create_addr(), reload_config(), and sip_show_settings().

const struct cfsubscription_types subscription_types[] [static]
 

Referenced by find_subscription_type(), and subscription_type2str().

int suserobjs = 0 [static]
 

Definition at line 377 of file chan_sip.c.

Referenced by build_user(), realtime_user(), sip_destroy_user(), and sip_show_objects().

char* synopsis_dtmfmode = "Change the dtmfmode for a SIP call" [static]
 

Definition at line 12938 of file chan_sip.c.

Referenced by load_module().

char* synopsis_sipaddheader = "Add a SIP header to the outbound call" [static]
 

Definition at line 12943 of file chan_sip.c.

Referenced by load_module().

char* synopsis_sipgetheader = "Get a SIP header from an incoming call" [static]
 

Definition at line 12955 of file chan_sip.c.

Referenced by load_module().

int tos = 0 [static]
 

Definition at line 422 of file chan_sip.c.

int usecnt = 0 [static]
 

Definition at line 389 of file chan_sip.c.

struct ast_user_list userl [static]
 

The user list: Users and friends ---.

int videosupport = 0 [static]
 

Definition at line 424 of file chan_sip.c.

Referenced by reload_config(), sip_alloc(), and sip_show_settings().


Generated on Sun Aug 6 15:06:31 2006 for Asterisk - the Open Source PBX by  doxygen 1.4.2