Sat Nov 25 00:45:55 2006

Asterisk developer's documentation


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"

Go to the source code of this file.

Data Structures

struct  ast_peer_list
 The peer list: Peers and Friends ---. More...
struct  ast_register_list
 The register list: Other SIP proxys we register with and call ---. More...
struct  ast_user_list
 The user list: Users and friends ---. More...
struct  cfalias
 Structure for conversion between compressed SIP and "normal" SIP. More...
struct  cfsip_methods
struct  cfsip_options
 List of well-known SIP options. If we get this in a require, we should check the list and answer accordingly. More...
struct  cfsubscription_types
struct  domain
struct  sip_auth
 sip_auth: Creadentials for authentication to other SIP services More...
struct  sip_dual
struct  sip_history
 sip_history: Structure for saving transactions within a SIP dialog More...
struct  sip_invite_param
 Parameters to the transmit_invite function. More...
struct  sip_peer
struct  sip_pkt
 sip packet - read in sipsock_read, transmitted in send_request More...
struct  sip_pvt
 sip_pvt: PVT structures are used for each SIP conversation, ie. a call More...
struct  sip_registry
 sip_registry: Registrations with other SIP proxies More...
struct  sip_request
 sip_request: The data grabbed from the UDP socket More...
struct  sip_route
struct  sip_user
 Structure for SIP user data. User's place calls to us. 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 FORMAT   "%-15.15s %-10.10s %-11.11s %5.5d/%5.5d %-4.4s %-3.3s %-3.3s %-15.15s\n"
 sip_show_domains: CLI command to list local domains
#define FORMAT   "%-30.30s %-12.12s %8d %-20.20s\n"
 sip_show_domains: CLI command to list local domains
#define FORMAT   "%-40.40s %-20.20s %-16.16s\n"
 sip_show_domains: CLI command to list local domains
#define FORMAT   "%-25.25s %-15.15s %-3.3s %-3.3s %-3.3s %-8d %-10s\n"
 sip_show_domains: CLI command to list local domains
#define FORMAT   "%-25.25s %-15.15s %-15.15s %-15.15s %-5.5s%-10.10s\n"
 sip_show_domains: CLI command to list local domains
#define FORMAT   "%-25.25s %-15.15s %-15.15s \n"
 sip_show_domains: CLI command to list local domains
#define FORMAT2   "%-15.15s %-10.10s %-11.11s %-11.11s %-4.4s %-7.7s %-15.15s\n"
#define FORMAT2   "%-30.30s %-12.12s %8.8s %-20.20s\n"
#define FORMAT2   "%-25.25s %-15.15s %-3.3s %-3.3s %-3.3s %-8s %-10s\n"
#define FORMAT2   "%-25.25s %-15.15s %-15.15s \n"
#define FORMAT3   "%-15.15s %-10.10s %-11.11s %-15.15s %-13.13s %-15.15s\n"
#define FREE   free
#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 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.
static 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, char **transfercontext)
 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 ----
static 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, ast_group_t 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 sdp, 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 seqno, int reliable, int newbranch)
 transmit_request: transmit generic SIP request ---
static int transmit_request_with_auth (struct sip_pvt *p, int sipmethod, int seqno, 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_using_temp (char *callid, struct sockaddr_in *sin, int useglobal_nat, const int intended_method, struct sip_request *req, char *msg)
 transmit_response_using_temp: Transmit response, no retransmits, using temporary pvt
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 * sipsock_read_id
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 324 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.

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

Referenced by reload_config().

#define DEFAULT_CONTEXT   "default"
 

Definition at line 334 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 437 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 reqprep(), and transmit_register().

#define DEFAULT_MAXMS   2000
 

Definition at line 131 of file chan_sip.c.

#define DEFAULT_MWITIME   10
 

Definition at line 387 of file chan_sip.c.

Referenced by reload_config().

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

Definition at line 348 of file chan_sip.c.

Referenced by reload_config().

#define DEFAULT_REALM   "asterisk"
 

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

Referenced by reload_config().

#define EXPIRY_GUARD_LIMIT   30
 

Definition at line 109 of file chan_sip.c.

#define EXPIRY_GUARD_MIN   500
 

Definition at line 111 of file chan_sip.c.

#define EXPIRY_GUARD_PCT   0.20
 

Definition at line 115 of file chan_sip.c.

#define EXPIRY_GUARD_SECS   15
 

Definition at line 108 of file chan_sip.c.

#define FLAG_FATAL   (1 << 1)
 

Definition at line 705 of file chan_sip.c.

Referenced by __sip_reliable_xmit(), and retrans_pkt().

#define FLAG_RESPONSE   (1 << 0)
 

Definition at line 704 of file chan_sip.c.

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

#define FORMAT   "%-15.15s %-10.10s %-11.11s %5.5d/%5.5d %-4.4s %-3.3s %-3.3s %-15.15s\n"
 

sip_show_domains: CLI command to list local domains

Definition at line 7999 of file chan_sip.c.

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

sip_show_domains: CLI command to list local domains

Definition at line 7999 of file chan_sip.c.

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

sip_show_domains: CLI command to list local domains

Definition at line 7999 of file chan_sip.c.

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

sip_show_domains: CLI command to list local domains

Definition at line 7999 of file chan_sip.c.

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

sip_show_domains: CLI command to list local domains

Definition at line 7999 of file chan_sip.c.

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

sip_show_domains: CLI command to list local domains

Definition at line 7999 of file chan_sip.c.

#define FORMAT2   "%-15.15s %-10.10s %-11.11s %-11.11s %-4.4s %-7.7s %-15.15s\n"
 

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

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

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

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

Referenced by __sip_show_channels().

#define FREE   free
 

Definition at line 964 of file chan_sip.c.

#define INC_CALL_LIMIT   1
 

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

#define REG_STATE_AUTHSENT   2
 

Definition at line 813 of file chan_sip.c.

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

#define REG_STATE_FAILED   7
 

Definition at line 818 of file chan_sip.c.

Referenced by regstate2str(), and sip_reg_timeout().

#define REG_STATE_NOAUTH   6
 

Definition at line 817 of file chan_sip.c.

Referenced by registry_rerequest(), and regstate2str().

#define REG_STATE_REGISTERED   3
 

Definition at line 814 of file chan_sip.c.

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

#define REG_STATE_REGSENT   1
 

Definition at line 812 of file chan_sip.c.

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

#define REG_STATE_REJECTED   4
 

Definition at line 815 of file chan_sip.c.

Referenced by regstate2str(), and socket_read().

#define REG_STATE_TIMEOUT   5
 

Definition at line 816 of file chan_sip.c.

Referenced by attempt_transmit(), and regstate2str().

#define REG_STATE_UNREGISTERED   0
 

Definition at line 811 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 520 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 568 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 567 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 535 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 550 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 418 of file chan_sip.c.

Referenced by reload_config().

#define SIP_DEBUG_CONSOLE   1 << 1
 

Definition at line 419 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 537 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 541 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 539 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 540 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 538 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 574 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 527 of file chan_sip.c.

Referenced by handle_request_refer(), and sip_set_rtp_peer().

#define SIP_INC_COUNT   (1 << 31)
 

Definition at line 572 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 554 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 553 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 444 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 445 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 330 of file chan_sip.c.

#define SIP_NAT   (3 << 18)
 

four settings, uses two bits

Definition at line 543 of file chan_sip.c.

Referenced by __sip_xmit(), _sip_show_peer(), _sip_show_peers(), 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 transmit_response_using_temp().

#define SIP_NAT_ALWAYS   (3 << 18)
 

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

Referenced by handle_common_options(), and nat2str().

#define SIP_NAT_RFC3581   (1 << 18)
 

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

Referenced by __sip_xmit(), _sip_show_peers(), check_user_full(), check_via(), create_addr_from_peer(), handle_common_options(), 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 521 of file chan_sip.c.

Referenced by __sip_show_channels(), 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 525 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 522 of file chan_sip.c.

Referenced by process_sdp(), and sip_indicate().

#define SIP_OPT_100REL   (1 << 1)
 

Definition at line 271 of file chan_sip.c.

#define SIP_OPT_EARLY_SESSION   (1 << 3)
 

Definition at line 273 of file chan_sip.c.

#define SIP_OPT_EVENTLIST   (1 << 11)
 

Definition at line 281 of file chan_sip.c.

#define SIP_OPT_GRUU   (1 << 12)
 

Definition at line 282 of file chan_sip.c.

#define SIP_OPT_JOIN   (1 << 4)
 

Definition at line 274 of file chan_sip.c.

#define SIP_OPT_PATH   (1 << 5)
 

Definition at line 275 of file chan_sip.c.

#define SIP_OPT_PRECONDITION   (1 << 7)
 

Definition at line 277 of file chan_sip.c.

#define SIP_OPT_PREF   (1 << 6)
 

Definition at line 276 of file chan_sip.c.

#define SIP_OPT_PRIVACY   (1 << 8)
 

Definition at line 278 of file chan_sip.c.

#define SIP_OPT_REPLACES   (1 << 0)
 

Definition at line 270 of file chan_sip.c.

#define SIP_OPT_SDP_ANAT   (1 << 9)
 

Definition at line 279 of file chan_sip.c.

#define SIP_OPT_SEC_AGREE   (1 << 10)
 

Definition at line 280 of file chan_sip.c.

#define SIP_OPT_TARGET_DIALOG   (1 << 13)
 

Definition at line 283 of file chan_sip.c.

#define SIP_OPT_TIMER   (1 << 2)
 

Definition at line 272 of file chan_sip.c.

#define SIP_OSPAUTH   (3 << 26)
 

four settings, uses two bits

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

Referenced by check_auth(), and handle_common_options().

#define SIP_OSPAUTH_GATEWAY   (1 << 26)
 

Definition at line 563 of file chan_sip.c.

Referenced by check_auth(), and handle_common_options().

#define SIP_OSPAUTH_NO   (0 << 26)
 

Definition at line 562 of file chan_sip.c.

Referenced by check_auth().

#define SIP_OSPAUTH_PROXY   (2 << 26)
 

Definition at line 564 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 533 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 585 of file chan_sip.c.

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

#define SIP_PAGE2_IGNOREREGEXPIRE   (1 << 3)
 

Definition at line 583 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 584 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 582 of file chan_sip.c.

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

#define SIP_PAGE2_RTCACHEFRIENDS   (1 << 0)
 

Definition at line 580 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 581 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 526 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 588 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 589 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 556 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 557 of file chan_sip.c.

Referenced by sip_indicate(), and sip_show_settings().

#define SIP_PROG_INBAND_NO   (1 << 24)
 

Definition at line 558 of file chan_sip.c.

Referenced by handle_common_options(), and sip_show_settings().

#define SIP_PROG_INBAND_YES   (2 << 24)
 

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

Referenced by sip_indicate(), and sip_write().

#define SIP_PROMISCREDIR   (1 << 8)
 

Promiscuous redirection

Definition at line 528 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 531 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 549 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 551 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 523 of file chan_sip.c.

Referenced by sip_indicate().

#define SIP_SELFDESTRUCT   (1 << 14)
 

This is an autocreated peer

Definition at line 534 of file chan_sip.c.

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

#define SIP_SENDRPID   (1 << 30)
 

Definition at line 570 of file chan_sip.c.

Referenced by _sip_show_peer(), and handle_common_options().

#define SIP_TRUSTRPID   (1 << 9)
 

Trust RPID headers?

Definition at line 529 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 532 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 530 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 267 of file chan_sip.c.

#define SUPPORTED_EXTENSIONS   "replaces"
 

SIP Extensions we support.

Definition at line 327 of file chan_sip.c.

#define VIDEO_CODEC_MASK   0x1fc0000
 

Definition at line 93 of file chan_sip.c.


Enumeration Type Documentation

enum domain_mode
 

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

Definition at line 489 of file chan_sip.c.

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

enum parse_register_result
 

Enumerator:
PARSE_REGISTER_FAILED 
PARSE_REGISTER_UPDATE 
PARSE_REGISTER_QUERY 

Definition at line 5945 of file chan_sip.c.

enum sip_auth_type
 

Enumerator:
PROXY_AUTH 
WWW_AUTH 

Definition at line 202 of file chan_sip.c.

00202                    {
00203    PROXY_AUTH,
00204    WWW_AUTH,
00205 };

enum sipmethod
 

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

Enumerator:
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 2951 of file chan_sip.c.

References sip_request::header, sip_request::headers, pass, and pedanticsipchecking.

02952 {
02953    int pass;
02954 
02955    /*
02956     * Technically you can place arbitrary whitespace both before and after the ':' in
02957     * a header, although RFC3261 clearly says you shouldn't before, and place just
02958     * one afterwards.  If you shouldn't do it, what absolute idiot decided it was 
02959     * a good idea to say you can do it, and if you can do it, why in the hell would.
02960     * you say you shouldn't.
02961     * Anyways, pedanticsipchecking controls whether we allow spaces before ':',
02962     * and we always allow spaces after that for compatibility.
02963     */
02964    for (pass = 0; name && pass < 2;pass++) {
02965       int x, len = strlen(name);
02966       for (x=*start; x<req->headers; x++) {
02967          if (!strncasecmp(req->header[x], name, len)) {
02968             char *r = req->header[x] + len;  /* skip name */
02969             if (pedanticsipchecking)
02970                r = ast_skip_blanks(r);
02971 
02972             if (*r == ':') {
02973                *start = x+1;
02974                return ast_skip_blanks(r+1);
02975             }
02976          }
02977       }
02978       if (pass == 0) /* Try aliases */
02979          name = find_alias(name, NULL);
02980    }
02981 
02982    /* Don't return NULL, so get_header is always a valid pointer */
02983    return "";
02984 }

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 1373 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, sched, sip_pkt::seqno, sip_methods, and cfsip_methods::text.

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

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

static int __sip_autodestruct void *  data  )  [static]
 

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

Definition at line 1317 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().

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

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

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

Definition at line 2114 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, free, free_old_route(), iflist, LOG_DEBUG, LOG_WARNING, sip_pvt::next, oh323_pvt::next, sip_history::next, sip_pkt::retransid, sched, sip_debug_test_pvt(), sip_dump_history(), and sip_registry_destroy().

Referenced by do_monitor(), and sip_destroy().

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

static int __sip_do_register struct sip_registry r  )  [static]
 

__sip_do_register: Register with SIP proxy ---

Definition at line 5408 of file chan_sip.c.

References SIP_REGISTER, and transmit_register().

Referenced by sip_reregister().

05409 {
05410    int res;
05411 
05412    res = transmit_register(r, SIP_REGISTER, NULL, NULL);
05413    return res;
05414 }

static int __sip_pretend_ack struct sip_pvt p  )  [static]
 

Definition at line 1417 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().

01418 {
01419    struct sip_pkt *cur=NULL;
01420 
01421    while(p->packets) {
01422       if (cur == p->packets) {
01423          ast_log(LOG_WARNING, "Have a packet that doesn't want to give up! %s\n", sip_methods[cur->method].text);
01424          return -1;
01425       }
01426       cur = p->packets;
01427       if (cur->method)
01428          __sip_ack(p, p->packets->seqno, (ast_test_flag(p->packets, FLAG_RESPONSE)), cur->method);
01429       else {   /* Unknown packet type */
01430          char *c;
01431          char method[128];
01432          ast_copy_string(method, p->packets->data, sizeof(method));
01433          c = ast_skip_blanks(method); /* XXX what ? */
01434          *c = '\0';
01435          __sip_ack(p, p->packets->seqno, (ast_test_flag(p->packets, FLAG_RESPONSE)), find_sip_method(method));
01436       }
01437    }
01438    return 0;
01439 }

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

References __sip_xmit(), ast_log(), ast_sched_add_variable(), ast_set_flag, sip_pkt::data, DEFAULT_RETRANS, FLAG_FATAL, sip_pkt::flags, LOG_DEBUG, malloc, sip_pkt::method, sip_pkt::next, option_debug, sip_pkt::owner, sip_pkt::packetlen, sip_pvt::packets, sip_pvt::pendinginvite, retrans_pkt(), sched, sip_pkt::seqno, SIP_INVITE, sip_pvt::timer_t1, and sip_pkt::timer_t1.

Referenced by send_request(), and send_response().

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

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 1442 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, sched, sip_pkt::seqno, sip_methods, and cfsip_methods::text.

Referenced by handle_response().

01443 {
01444    struct sip_pkt *cur;
01445    int res = -1;
01446    char *msg = sip_methods[sipmethod].text;
01447 
01448    cur = p->packets;
01449    while(cur) {
01450       if ((cur->seqno == seqno) && ((ast_test_flag(cur, FLAG_RESPONSE)) == resp) &&
01451          ((ast_test_flag(cur, FLAG_RESPONSE)) || 
01452           (!strncasecmp(msg, cur->data, strlen(msg)) && (cur->data[strlen(msg)] < 33)))) {
01453          /* this is our baby */
01454          if (cur->retransid > -1) {
01455             if (option_debug > 3 && sipdebug)
01456                ast_log(LOG_DEBUG, "*** SIP TIMER: Cancelling retransmission #%d - %s (got response)\n", cur->retransid, msg);
01457             ast_sched_del(sched, cur->retransid);
01458          }
01459          cur->retransid = -1;
01460          res = 0;
01461          break;
01462       }
01463       cur = cur->next;
01464    }
01465    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");
01466    return res;
01467 }

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

Definition at line 8456 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, FORMAT3, 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().

08457 {
08458 #define FORMAT3 "%-15.15s  %-10.10s  %-11.11s  %-15.15s  %-13.13s  %-15.15s\n"
08459 #define FORMAT2 "%-15.15s  %-10.10s  %-11.11s  %-11.11s  %-4.4s  %-7.7s  %-15.15s\n"
08460 #define FORMAT  "%-15.15s  %-10.10s  %-11.11s  %5.5d/%5.5d  %-4.4s  %-3.3s %-3.3s  %-15.15s\n"
08461    struct sip_pvt *cur;
08462    char iabuf[INET_ADDRSTRLEN];
08463    int numchans = 0;
08464    if (argc != 3)
08465       return RESULT_SHOWUSAGE;
08466    ast_mutex_lock(&iflock);
08467    cur = iflist;
08468    if (!subscriptions)
08469       ast_cli(fd, FORMAT2, "Peer", "User/ANR", "Call ID", "Seq (Tx/Rx)", "Format", "Hold", "Last Message");
08470    else
08471       ast_cli(fd, FORMAT3, "Peer", "User", "Call ID", "Extension", "Last state", "Type");
08472    while (cur) {
08473       if (cur->subscribed == NONE && !subscriptions) {
08474          ast_cli(fd, FORMAT, ast_inet_ntoa(iabuf, sizeof(iabuf), cur->sa.sin_addr), 
08475             ast_strlen_zero(cur->username) ? ( ast_strlen_zero(cur->cid_num) ? "(None)" : cur->cid_num ) : cur->username, 
08476             cur->callid, 
08477             cur->ocseq, cur->icseq, 
08478             ast_getformatname(cur->owner ? cur->owner->nativeformats : 0), 
08479             ast_test_flag(cur, SIP_CALL_ONHOLD) ? "Yes" : "No",
08480             ast_test_flag(cur, SIP_NEEDDESTROY) ? "(d)" : "",
08481             cur->lastmsg );
08482          numchans++;
08483       }
08484       if (cur->subscribed != NONE && subscriptions) {
08485          ast_cli(fd, FORMAT3, ast_inet_ntoa(iabuf, sizeof(iabuf), cur->sa.sin_addr),
08486                  ast_strlen_zero(cur->username) ? ( ast_strlen_zero(cur->cid_num) ? "(None)" : cur->cid_num ) : cur->username, 
08487                  cur->callid, cur->exten, ast_extension_state2str(cur->laststate), 
08488                  subscription_type2str(cur->subscribed));
08489          numchans++;
08490       }
08491       cur = cur->next;
08492    }
08493    ast_mutex_unlock(&iflock);
08494    if (!subscriptions)
08495       ast_cli(fd, "%d active SIP channel%s\n", numchans, (numchans != 1) ? "s" : "");
08496    else
08497       ast_cli(fd, "%d active SIP subscription%s\n", numchans, (numchans != 1) ? "s" : "");
08498    return RESULT_SUCCESS;
08499 #undef FORMAT
08500 #undef FORMAT2
08501 #undef FORMAT3
08502 }

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

__sip_xmit: Transmit SIP message ---

Definition at line 1073 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().

01074 {
01075    int res;
01076    char iabuf[INET_ADDRSTRLEN];
01077 
01078    if (ast_test_flag(p, SIP_NAT) & SIP_NAT_ROUTE)
01079       res=sendto(sipsock, data, len, 0, (struct sockaddr *)&p->recv, sizeof(struct sockaddr_in));
01080    else
01081       res=sendto(sipsock, data, len, 0, (struct sockaddr *)&p->sa, sizeof(struct sockaddr_in));
01082 
01083    if (res != len) {
01084       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));
01085    }
01086    return res;
01087 }

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 4239 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(), transmit_response_reliable(), and transmit_response_using_temp().

04240 {
04241    struct sip_request resp;
04242    int seqno = 0;
04243 
04244    if (reliable && (sscanf(get_header(req, "CSeq"), "%d ", &seqno) != 1)) {
04245       ast_log(LOG_WARNING, "Unable to determine sequence number from '%s'\n", get_header(req, "CSeq"));
04246       return -1;
04247    }
04248    respprep(&resp, p, msg, req);
04249    add_header_contentLength(&resp, 0);
04250    /* If we are cancelling an incoming invite for some reason, add information
04251       about the reason why we are doing this in clear text */
04252    if (msg[0] != '1' && p->owner && p->owner->hangupcause) {
04253       add_header(&resp, "X-Asterisk-HangupCause", ast_cause2str(p->owner->hangupcause));
04254    }
04255    add_blank_header(&resp);
04256    return send_response(p, &resp, reliable, seqno);
04257 }

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

Definition at line 8062 of file chan_sip.c.

References sip_peer::accountcode, sip_peer::addr, sip_peer::amaflags, ast_callerid_merge(), ast_cdr_flags2str(), ast_cli(), ast_describe_caller_presentation(), 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, 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, s, 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().

08063 {
08064    char status[30] = "";
08065    char cbuf[256];
08066    char iabuf[INET_ADDRSTRLEN];
08067    struct sip_peer *peer;
08068    char codec_buf[512];
08069    struct ast_codec_pref *pref;
08070    struct ast_variable *v;
08071    struct sip_auth *auth;
08072    int x = 0, codec = 0, load_realtime = 0;
08073 
08074    if (argc < 4)
08075       return RESULT_SHOWUSAGE;
08076 
08077    load_realtime = (argc == 5 && !strcmp(argv[4], "load")) ? 1 : 0;
08078    peer = find_peer(argv[3], NULL, load_realtime);
08079    if (s) {    /* Manager */
08080       if (peer)
08081          ast_cli(s->fd, "Response: Success\r\n");
08082       else {
08083          snprintf (cbuf, sizeof(cbuf), "Peer %s not found.\n", argv[3]);
08084          astman_send_error(s, m, cbuf);
08085          return 0;
08086       }
08087    }
08088    if (peer && type==0 ) { /* Normal listing */
08089       ast_cli(fd,"\n\n");
08090       ast_cli(fd, "  * Name       : %s\n", peer->name);
08091       ast_cli(fd, "  Secret       : %s\n", ast_strlen_zero(peer->secret)?"<Not set>":"<Set>");
08092       ast_cli(fd, "  MD5Secret    : %s\n", ast_strlen_zero(peer->md5secret)?"<Not set>":"<Set>");
08093       auth = peer->auth;
08094       while(auth) {
08095          ast_cli(fd, "  Realm-auth   : Realm %-15.15s User %-10.20s ", auth->realm, auth->username);
08096          ast_cli(fd, "%s\n", !ast_strlen_zero(auth->secret)?"<Secret set>":(!ast_strlen_zero(auth->md5secret)?"<MD5secret set>" : "<Not set>"));
08097          auth = auth->next;
08098       }
08099       ast_cli(fd, "  Context      : %s\n", peer->context);
08100       ast_cli(fd, "  Subscr.Cont. : %s\n", ast_strlen_zero(peer->subscribecontext)?"<Not set>":peer->subscribecontext);
08101       ast_cli(fd, "  Language     : %s\n", peer->language);
08102       if (!ast_strlen_zero(peer->accountcode))
08103          ast_cli(fd, "  Accountcode  : %s\n", peer->accountcode);
08104       ast_cli(fd, "  AMA flags    : %s\n", ast_cdr_flags2str(peer->amaflags));
08105       ast_cli(fd, "  CallingPres  : %s\n", ast_describe_caller_presentation(peer->callingpres));
08106       if (!ast_strlen_zero(peer->fromuser))
08107          ast_cli(fd, "  FromUser     : %s\n", peer->fromuser);
08108       if (!ast_strlen_zero(peer->fromdomain))
08109          ast_cli(fd, "  FromDomain   : %s\n", peer->fromdomain);
08110       ast_cli(fd, "  Callgroup    : ");
08111       print_group(fd, peer->callgroup, 0);
08112       ast_cli(fd, "  Pickupgroup  : ");
08113       print_group(fd, peer->pickupgroup, 0);
08114       ast_cli(fd, "  Mailbox      : %s\n", peer->mailbox);
08115       ast_cli(fd, "  VM Extension : %s\n", peer->vmexten);
08116       ast_cli(fd, "  LastMsgsSent : %d\n", peer->lastmsgssent);
08117       ast_cli(fd, "  Call limit   : %d\n", peer->call_limit);
08118       ast_cli(fd, "  Dynamic      : %s\n", (ast_test_flag(&peer->flags_page2, SIP_PAGE2_DYNAMIC)?"Yes":"No"));
08119       ast_cli(fd, "  Callerid     : %s\n", ast_callerid_merge(cbuf, sizeof(cbuf), peer->cid_name, peer->cid_num, "<unspecified>"));
08120       ast_cli(fd, "  Expire       : %ld\n", ast_sched_when(sched, peer->expire));
08121       ast_cli(fd, "  Insecure     : %s\n", insecure2str(ast_test_flag(peer, SIP_INSECURE_PORT), ast_test_flag(peer, SIP_INSECURE_INVITE)));
08122       ast_cli(fd, "  Nat          : %s\n", nat2str(ast_test_flag(peer, SIP_NAT)));
08123       ast_cli(fd, "  ACL          : %s\n", (peer->ha?"Yes":"No"));
08124       ast_cli(fd, "  CanReinvite  : %s\n", (ast_test_flag(peer, SIP_CAN_REINVITE)?"Yes":"No"));
08125       ast_cli(fd, "  PromiscRedir : %s\n", (ast_test_flag(peer, SIP_PROMISCREDIR)?"Yes":"No"));
08126       ast_cli(fd, "  User=Phone   : %s\n", (ast_test_flag(peer, SIP_USEREQPHONE)?"Yes":"No"));
08127       ast_cli(fd, "  Trust RPID   : %s\n", (ast_test_flag(peer, SIP_TRUSTRPID) ? "Yes" : "No"));
08128       ast_cli(fd, "  Send RPID    : %s\n", (ast_test_flag(peer, SIP_SENDRPID) ? "Yes" : "No"));
08129 
08130       /* - is enumerated */
08131       ast_cli(fd, "  DTMFmode     : %s\n", dtmfmode2str(ast_test_flag(peer, SIP_DTMF)));
08132       ast_cli(fd, "  LastMsg      : %d\n", peer->lastmsg);
08133       ast_cli(fd, "  ToHost       : %s\n", peer->tohost);
08134       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));
08135       ast_cli(fd, "  Defaddr->IP  : %s Port %d\n", ast_inet_ntoa(iabuf, sizeof(iabuf), peer->defaddr.sin_addr), ntohs(peer->defaddr.sin_port));
08136       ast_cli(fd, "  Def. Username: %s\n", peer->username);
08137       ast_cli(fd, "  SIP Options  : ");
08138       if (peer->sipoptions) {
08139          for (x=0 ; (x < (sizeof(sip_options) / sizeof(sip_options[0]))); x++) {
08140             if (peer->sipoptions & sip_options[x].id)
08141                ast_cli(fd, "%s ", sip_options[x].text);
08142          }
08143       } else
08144          ast_cli(fd, "(none)");
08145 
08146       ast_cli(fd, "\n");
08147       ast_cli(fd, "  Codecs       : ");
08148       ast_getformatname_multiple(codec_buf, sizeof(codec_buf) -1, peer->capability);
08149       ast_cli(fd, "%s\n", codec_buf);
08150       ast_cli(fd, "  Codec Order  : (");
08151       print_codec_to_cli(fd, &peer->prefs);
08152 
08153       ast_cli(fd, ")\n");
08154 
08155       ast_cli(fd, "  Status       : ");
08156       peer_status(peer, status, sizeof(status));
08157       ast_cli(fd, "%s\n",status);
08158       ast_cli(fd, "  Useragent    : %s\n", peer->useragent);
08159       ast_cli(fd, "  Reg. Contact : %s\n", peer->fullcontact);
08160       if (peer->chanvars) {
08161          ast_cli(fd, "  Variables    :\n");
08162          for (v = peer->chanvars ; v ; v = v->next)
08163             ast_cli(fd, "                 %s = %s\n", v->name, v->value);
08164       }
08165       ast_cli(fd,"\n");
08166       ASTOBJ_UNREF(peer,sip_destroy_peer);
08167    } else  if (peer && type == 1) { /* manager listing */
08168       ast_cli(fd, "Channeltype: SIP\r\n");
08169       ast_cli(fd, "ObjectName: %s\r\n", peer->name);
08170       ast_cli(fd, "ChanObjectType: peer\r\n");
08171       ast_cli(fd, "SecretExist: %s\r\n", ast_strlen_zero(peer->secret)?"N":"Y");
08172       ast_cli(fd, "MD5SecretExist: %s\r\n", ast_strlen_zero(peer->md5secret)?"N":"Y");
08173       ast_cli(fd, "Context: %s\r\n", peer->context);
08174       ast_cli(fd, "Language: %s\r\n", peer->language);
08175       if (!ast_strlen_zero(peer->accountcode))
08176          ast_cli(fd, "Accountcode: %s\r\n", peer->accountcode);
08177       ast_cli(fd, "AMAflags: %s\r\n", ast_cdr_flags2str(peer->amaflags));
08178       ast_cli(fd, "CID-CallingPres: %s\r\n", ast_describe_caller_presentation(peer->callingpres));
08179       if (!ast_strlen_zero(peer->fromuser))
08180          ast_cli(fd, "SIP-FromUser: %s\r\n", peer->fromuser);
08181       if (!ast_strlen_zero(peer->fromdomain))
08182          ast_cli(fd, "SIP-FromDomain: %s\r\n", peer->fromdomain);
08183       ast_cli(fd, "Callgroup: ");
08184       print_group(fd, peer->callgroup, 1);
08185       ast_cli(fd, "Pickupgroup: ");
08186       print_group(fd, peer->pickupgroup, 1);
08187       ast_cli(fd, "VoiceMailbox: %s\r\n", peer->mailbox);
08188       ast_cli(fd, "LastMsgsSent: %d\r\n", peer->lastmsgssent);
08189       ast_cli(fd, "Call limit: %d\r\n", peer->call_limit);
08190       ast_cli(fd, "Dynamic: %s\r\n", (ast_test_flag(&peer->flags_page2, SIP_PAGE2_DYNAMIC)?"Y":"N"));
08191       ast_cli(fd, "Callerid: %s\r\n", ast_callerid_merge(cbuf, sizeof(cbuf), peer->cid_name, peer->cid_num, ""));
08192       ast_cli(fd, "RegExpire: %ld seconds\r\n", ast_sched_when(sched,peer->expire));
08193       ast_cli(fd, "SIP-AuthInsecure: %s\r\n", insecure2str(ast_test_flag(peer, SIP_INSECURE_PORT), ast_test_flag(peer, SIP_INSECURE_INVITE)));
08194       ast_cli(fd, "SIP-NatSupport: %s\r\n", nat2str(ast_test_flag(peer, SIP_NAT)));
08195       ast_cli(fd, "ACL: %s\r\n", (peer->ha?"Y":"N"));
08196       ast_cli(fd, "SIP-CanReinvite: %s\r\n", (ast_test_flag(peer, SIP_CAN_REINVITE)?"Y":"N"));
08197       ast_cli(fd, "SIP-PromiscRedir: %s\r\n", (ast_test_flag(peer, SIP_PROMISCREDIR)?"Y":"N"));
08198       ast_cli(fd, "SIP-UserPhone: %s\r\n", (ast_test_flag(peer, SIP_USEREQPHONE)?"Y":"N"));
08199 
08200       /* - is enumerated */
08201       ast_cli(fd, "SIP-DTMFmode: %s\r\n", dtmfmode2str(ast_test_flag(peer, SIP_DTMF)));
08202       ast_cli(fd, "SIPLastMsg: %d\r\n", peer->lastmsg);
08203       ast_cli(fd, "ToHost: %s\r\n", peer->tohost);
08204       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));
08205       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));
08206       ast_cli(fd, "Default-Username: %s\r\n", peer->username);
08207       ast_cli(fd, "Codecs: ");
08208       ast_getformatname_multiple(codec_buf, sizeof(codec_buf) -1, peer->capability);
08209       ast_cli(fd, "%s\r\n", codec_buf);
08210       ast_cli(fd, "CodecOrder: ");
08211       pref = &peer->prefs;
08212       for(x = 0; x < 32 ; x++) {
08213          codec = ast_codec_pref_index(pref,x);
08214          if (!codec)
08215             break;
08216          ast_cli(fd, "%s", ast_getformatname(codec));
08217          if (x < 31 && ast_codec_pref_index(pref,x+1))
08218             ast_cli(fd, ",");
08219       }
08220 
08221       ast_cli(fd, "\r\n");
08222       ast_cli(fd, "Status: ");
08223       peer_status(peer, status, sizeof(status));
08224       ast_cli(fd, "%s\r\n", status);
08225       ast_cli(fd, "SIP-Useragent: %s\r\n", peer->useragent);
08226       ast_cli(fd, "Reg-Contact : %s\r\n", peer->fullcontact);
08227       if (peer->chanvars) {
08228          for (v = peer->chanvars ; v ; v = v->next) {
08229             ast_cli(fd, "ChanVariable:\n");
08230             ast_cli(fd, " %s,%s\r\n", v->name, v->value);
08231          }
08232       }
08233 
08234       ASTOBJ_UNREF(peer,sip_destroy_peer);
08235 
08236    } else {
08237       ast_cli(fd,"Peer %s not found.\n", argv[3]);
08238       ast_cli(fd,"\n");
08239    }
08240 
08241    return RESULT_SUCCESS;
08242 }

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

References ast_cli(), ast_inet_ntoa(), ast_strlen_zero(), ast_test_flag, astman_get_header(), ASTOBJ_CONTAINER_TRAVERSE, ASTOBJ_RDLOCK, ASTOBJ_UNLOCK, FORMAT, FORMAT2, id, name, peer_status(), peerl, RESULT_SHOWUSAGE, s, SIP_NAT, SIP_NAT_ROUTE, and SIP_PAGE2_DYNAMIC.

Referenced by manager_sip_show_peers(), and sip_show_peers().

07641 {
07642    regex_t regexbuf;
07643    int havepattern = 0;
07644 
07645 #define FORMAT2 "%-25.25s  %-15.15s %-3.3s %-3.3s %-3.3s %-8s %-10s\n"
07646 #define FORMAT  "%-25.25s  %-15.15s %-3.3s %-3.3s %-3.3s %-8d %-10s\n"
07647 
07648    char name[256];
07649    char iabuf[INET_ADDRSTRLEN];
07650    int total_peers = 0;
07651    int peers_online = 0;
07652    int peers_offline = 0;
07653    char *id;
07654    char idtext[256] = "";
07655 
07656    if (s) { /* Manager - get ActionID */
07657       id = astman_get_header(m,"ActionID");
07658       if (!ast_strlen_zero(id))
07659          snprintf(idtext,256,"ActionID: %s\r\n",id);
07660    }
07661 
07662    switch (argc) {
07663    case 5:
07664       if (!strcasecmp(argv[3], "like")) {
07665          if (regcomp(&regexbuf, argv[4], REG_EXTENDED | REG_NOSUB))
07666             return RESULT_SHOWUSAGE;
07667          havepattern = 1;
07668       } else
07669          return RESULT_SHOWUSAGE;
07670    case 3:
07671       break;
07672    default:
07673       return RESULT_SHOWUSAGE;
07674    }
07675 
07676    if (!s) { /* Normal list */
07677       ast_cli(fd, FORMAT2, "Name/username", "Host", "Dyn", "Nat", "ACL", "Port", "Status");
07678    } 
07679    
07680    ASTOBJ_CONTAINER_TRAVERSE(&peerl, 1, do {
07681       char status[20] = "";
07682       char srch[2000];
07683       char pstatus;
07684       
07685       ASTOBJ_RDLOCK(iterator);
07686 
07687       if (havepattern && regexec(&regexbuf, iterator->name, 0, NULL, 0)) {
07688          ASTOBJ_UNLOCK(iterator);
07689          continue;
07690       }
07691 
07692       if (!ast_strlen_zero(iterator->username) && !s)
07693          snprintf(name, sizeof(name), "%s/%s", iterator->name, iterator->username);
07694       else
07695          ast_copy_string(name, iterator->name, sizeof(name));
07696 
07697       pstatus = peer_status(iterator, status, sizeof(status));
07698       if (pstatus)   
07699          peers_online++;
07700       else  {
07701          if (pstatus == 0)
07702             peers_offline++;
07703          else {   /* Unmonitored */
07704             /* Checking if port is 0 */
07705             if ( ntohs(iterator->addr.sin_port) == 0 ) {
07706                peers_offline++;
07707             } else {
07708                peers_online++;
07709             }
07710          }
07711       }        
07712       
07713       snprintf(srch, sizeof(srch), FORMAT, name,
07714          iterator->addr.sin_addr.s_addr ? ast_inet_ntoa(iabuf, sizeof(iabuf), iterator->addr.sin_addr) : "(Unspecified)",
07715          ast_test_flag(&iterator->flags_page2, SIP_PAGE2_DYNAMIC) ? " D " : "   ",  /* Dynamic or not? */
07716          (ast_test_flag(iterator, SIP_NAT) & SIP_NAT_ROUTE) ? " N " : "   ",  /* NAT=yes? */
07717          iterator->ha ? " A " : "   ",    /* permit/deny */
07718          ntohs(iterator->addr.sin_port), status);
07719 
07720       if (!s)  {/* Normal CLI list */
07721          ast_cli(fd, FORMAT, name, 
07722          iterator->addr.sin_addr.s_addr ? ast_inet_ntoa(iabuf, sizeof(iabuf), iterator->addr.sin_addr) : "(Unspecified)",
07723          ast_test_flag(&iterator->flags_page2, SIP_PAGE2_DYNAMIC) ? " D " : "   ",  /* Dynamic or not? */
07724          (ast_test_flag(iterator, SIP_NAT) & SIP_NAT_ROUTE) ? " N " : "   ",  /* NAT=yes? */
07725          iterator->ha ? " A " : "   ",       /* permit/deny */
07726          
07727          ntohs(iterator->addr.sin_port), status);
07728       } else { /* Manager format */
07729          /* The names here need to be the same as other channels */
07730          ast_cli(fd, 
07731          "Event: PeerEntry\r\n%s"
07732          "Channeltype: SIP\r\n"
07733          "ObjectName: %s\r\n"
07734          "ChanObjectType: peer\r\n" /* "peer" or "user" */
07735          "IPaddress: %s\r\n"
07736          "IPport: %d\r\n"
07737          "Dynamic: %s\r\n"
07738          "Natsupport: %s\r\n"
07739          "ACL: %s\r\n"
07740          "Status: %s\r\n\r\n", 
07741          idtext,
07742          iterator->name, 
07743          iterator->addr.sin_addr.s_addr ? ast_inet_ntoa(iabuf, sizeof(iabuf), iterator->addr.sin_addr) : "-none-",
07744          ntohs(iterator->addr.sin_port), 
07745          ast_test_flag(&iterator->flags_page2, SIP_PAGE2_DYNAMIC) ? "yes" : "no",  /* Dynamic or not? */
07746          (ast_test_flag(iterator, SIP_NAT) & SIP_NAT_ROUTE) ? "yes" : "no",   /* NAT=yes? */
07747          iterator->ha ? "yes" : "no",       /* permit/deny */
07748          status);
07749       }
07750 
07751       ASTOBJ_UNLOCK(iterator);
07752 
07753       total_peers++;
07754    } while(0) );
07755 
07756    if (!s) {
07757       ast_cli(fd,"%d sip peers [%d online , %d offline]\n",total_peers,peers_online,peers_offline);
07758    }
07759 
07760    if (havepattern)
07761       regfree(&regexbuf);
07762 
07763    if (total)
07764       *total = total_peers;
07765    
07766 
07767    return RESULT_SUCCESS;
07768 #undef FORMAT
07769 #undef FORMAT2
07770 }

static int add_blank_header struct sip_request req  )  [static]
 

add_blank_header: Add blank header to SIP message

Definition at line 3828 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().

03829 {
03830    if (req->headers == SIP_MAX_HEADERS)  {
03831       ast_log(LOG_WARNING, "Out of SIP header space\n");
03832       return -1;
03833    }
03834    if (req->lines) {
03835       ast_log(LOG_WARNING, "Can't add more headers when lines have been added\n");
03836       return -1;
03837    }
03838    if (req->len >= sizeof(req->data) - 4) {
03839       ast_log(LOG_WARNING, "Out of space, can't add anymore\n");
03840       return -1;
03841    }
03842    req->header[req->headers] = req->data + req->len;
03843    snprintf(req->header[req->headers], sizeof(req->data) - req->len, "\r\n");
03844    req->len += strlen(req->header[req->headers]);
03845    req->headers++;
03846    return 0;   
03847 }

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 4412 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().

04415 {
04416    int rtp_code;
04417 
04418    if (debug)
04419       ast_verbose("Adding codec 0x%x (%s) to SDP\n", codec, ast_getformatname(codec));
04420    if ((rtp_code = ast_rtp_lookup_code(p->rtp, 1, codec)) == -1)
04421       return;
04422 
04423    ast_build_string(m_buf, m_size, " %d", rtp_code);
04424    ast_build_string(a_buf, a_size, "a=rtpmap:%d %s/%d\r\n", rtp_code,
04425           ast_rtp_lookup_mime_subtype(1, codec),
04426           sample_rate);
04427    if (codec == AST_FORMAT_G729A)
04428       /* Indicate that we don't support VAD (G.729 annex B) */
04429       ast_build_string(a_buf, a_size, "a=fmtp:%d annexb=no\r\n", rtp_code);
04430 }

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

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

Definition at line 4381 of file chan_sip.c.

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

Referenced by transmit_info_with_digit().

04382 {
04383    char tmp[256];
04384 
04385    snprintf(tmp, sizeof(tmp), "Signal=%c\r\nDuration=250\r\n", digit);
04386    add_header(req, "Content-Type", "application/dtmf-relay");
04387    add_header_contentLength(req, strlen(tmp));
04388    add_line(req, tmp);
04389    return 0;
04390 }

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

03785 {
03786    int x = 0;
03787 
03788    if (req->headers == SIP_MAX_HEADERS) {
03789       ast_log(LOG_WARNING, "Out of SIP header space\n");
03790       return -1;
03791    }
03792 
03793    if (req->lines) {
03794       ast_log(LOG_WARNING, "Can't add more headers when lines have been added\n");
03795       return -1;
03796    }
03797 
03798    if (req->len >= sizeof(req->data) - 4) {
03799       ast_log(LOG_WARNING, "Out of space, can't add anymore (%s:%s)\n", var, value);
03800       return -1;
03801    }
03802 
03803    req->header[req->headers] = req->data + req->len;
03804 
03805    if (compactheaders) {
03806       for (x = 0; x < (sizeof(aliases) / sizeof(aliases[0])); x++)
03807          if (!strcasecmp(aliases[x].fullname, var))
03808             var = aliases[x].shortname;
03809    }
03810 
03811    snprintf(req->header[req->headers], sizeof(req->data) - req->len - 4, "%s: %s\r\n", var, value);
03812    req->len += strlen(req->header[req->headers]);
03813    req->headers++;
03814 
03815    return 0;   
03816 }

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

References add_header().

Referenced by __transmit_response(), add_digit(), 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().

03820 {
03821    char clen[10];
03822 
03823    snprintf(clen, sizeof(clen), "%d", len);
03824    return add_header(req, "Content-Length", clen);
03825 }

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

add_line: Add content (not header) to SIP message

Definition at line 3850 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.

03851 {
03852    if (req->lines == SIP_MAX_LINES)  {
03853       ast_log(LOG_WARNING, "Out of SIP line space\n");
03854       return -1;
03855    }
03856    if (!req->lines) {
03857       /* Add extra empty return */
03858       snprintf(req->data + req->len, sizeof(req->data) - req->len, "\r\n");
03859       req->len += strlen(req->data + req->len);
03860    }
03861    if (req->len >= sizeof(req->data) - 4) {
03862       ast_log(LOG_WARNING, "Out of space, can't add anymore\n");
03863       return -1;
03864    }
03865    req->line[req->lines] = req->data + req->len;
03866    snprintf(req->line[req->lines], sizeof(req->data) - req->len, "%s", line);
03867    req->len += strlen(req->line[req->lines]);
03868    req->lines++;
03869    return 0;   
03870 }

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

04435 {
04436    int rtp_code;
04437 
04438    if (debug)
04439       ast_verbose("Adding non-codec 0x%x (%s) to SDP\n", format, ast_rtp_lookup_mime_subtype(0, format));
04440    if ((rtp_code = ast_rtp_lookup_code(p->rtp, 0, format)) == -1)
04441       return;
04442 
04443    ast_build_string(m_buf, m_size, " %d", rtp_code);
04444    ast_build_string(a_buf, a_size, "a=rtpmap:%d %s/%d\r\n", rtp_code,
04445           ast_rtp_lookup_mime_subtype(0, format),
04446           sample_rate);
04447    if (format == AST_RTP_DTMF)
04448       /* Indicate we support DTMF and FLASH... */
04449       ast_build_string(a_buf, a_size, "a=fmtp:%d 0-16\r\n", rtp_code);
04450 }

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 12064 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().

12065 {
12066    char authcopy[256];
12067    char *username=NULL, *realm=NULL, *secret=NULL, *md5secret=NULL;
12068    char *stringp;
12069    struct sip_auth *auth;
12070    struct sip_auth *b = NULL, *a = authlist;
12071 
12072    if (ast_strlen_zero(configuration))
12073       return authlist;
12074 
12075    ast_log(LOG_DEBUG, "Auth config ::  %s\n", configuration);
12076 
12077    ast_copy_string(authcopy, configuration, sizeof(authcopy));
12078    stringp = authcopy;
12079 
12080    username = stringp;
12081    realm = strrchr(stringp, '@');
12082    if (realm) {
12083       *realm = '\0';
12084       realm++;
12085    }
12086    if (ast_strlen_zero(username) || ast_strlen_zero(realm)) {
12087       ast_log(LOG_WARNING, "Format for authentication entry is user[:secret]@realm at line %d\n", lineno);
12088       return authlist;
12089    }
12090    stringp = username;
12091    username = strsep(&stringp, ":");
12092    if (username) {
12093       secret = strsep(&stringp, ":");
12094       if (!secret) {
12095          stringp = username;
12096          md5secret = strsep(&stringp,"#");
12097       }
12098    }
12099    auth = malloc(sizeof(struct sip_auth));
12100    if (auth) {
12101       memset(auth, 0, sizeof(struct sip_auth));
12102       ast_copy_string(auth->realm, realm, sizeof(auth->realm));
12103       ast_copy_string(auth->username, username, sizeof(auth->username));
12104       if (secret)
12105          ast_copy_string(auth->secret, secret, sizeof(auth->secret));
12106       if (md5secret)
12107          ast_copy_string(auth->md5secret, md5secret, sizeof(auth->md5secret));
12108    } else {
12109       ast_log(LOG_ERROR, "Allocation of auth structure failed, Out of memory\n");
12110       return authlist;
12111    }
12112 
12113    /* Add authentication to authl */
12114    if (!authlist) {  /* No existing list */
12115       return auth;
12116    } 
12117    while(a) {
12118       b = a;
12119       a = a->next;
12120    }
12121    b->next = auth;   /* Add structure add end of list */
12122 
12123    if (option_verbose > 2)
12124       ast_verbose("Added authentication for realm %s\n", realm);
12125 
12126    return authlist;
12127 
12128 }

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

References add_header(), sip_route::hop, n, and sip_route::next.

Referenced by reqprep().

03969 {
03970    char r[BUFSIZ*2], *p;
03971    int n, rem = sizeof(r);
03972 
03973    if (!route) return;
03974 
03975    p = r;
03976    while (route) {
03977       n = strlen(route->hop);
03978       if ((n+3)>rem) break;
03979       if (p != r) {
03980          *p++ = ',';
03981          --rem;
03982       }
03983       *p++ = '<';
03984       ast_copy_string(p, route->hop, rem);  p += n;
03985       *p++ = '>';
03986       rem -= (n+2);
03987       route = route->next;
03988    }
03989    *p = '\0';
03990    add_header(req, "Route", r);
03991 }

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

add_sdp: Add Session Description Protocol message ---

Definition at line 4453 of file chan_sip.c.

References add_codec_to_sdp(), ast_build_string(), ast_codec_pref_index(), AST_FORMAT_MAX_AUDIO, ast_inet_ntoa(), ast_log(), ast_rtp_get_us(), ast_verbose(), capability, debug, sip_pvt::jointcapability, sip_request::len, LOG_WARNING, 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(), t, sip_pvt::vredirip, and sip_pvt::vrtp.

04454 {
04455    int len = 0;
04456    int pref_codec;
04457    int alreadysent = 0;
04458    struct sockaddr_in sin;
04459    struct sockaddr_in vsin;
04460    char v[256];
04461    char s[256];
04462    char o[256];
04463    char c[256];
04464    char t[256];
04465    char m_audio[256];
04466    char m_video[256];
04467    char a_audio[1024];
04468    char a_video[1024];
04469    char *m_audio_next = m_audio;
04470    char *m_video_next = m_video;
04471    size_t m_audio_left = sizeof(m_audio);
04472    size_t m_video_left = sizeof(m_video);
04473    char *a_audio_next = a_audio;
04474    char *a_video_next = a_video;
04475    size_t a_audio_left = sizeof(a_audio);
04476    size_t a_video_left = sizeof(a_video);
04477    char iabuf[INET_ADDRSTRLEN];
04478    int x;
04479    int capability;
04480    struct sockaddr_in dest;
04481    struct sockaddr_in vdest = { 0, };
04482    int debug;
04483    
04484    debug = sip_debug_test_pvt(p);
04485 
04486    len = 0;
04487    if (!p->rtp) {
04488       ast_log(LOG_WARNING, "No way to add SDP without an RTP structure\n");
04489       return -1;
04490    }
04491    capability = p->jointcapability;
04492       
04493    if (!p->sessionid) {
04494       p->sessionid = getpid();
04495       p->sessionversion = p->sessionid;
04496    } else
04497       p->sessionversion++;
04498    ast_rtp_get_us(p->rtp, &sin);
04499    if (p->vrtp)
04500       ast_rtp_get_us(p->vrtp, &vsin);
04501 
04502    if (p->redirip.sin_addr.s_addr) {
04503       dest.sin_port = p->redirip.sin_port;
04504       dest.sin_addr = p->redirip.sin_addr;
04505       if (p->redircodecs)
04506          capability = p->redircodecs;
04507    } else {
04508       dest.sin_addr = p->ourip;
04509       dest.sin_port = sin.sin_port;
04510    }
04511 
04512    /* Determine video destination */
04513    if (p->vrtp) {
04514       if (p->vredirip.sin_addr.s_addr) {
04515          vdest.sin_port = p->vredirip.sin_port;
04516          vdest.sin_addr = p->vredirip.sin_addr;
04517       } else {
04518          vdest.sin_addr = p->ourip;
04519          vdest.sin_port = vsin.sin_port;
04520       }
04521    }
04522    if (debug){
04523       ast_verbose("We're at %s port %d\n", ast_inet_ntoa(iabuf, sizeof(iabuf), p->ourip), ntohs(sin.sin_port));   
04524       if (p->vrtp)
04525          ast_verbose("Video is at %s port %d\n", ast_inet_ntoa(iabuf, sizeof(iabuf), p->ourip), ntohs(vsin.sin_port));  
04526    }
04527 
04528    /* We break with the "recommendation" and send our IP, in order that our
04529       peer doesn't have to ast_gethostbyname() us */
04530 
04531    snprintf(v, sizeof(v), "v=0\r\n");
04532    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));
04533    snprintf(s, sizeof(s), "s=session\r\n");
04534    snprintf(c, sizeof(c), "c=IN IP4 %s\r\n", ast_inet_ntoa(iabuf, sizeof(iabuf), dest.sin_addr));
04535    snprintf(t, sizeof(t), "t=0 0\r\n");
04536 
04537    ast_build_string(&m_audio_next, &m_audio_left, "m=audio %d RTP/AVP", ntohs(dest.sin_port));
04538    ast_build_string(&m_video_next, &m_video_left, "m=video %d RTP/AVP", ntohs(vdest.sin_port));
04539 
04540    /* Prefer the codec we were requested to use, first, no matter what */
04541    if (capability & p->prefcodec) {
04542       if (p->prefcodec <= AST_FORMAT_MAX_AUDIO)
04543          add_codec_to_sdp(p, p->prefcodec, 8000,
04544                 &m_audio_next, &m_audio_left,
04545                 &a_audio_next, &a_audio_left,
04546                 debug);
04547       else
04548          add_codec_to_sdp(p, p->prefcodec, 90000,
04549                 &m_video_next, &m_video_left,
04550                 &a_video_next, &a_video_left,
04551                 debug);
04552       alreadysent |= p->prefcodec;
04553    }
04554 
04555    /* Start by sending our preferred codecs */
04556    for (x = 0; x < 32; x++) {
04557       if (!(pref_codec = ast_codec_pref_index(&p->prefs, x)))
04558          break; 
04559 
04560       if (!(capability & pref_codec))
04561          continue;
04562 
04563       if (alreadysent & pref_codec)
04564          continue;
04565 
04566       if (pref_codec <= AST_FORMAT_MAX_AUDIO)
04567          add_codec_to_sdp(p, pref_codec, 8000,
04568                 &m_audio_next, &m_audio_left,
04569                 &a_audio_next, &a_audio_left,
04570                 debug);
04571       else
04572          add_codec_to_sdp(p, pref_codec, 90000,
04573                 &m_video_next, &m_video_left,
04574                 &a_video_next, &a_video_left,
04575                 debug);
04576       alreadysent |= pref_codec;
04577    }
04578 
04579    /* Now send any other common codecs, and non-codec formats: */
04580    for (x = 1; x <= ((videosupport && p->vrtp) ? AST_FORMAT_MAX_VIDEO : AST_FORMAT_MAX_AUDIO); x <<= 1) {
04581       if (!(capability & x))
04582          continue;
04583 
04584       if (alreadysent & x)
04585          continue;
04586 
04587       if (x <= AST_FORMAT_MAX_AUDIO)
04588          add_codec_to_sdp(p, x, 8000,
04589                 &m_audio_next, &m_audio_left,
04590                 &a_audio_next, &a_audio_left,
04591                 debug);
04592       else
04593          add_codec_to_sdp(p, x, 90000,
04594                 &m_video_next, &m_video_left,
04595                 &a_video_next, &a_video_left,
04596                 debug);
04597    }
04598 
04599    for (x = 1; x <= AST_RTP_MAX; x <<= 1) {
04600       if (!(p->noncodeccapability & x))
04601          continue;
04602 
04603       add_noncodec_to_sdp(p, x, 8000,
04604                 &m_audio_next, &m_audio_left,
04605                 &a_audio_next, &a_audio_left,
04606                 debug);
04607    }
04608 
04609    ast_build_string(&a_audio_next, &a_audio_left, "a=silenceSupp:off - - - -\r\n");
04610 
04611    if ((m_audio_left < 2) || (m_video_left < 2) || (a_audio_left == 0) || (a_video_left == 0))
04612       ast_log(LOG_WARNING, "SIP SDP may be truncated due to undersized buffer!!\n");
04613 
04614    ast_build_string(&m_audio_next, &m_audio_left, "\r\n");
04615    ast_build_string(&m_video_next, &m_video_left, "\r\n");
04616 
04617    len = strlen(v) + strlen(s) + strlen(o) + strlen(c) + strlen(t) + strlen(m_audio) + strlen(a_audio);
04618    if ((p->vrtp) && (!ast_test_flag(p, SIP_NOVIDEO)) && (capability & VIDEO_CODEC_MASK)) /* only if video response is appropriate */
04619       len += strlen(m_video) + strlen(a_video);
04620 
04621    add_header(resp, "Content-Type", "application/sdp");
04622    add_header_contentLength(resp, len);
04623    add_line(resp, v);
04624    add_line(resp, o);
04625    add_line(resp, s);
04626    add_line(resp, c);
04627    add_line(resp, t);
04628    add_line(resp, m_audio);
04629    add_line(resp, a_audio);
04630    if ((p->vrtp) && (!ast_test_flag(p, SIP_NOVIDEO)) && (capability & VIDEO_CODEC_MASK)) { /* only if video response is appropriate */
04631       add_line(resp, m_video);
04632       add_line(resp, a_video);
04633    }
04634 
04635    /* Update lastrtprx when we send our SDP */
04636    time(&p->lastrtprx);
04637    time(&p->lastrtptx);
04638 
04639    return 0;
04640 }

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 11997 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().

11998 {
11999    struct domain *d;
12000 
12001    if (ast_strlen_zero(domain)) {
12002       ast_log(LOG_WARNING, "Zero length domain.\n");
12003       return 1;
12004    }
12005 
12006    d = calloc(1, sizeof(*d));
12007    if (!d) {
12008       ast_log(LOG_ERROR, "Allocation of domain structure failed, Out of memory\n");
12009       return 0;
12010    }
12011 
12012    ast_copy_string(d->domain, domain, sizeof(d->domain));
12013 
12014    if (!ast_strlen_zero(context))
12015       ast_copy_string(d->context, context, sizeof(d->context));
12016 
12017    d->mode = mode;
12018 
12019    AST_LIST_LOCK(&domain_list);
12020    AST_LIST_INSERT_TAIL(&domain_list, d, list);
12021    AST_LIST_UNLOCK(&domain_list);
12022 
12023    if (sipdebug)  
12024       ast_log(LOG_DEBUG, "Added local SIP domain '%s'\n", domain);
12025 
12026    return 1;
12027 }

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

add_text: Add text body to SIP message ---

Definition at line 4370 of file chan_sip.c.

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

Referenced by transmit_message_with_text().

04371 {
04372    /* XXX Convert \n's to \r\n's XXX */
04373    add_header(req, "Content-Type", "text/plain");
04374    add_header_contentLength(req, strlen(text));
04375    add_line(req, text);
04376    return 0;
04377 }

static int add_vidupdate struct sip_request req  )  [static]
 

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

Definition at line 4394 of file chan_sip.c.

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

Referenced by transmit_info_with_vidupdate().

04395 {
04396    const char *xml_is_a_huge_waste_of_space =
04397       "<?xml version=\"1.0\" encoding=\"utf-8\" ?>\r\n"
04398       " <media_control>\r\n"
04399       "  <vc_primitive>\r\n"
04400       "   <to_encoder>\r\n"
04401       "    <picture_fast_update>\r\n"
04402       "    </picture_fast_update>\r\n"
04403       "   </to_encoder>\r\n"
04404       "  </vc_primitive>\r\n"
04405       " </media_control>\r\n";
04406    add_header(req, "Content-Type", "application/media_control+xml");
04407    add_header_contentLength(req, strlen(xml_is_a_huge_waste_of_space));
04408    add_line(req, xml_is_a_huge_waste_of_space);
04409    return 0;
04410 }

static void append_date struct sip_request req  )  [static]
 

append_date: Append date to SIP message ---

Definition at line 4314 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().

04315 {
04316    char tmpdat[256];
04317    struct tm tm;
04318    time_t t;
04319 
04320    time(&t);
04321    gmtime_r(&t, &tm);
04322    strftime(tmpdat, sizeof(tmpdat), "%a, %d %b %Y %T GMT", &tm);
04323    add_header(req, "Date", tmpdat);
04324 }

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

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

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().

01141 {
01142    struct sip_history *hist, *prev;
01143    char *c;
01144 
01145    if (!recordhistory || !p)
01146       return 0;
01147    if(!(hist = malloc(sizeof(struct sip_history)))) {
01148       ast_log(LOG_WARNING, "Can't allocate memory for history\n");
01149       return 0;
01150    }
01151    memset(hist, 0, sizeof(struct sip_history));
01152    snprintf(hist->event, sizeof(hist->event), "%-15s %s", event, data);
01153    /* Trim up nicely */
01154    c = hist->event;
01155    while(*c) {
01156       if ((*c == '\r') || (*c == '\n')) {
01157          *c = '\0';
01158          break;
01159       }
01160       c++;
01161    }
01162    /* Enqueue into history */
01163    prev = p->history;
01164    if (prev) {
01165       while(prev->next)
01166          prev = prev->next;
01167       prev->next = hist;
01168    } else {
01169       p->history = hist;
01170    }
01171    return 0;
01172 }

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

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

Referenced by attempt_transfer().

10340 {
10341    if (chan && chan->_state == AST_STATE_UP) {
10342       if (chan->generatordata)
10343          ast_deactivate_generator(chan);
10344    }
10345 }

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

References ahp, ast_apply_ha(), ast_gethostbyname(), ast_inet_ntoa(), ast_log(), ast_ouraddrfor(), bindaddr, externexpire, externhost, externip, 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(), transmit_register(), and transmit_response_using_temp().

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

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

attempt_transfer: Attempt transfer of SIP call ---

Definition at line 10348 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.

10349 {
10350    int res = 0;
10351    struct ast_channel 
10352       *chana = NULL,
10353       *chanb = NULL,
10354       *bridgea = NULL,
10355       *bridgeb = NULL,
10356       *peera = NULL,
10357       *peerb = NULL,
10358       *peerc = NULL,
10359       *peerd = NULL;
10360 
10361    if (!p1->owner || !p2->owner) {
10362       ast_log(LOG_WARNING, "Transfer attempted without dual ownership?\n");
10363       return -1;
10364    }
10365    chana = p1->owner;
10366    chanb = p2->owner;
10367    bridgea = ast_bridged_channel(chana);
10368    bridgeb = ast_bridged_channel(chanb);
10369    
10370    if (bridgea) {
10371       peera = chana;
10372       peerb = chanb;
10373       peerc = bridgea;
10374       peerd = bridgeb;
10375    } else if (bridgeb) {
10376       peera = chanb;
10377       peerb = chana;
10378       peerc = bridgeb;
10379       peerd = bridgea;
10380    }
10381    
10382    if (peera && peerb && peerc && (peerb != peerc)) {
10383       ast_quiet_chan(peera);
10384       ast_quiet_chan(peerb);
10385       ast_quiet_chan(peerc);
10386       ast_quiet_chan(peerd);
10387 
10388       if (peera->cdr && peerb->cdr) {
10389          peerb->cdr = ast_cdr_append(peerb->cdr, peera->cdr);
10390       } else if (peera->cdr) {
10391          peerb->cdr = peera->cdr;
10392       }
10393       peera->cdr = NULL;
10394 
10395       if (peerb->cdr && peerc->cdr) {
10396          peerb->cdr = ast_cdr_append(peerb->cdr, peerc->cdr);
10397       } else if (peerc->cdr) {
10398          peerb->cdr = peerc->cdr;
10399       }
10400       peerc->cdr = NULL;
10401       
10402       if (ast_channel_masquerade(peerb, peerc)) {
10403          ast_log(LOG_WARNING, "Failed to masquerade %s into %s\n", peerb->name, peerc->name);
10404          res = -1;
10405       }
10406       return res;
10407    } else {
10408       ast_log(LOG_NOTICE, "Transfer attempted with no appropriate bridged calls to transfer\n");
10409       if (chana)
10410          ast_softhangup_nolock(chana, AST_SOFTHANGUP_DEV);
10411       if (chanb)
10412          ast_softhangup_nolock(chanb, AST_SOFTHANGUP_DEV);
10413       return -1;
10414    }
10415    return 0;
10416 }

static int auto_congest void *  nothing  )  [static]
 

auto_congest: Scheduled congestion on a call ---

Definition at line 2001 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.

02002 {
02003    struct sip_pvt *p = nothing;
02004    ast_mutex_lock(&p->lock);
02005    p->initid = -1;
02006    if (p->owner) {
02007       if (!ast_mutex_trylock(&p->owner->lock)) {
02008          ast_log(LOG_NOTICE, "Auto-congesting %s\n", p->owner->name);
02009          ast_queue_control(p->owner, AST_CONTROL_CONGESTION);
02010          ast_mutex_unlock(&p->owner->lock);
02011       }
02012    }
02013    ast_mutex_unlock(&p->lock);
02014    return 0;
02015 }

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

build_callid: Build SIP CALLID header ---

Definition at line 3056 of file chan_sip.c.

References thread_safe_rand().

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

03057 {
03058    int res;
03059    int val;
03060    int x;
03061    char iabuf[INET_ADDRSTRLEN];
03062    for (x=0; x<4; x++) {
03063       val = thread_safe_rand();
03064       res = snprintf(callid, len, "%08x", val);
03065       len -= res;
03066       callid += res;
03067    }
03068    if (!ast_strlen_zero(fromdomain))
03069       snprintf(callid, len, "@%s", fromdomain);
03070    else
03071    /* It's not important that we really use our right IP here... */
03072       snprintf(callid, len, "@%s", ast_inet_ntoa(iabuf, sizeof(iabuf), ourip));
03073 }

static void build_contact struct sip_pvt p  )  [static]
 

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

Definition at line 4770 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(), register_verify(), and transmit_register().

04771 {
04772    char iabuf[INET_ADDRSTRLEN];
04773 
04774    /* Construct Contact: header */
04775    if (ourport != 5060) /* Needs to be 5060, according to the RFC */
04776       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);
04777    else
04778       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));
04779 }

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 12294 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, sip_peer::fromdomain, sip_peer::fromuser, sip_peer::fullcontact, global_capability, global_flags, global_flags_page2, 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, prefs, 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, srvlookup, sip_peer::subscribecontext, sip_peer::tohost, sip_peer::username, ast_variable::value, and sip_peer::vmexten.

12295 {
12296    struct sip_peer *peer = NULL;
12297    struct ast_ha *oldha = NULL;
12298    int obproxyfound=0;
12299    int found=0;
12300    int format=0;     /* Ama flags */
12301    time_t regseconds;
12302    char *varname = NULL, *varval = NULL;
12303    struct ast_variable *tmpvar = NULL;
12304    struct ast_flags peerflags = {(0)};
12305    struct ast_flags mask = {(0)};
12306 
12307 
12308    if (!realtime)
12309       /* Note we do NOT use find_peer here, to avoid realtime recursion */
12310       /* We also use a case-sensitive comparison (unlike find_peer) so
12311          that case changes made to the peer name will be properly handled
12312          during reload
12313       */
12314       peer = ASTOBJ_CONTAINER_FIND_UNLINK_FULL(&peerl, name, name, 0, 0, strcmp);
12315 
12316    if (peer) {
12317       /* Already in the list, remove it and it will be added back (or FREE'd)  */
12318       found++;
12319    } else {
12320       peer = malloc(sizeof(*peer));
12321       if (peer) {
12322          memset(peer, 0, sizeof(*peer));
12323          if (realtime)
12324             rpeerobjs++;
12325          else
12326             speerobjs++;
12327          ASTOBJ_INIT(peer);
12328          peer->expire = -1;
12329          peer->pokeexpire = -1;
12330       } else {
12331          ast_log(LOG_WARNING, "Can't allocate SIP peer memory\n");
12332       }
12333    }
12334    /* Note that our peer HAS had its reference count incrased */
12335    if (!peer)
12336       return NULL;
12337 
12338    peer->lastmsgssent = -1;
12339    if (!found) {
12340       if (name)
12341          ast_copy_string(peer->name, name, sizeof(peer->name));
12342       peer->addr.sin_port = htons(DEFAULT_SIP_PORT);
12343       peer->addr.sin_family = AF_INET;
12344       peer->defaddr.sin_family = AF_INET;
12345    }
12346    /* If we have channel variables, remove them (reload) */
12347    if (peer->chanvars) {
12348       ast_variables_destroy(peer->chanvars);
12349       peer->chanvars = NULL;
12350    }
12351    strcpy(peer->context, default_context);
12352    strcpy(peer->subscribecontext, default_subscribecontext);
12353    strcpy(peer->vmexten, global_vmexten);
12354    strcpy(peer->language, default_language);
12355    strcpy(peer->musicclass, global_musicclass);
12356    ast_copy_flags(peer, &global_flags, SIP_USEREQPHONE);
12357    peer->secret[0] = '\0';
12358    peer->md5secret[0] = '\0';
12359    peer->cid_num[0] = '\0';
12360    peer->cid_name[0] = '\0';
12361    peer->fromdomain[0] = '\0';
12362    peer->fromuser[0] = '\0';
12363    peer->regexten[0] = '\0';
12364    peer->mailbox[0] = '\0';
12365    peer->callgroup = 0;
12366    peer->pickupgroup = 0;
12367    peer->rtpkeepalive = global_rtpkeepalive;
12368    peer->maxms = default_qualify;
12369    peer->prefs = prefs;
12370    oldha = peer->ha;
12371    peer->ha = NULL;
12372    peer->addr.sin_family = AF_INET;
12373    ast_copy_flags(peer, &global_flags, SIP_FLAGS_TO_COPY);
12374    peer->capability = global_capability;
12375    peer->rtptimeout = global_rtptimeout;
12376    peer->rtpholdtimeout = global_rtpholdtimeout;
12377    while(v) {
12378       if (handle_common_options(&peerflags, &mask, v)) {
12379          v = v->next;
12380          continue;
12381       }
12382 
12383       if (realtime && !strcasecmp(v->name, "regseconds")) {
12384          if (sscanf(v->value, "%ld", (time_t *)&regseconds) != 1)
12385             regseconds = 0;
12386       } else if (realtime && !strcasecmp(v->name, "ipaddr") && !ast_strlen_zero(v->value) ) {
12387          inet_aton(v->value, &(peer->addr.sin_addr));
12388       } else if (realtime && !strcasecmp(v->name, "name"))
12389          ast_copy_string(peer->name, v->value, sizeof(peer->name));
12390       else if (realtime && !strcasecmp(v->name, "fullcontact")) {
12391          ast_copy_string(peer->fullcontact, v->value, sizeof(peer->fullcontact));
12392          ast_set_flag((&peer->flags_page2), SIP_PAGE2_RT_FROMCONTACT);
12393       } else if (!strcasecmp(v->name, "secret")) 
12394          ast_copy_string(peer->secret, v->value, sizeof(peer->secret));
12395       else if (!strcasecmp(v->name, "md5secret")) 
12396          ast_copy_string(peer->md5secret, v->value, sizeof(peer->md5secret));
12397       else if (!strcasecmp(v->name, "auth"))
12398          peer->auth = add_realm_authentication(peer->auth, v->value, v->lineno);
12399       else if (!strcasecmp(v->name, "callerid")) {
12400          ast_callerid_split(v->value, peer->cid_name, sizeof(peer->cid_name), peer->cid_num, sizeof(peer->cid_num));
12401       } else if (!strcasecmp(v->name, "context")) {
12402          ast_copy_string(peer->context, v->value, sizeof(peer->context));
12403       } else if (!strcasecmp(v->name, "subscribecontext")) {
12404          ast_copy_string(peer->subscribecontext, v->value, sizeof(peer->subscribecontext));
12405       } else if (!strcasecmp(v->name, "fromdomain"))
12406          ast_copy_string(peer->fromdomain, v->value, sizeof(peer->fromdomain));
12407       else if (!strcasecmp(v->name, "usereqphone"))
12408          ast_set2_flag(peer, ast_true(v->value), SIP_USEREQPHONE);
12409       else if (!strcasecmp(v->name, "fromuser"))
12410          ast_copy_string(peer->fromuser, v->value, sizeof(peer->fromuser));
12411       else if (!strcasecmp(v->name, "host") || !strcasecmp(v->name, "outboundproxy")) {
12412          if (!strcasecmp(v->value, "dynamic")) {
12413             if (!strcasecmp(v->name, "outboundproxy") || obproxyfound) {
12414                ast_log(LOG_WARNING, "You can't have a dynamic outbound proxy, you big silly head at line %d.\n", v->lineno);
12415             } else {
12416                /* They'll register with us */
12417                ast_set_flag(&peer->flags_page2, SIP_PAGE2_DYNAMIC);
12418                if (!found) {
12419                   /* Initialize stuff iff we're not found, otherwise
12420                      we keep going with what we had */
12421                   memset(&peer->addr.sin_addr, 0, 4);
12422                   if (peer->addr.sin_port) {
12423                      /* If we've already got a port, make it the default rather than absolute */
12424                      peer->defaddr.sin_port = peer->addr.sin_port;
12425                      peer->addr.sin_port = 0;
12426                   }
12427                }
12428             }
12429          } else {
12430             /* Non-dynamic.  Make sure we become that way if we're not */
12431             if (peer->expire > -1)
12432                ast_sched_del(sched, peer->expire);
12433             peer->expire = -1;
12434             ast_clear_flag(&peer->flags_page2, SIP_PAGE2_DYNAMIC);   
12435             if (!obproxyfound || !strcasecmp(v->name, "outboundproxy")) {
12436                if (ast_get_ip_or_srv(&peer->addr, v->value, srvlookup ? "_sip._udp" : NULL)) {
12437                   ASTOBJ_UNREF(peer, sip_destroy_peer);
12438                   return NULL;
12439                }
12440             }
12441             if (!strcasecmp(v->name, "outboundproxy"))
12442                obproxyfound=1;
12443             else {
12444                ast_copy_string(peer->tohost, v->value, sizeof(peer->tohost));
12445                if (!peer->addr.sin_port)
12446                   peer->addr.sin_port = htons(DEFAULT_SIP_PORT);
12447             }
12448          }
12449       } else if (!strcasecmp(v->name, "defaultip")) {
12450          if (ast_get_ip(&peer->defaddr, v->value)) {
12451             ASTOBJ_UNREF(peer, sip_destroy_peer);
12452             return NULL;
12453          }
12454       } else if (!strcasecmp(v->name, "permit") || !strcasecmp(v->name, "deny")) {
12455          peer->ha = ast_append_ha(v->name, v->value, peer->ha);
12456       } else if (!strcasecmp(v->name, "port")) {
12457          if (!realtime && ast_test_flag(&peer->flags_page2, SIP_PAGE2_DYNAMIC))
12458             peer->defaddr.sin_port = htons(atoi(v->value));
12459          else
12460             peer->addr.sin_port = htons(atoi(v->value));
12461       } else if (!strcasecmp(v->name, "callingpres")) {
12462          peer->callingpres = ast_parse_caller_presentation(v->value);
12463          if (peer->callingpres == -1)
12464             peer->callingpres = atoi(v->value);
12465       } else if (!strcasecmp(v->name, "username")) {
12466          ast_copy_string(peer->username, v->value, sizeof(peer->username));
12467       } else if (!strcasecmp(v->name, "language")) {
12468          ast_copy_string(peer->language, v->value, sizeof(peer->language));
12469       } else if (!strcasecmp(v->name, "regexten")) {
12470          ast_copy_string(peer->regexten, v->value, sizeof(peer->regexten));
12471       } else if (!strcasecmp(v->name, "call-limit") || !strcasecmp(v->name, "incominglimit")) {
12472          peer->call_limit = atoi(v->value);
12473          if (peer->call_limit < 0)
12474             peer->call_limit = 0;
12475       } else if (!strcasecmp(v->name, "amaflags")) {
12476          format = ast_cdr_amaflags2int(v->value);
12477          if (format < 0) {
12478             ast_log(LOG_WARNING, "Invalid AMA Flags for peer: %s at line %d\n", v->value, v->lineno);
12479          } else {
12480             peer->amaflags = format;
12481          }
12482       } else if (!strcasecmp(v->name, "accountcode")) {
12483          ast_copy_string(peer->accountcode, v->value, sizeof(peer->accountcode));
12484       } else if (!strcasecmp(v->name, "musicclass") || !strcasecmp(v->name, "musiconhold")) {
12485          ast_copy_string(peer->musicclass, v->value, sizeof(peer->musicclass));
12486       } else if (!strcasecmp(v->name, "mailbox")) {
12487          ast_copy_string(peer->mailbox, v->value, sizeof(peer->mailbox));
12488       } else if (!strcasecmp(v->name, "vmexten")) {
12489          ast_copy_string(peer->vmexten, v->value, sizeof(peer->vmexten));
12490       } else if (!strcasecmp(v->name, "callgroup")) {
12491          peer->callgroup = ast_get_group(v->value);
12492       } else if (!strcasecmp(v->name, "pickupgroup")) {
12493          peer->pickupgroup = ast_get_group(v->value);
12494       } else if (!strcasecmp(v->name, "allow")) {
12495          ast_parse_allow_disallow(&peer->prefs, &peer->capability, v->value, 1);
12496       } else if (!strcasecmp(v->name, "disallow")) {
12497          ast_parse_allow_disallow(&peer->prefs, &peer->capability, v->value, 0);
12498       } else if (!strcasecmp(v->name, "rtptimeout")) {
12499          if ((sscanf(v->value, "%d", &peer->rtptimeout) != 1) || (peer->rtptimeout < 0)) {
12500             ast_log(LOG_WARNING, "'%s' is not a valid RTP hold time at line %d.  Using default.\n", v->value, v->lineno);
12501             peer->rtptimeout = global_rtptimeout;
12502          }
12503       } else if (!strcasecmp(v->name, "rtpholdtimeout")) {
12504          if ((sscanf(v->value, "%d", &peer->rtpholdtimeout) != 1) || (peer->rtpholdtimeout < 0)) {
12505             ast_log(LOG_WARNING, "'%s' is not a valid RTP hold time at line %d.  Using default.\n", v->value, v->lineno);
12506             peer->rtpholdtimeout = global_rtpholdtimeout;
12507          }
12508       } else if (!strcasecmp(v->name, "rtpkeepalive")) {
12509          if ((sscanf(v->value, "%d", &peer->rtpkeepalive) != 1) || (peer->rtpkeepalive < 0)) {
12510             ast_log(LOG_WARNING, "'%s' is not a valid RTP keepalive time at line %d.  Using default.\n", v->value, v->lineno);
12511             peer->rtpkeepalive = global_rtpkeepalive;
12512          }
12513       } else if (!strcasecmp(v->name, "setvar")) {
12514          /* Set peer channel variable */
12515          varname = ast_strdupa(v->value);
12516          if (varname && (varval = strchr(varname,'='))) {
12517             *varval = '\0';
12518             varval++;
12519             if ((tmpvar = ast_variable_new(varname, varval))) {
12520                tmpvar->next = peer->chanvars;
12521                peer->chanvars = tmpvar;
12522             }
12523          }
12524       } else if (!strcasecmp(v->name, "qualify")) {
12525          if (!strcasecmp(v->value, "no")) {
12526             peer->maxms = 0;
12527          } else if (!strcasecmp(v->value, "yes")) {
12528             peer->maxms = DEFAULT_MAXMS;
12529          } else if (sscanf(v->value, "%d", &peer->maxms) != 1) {
12530             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);
12531             peer->maxms = 0;
12532          }
12533       }
12534       /* else if (strcasecmp(v->name,"type"))
12535        * ast_log(LOG_WARNING, "Ignoring %s\n", v->name);
12536        */
12537       v=v->next;
12538    }
12539    if (!ast_test_flag((&global_flags_page2), SIP_PAGE2_IGNOREREGEXPIRE) && ast_test_flag(&peer->flags_page2, SIP_PAGE2_DYNAMIC) && realtime) {
12540       time_t nowtime;
12541 
12542       time(&nowtime);
12543       if ((nowtime - regseconds) > 0) {
12544          destroy_association(peer);
12545          memset(&peer->addr, 0, sizeof(peer->addr));
12546          if (option_debug)
12547             ast_log(LOG_DEBUG, "Bah, we're expired (%d/%d/%d)!\n", (int)(nowtime - regseconds), (int)regseconds, (int)nowtime);
12548       }
12549    }
12550    ast_copy_flags(peer, &peerflags, mask.flags);
12551    if (!found && ast_test_flag(&peer->flags_page2, SIP_PAGE2_DYNAMIC) && !ast_test_flag(peer, SIP_REALTIME))
12552       reg_source_db(peer);
12553    ASTOBJ_UNMARK(peer);
12554    ast_free_ha(oldha);
12555    return peer;
12556 }

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 9174 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 transmit_register(), and transmit_request_with_auth().

09175 {
09176    char a1[256];
09177    char a2[256];
09178    char a1_hash[256];
09179    char a2_hash[256];
09180    char resp[256];
09181    char resp_hash[256];
09182    char uri[256];
09183    char cnonce[80];
09184    char iabuf[INET_ADDRSTRLEN];
09185    char *username;
09186    char *secret;
09187    char *md5secret;
09188    struct sip_auth *auth = (struct sip_auth *) NULL;  /* Realm authentication */
09189 
09190    if (!ast_strlen_zero(p->domain))
09191       ast_copy_string(uri, p->domain, sizeof(uri));
09192    else if (!ast_strlen_zero(p->uri))
09193       ast_copy_string(uri, p->uri, sizeof(uri));
09194    else
09195       snprintf(uri, sizeof(uri), "sip:%s@%s",p->username, ast_inet_ntoa(iabuf, sizeof(iabuf), p->sa.sin_addr));
09196 
09197    snprintf(cnonce, sizeof(cnonce), "%08x", thread_safe_rand());
09198 
09199    /* Check if we have separate auth credentials */
09200    if ((auth = find_realm_authentication(authl, p->realm))) {
09201       username = auth->username;
09202       secret = auth->secret;
09203       md5secret = auth->md5secret;
09204       if (sipdebug)
09205          ast_log(LOG_DEBUG,"Using realm %s authentication for call %s\n", p->realm, p->callid);
09206    } else {
09207       /* No authentication, use peer or register= config */
09208       username = p->authname;
09209       secret =  p->peersecret;
09210       md5secret = p->peermd5secret;
09211    }
09212    if (ast_strlen_zero(username))   /* We have no authentication */
09213       return -1;
09214  
09215 
09216    /* Calculate SIP digest response */
09217    snprintf(a1,sizeof(a1),"%s:%s:%s", username, p->realm, secret);
09218    snprintf(a2,sizeof(a2),"%s:%s", sip_methods[method].text, uri);
09219    if (!ast_strlen_zero(md5secret))
09220       ast_copy_string(a1_hash, md5secret, sizeof(a1_hash));
09221    else
09222       ast_md5_hash(a1_hash,a1);
09223    ast_md5_hash(a2_hash,a2);
09224 
09225    p->noncecount++;
09226    if (!ast_strlen_zero(p->qop))
09227       snprintf(resp,sizeof(resp),"%s:%s:%08x:%s:%s:%s", a1_hash, p->nonce, p->noncecount, cnonce, "auth", a2_hash);
09228    else
09229       snprintf(resp,sizeof(resp),"%s:%s:%s", a1_hash, p->nonce, a2_hash);
09230    ast_md5_hash(resp_hash, resp);
09231    /* XXX We hard code our qop to "auth" for now.  XXX */
09232    if (!ast_strlen_zero(p->qop))
09233       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);
09234    else
09235       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);
09236 
09237    return 0;
09238 }

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

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

Referenced by handle_request_invite(), and handle_response_invite().

06129 {
06130    struct sip_route *thishop, *head, *tail;
06131    int start = 0;
06132    int len;
06133    char *rr, *contact, *c;
06134 
06135    /* Once a persistant route is set, don't fool with it */
06136    if (p->route && p->route_persistant) {
06137       ast_log(LOG_DEBUG, "build_route: Retaining previous route: <%s>\n", p->route->hop);
06138       return;
06139    }
06140 
06141    if (p->route) {
06142       free_old_route(p->route);
06143       p->route = NULL;
06144    }
06145    
06146    p->route_persistant = backwards;
06147    
06148    /* We build up head, then assign it to p->route when we're done */
06149    head = NULL;  tail = head;
06150    /* 1st we pass through all the hops in any Record-Route headers */
06151    for (;;) {
06152       /* Each Record-Route header */
06153       rr = __get_header(req, "Record-Route", &start);
06154       if (*rr == '\0') break;
06155       for (;;) {
06156          /* Each route entry */
06157          /* Find < */
06158          rr = strchr(rr, '<');
06159          if (!rr) break; /* No more hops */
06160          ++rr;
06161          len = strcspn(rr, ">") + 1;
06162          /* Make a struct route */
06163          thishop = malloc(sizeof(*thishop) + len);
06164          if (thishop) {
06165             ast_copy_string(thishop->hop, rr, len);
06166             ast_log(LOG_DEBUG, "build_route: Record-Route hop: <%s>\n", thishop->hop);
06167             /* Link in */
06168             if (backwards) {
06169                /* Link in at head so they end up in reverse order */
06170                thishop->next = head;
06171                head = thishop;
06172                /* If this was the first then it'll be the tail */
06173                if (!tail) tail = thishop;
06174             } else {
06175                thishop->next = NULL;
06176                /* Link in at the end */
06177                if (tail)
06178                   tail->next = thishop;
06179                else
06180                   head = thishop;
06181                tail = thishop;
06182             }
06183          }
06184          rr += len;
06185       }
06186    }
06187 
06188    /* Only append the contact if we are dealing with a strict router */
06189    if (!head || (!ast_strlen_zero(head->hop) && strstr(head->hop,";lr") == NULL) ) {
06190       /* 2nd append the Contact: if there is one */
06191       /* Can be multiple Contact headers, comma separated values - we just take the first */
06192       contact = get_header(req, "Contact");
06193       if (!ast_strlen_zero(contact)) {
06194          ast_log(LOG_DEBUG, "build_route: Contact hop: %s\n", contact);
06195          /* Look for <: delimited address */
06196          c = strchr(contact, '<');
06197          if (c) {
06198             /* Take to > */
06199             ++c;
06200             len = strcspn(c, ">") + 1;
06201          } else {
06202             /* No <> - just take the lot */
06203             c = contact;
06204             len = strlen(contact) + 1;
06205          }
06206          thishop = malloc(sizeof(*thishop) + len);
06207          if (thishop) {
06208             ast_copy_string(thishop->hop, c, len);
06209             thishop->next = NULL;
06210             /* Goes at the end */
06211             if (tail)
06212                tail->next = thishop;
06213             else
06214                head = thishop;
06215          }
06216       }
06217    }
06218 
06219    /* Store as new route */
06220    p->route = head;
06221 
06222    /* For debugging dump what we ended up with */
06223    if (sip_debug_test_pvt(p))
06224       list_route(p->route);
06225 }

static void build_rpid struct sip_pvt p  )  [static]
 

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

Definition at line 4782 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.

04783 {
04784    int send_pres_tags = 1;
04785    const char *privacy = NULL;
04786    const char *screen = NULL;
04787    char buf[256];
04788    const char *clid = default_callerid;
04789    const char *clin = NULL;
04790    char iabuf[INET_ADDRSTRLEN];
04791    const char *fromdomain;
04792 
04793    if (p->rpid || p->rpid_from)
04794       return;
04795 
04796    if (p->owner && p->owner->cid.cid_num)
04797       clid = p->owner->cid.cid_num;
04798    if (p->owner && p->owner->cid.cid_name)
04799       clin = p->owner->cid.cid_name;
04800    if (ast_strlen_zero(clin))
04801       clin = clid;
04802 
04803    switch (p->callingpres) {
04804    case AST_PRES_ALLOWED_USER_NUMBER_NOT_SCREENED:
04805       privacy = "off";
04806       screen = "no";
04807       break;
04808    case AST_PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN:
04809       privacy = "off";
04810       screen = "yes";
04811       break;
04812    case AST_PRES_ALLOWED_USER_NUMBER_FAILED_SCREEN:
04813       privacy = "off";
04814       screen = "no";
04815       break;
04816    case AST_PRES_ALLOWED_NETWORK_NUMBER:
04817       privacy = "off";
04818       screen = "yes";
04819       break;
04820    case AST_PRES_PROHIB_USER_NUMBER_NOT_SCREENED:
04821       privacy = "full";
04822       screen = "no";
04823       break;
04824    case AST_PRES_PROHIB_USER_NUMBER_PASSED_SCREEN:
04825       privacy = "full";
04826       screen = "yes";
04827       break;
04828    case AST_PRES_PROHIB_USER_NUMBER_FAILED_SCREEN:
04829       privacy = "full";
04830       screen = "no";
04831       break;
04832    case AST_PRES_PROHIB_NETWORK_NUMBER:
04833       privacy = "full";
04834       screen = "yes";
04835       break;
04836    case AST_PRES_NUMBER_NOT_AVAILABLE:
04837       send_pres_tags = 0;
04838       break;
04839    default:
04840       ast_log(LOG_WARNING, "Unsupported callingpres (%d)\n", p->callingpres);
04841       if ((p->callingpres & AST_PRES_RESTRICTION) != AST_PRES_ALLOWED)
04842          privacy = "full";
04843       else
04844          privacy = "off";
04845       screen = "no";
04846       break;
04847    }
04848    
04849    fromdomain = ast_strlen_zero(p->fromdomain) ? ast_inet_ntoa(iabuf, sizeof(iabuf), p->ourip) : p->fromdomain;
04850 
04851    snprintf(buf, sizeof(buf), "\"%s\" <sip:%s@%s>", clin, clid, fromdomain);
04852    if (send_pres_tags)
04853       snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), ";privacy=%s;screen=%s", privacy, screen);
04854    p->rpid = strdup(buf);
04855 
04856    snprintf(buf, sizeof(buf), "\"%s\" <sip:%s@%s>;tag=%s", clin,
04857        ast_strlen_zero(p->fromuser) ? clid : p->fromuser,
04858        fromdomain, p->tag);
04859    p->rpid_from = strdup(buf);
04860 }

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 12161 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_flags, global_musicclass, handle_common_options(), ast_variable::lineno, LOG_WARNING, malloc, ast_variable::name, ast_variable::next, prefs, SIP_FLAGS_TO_COPY, suserobjs, user, and ast_variable::value.

12162 {
12163    struct sip_user *user;
12164    int format;
12165    struct ast_ha *oldha = NULL;
12166    char *varname = NULL, *varval = NULL;
12167    struct ast_variable *tmpvar = NULL;
12168    struct ast_flags userflags = {(0)};
12169    struct ast_flags mask = {(0)};
12170 
12171 
12172    user = (struct sip_user *)malloc(sizeof(struct sip_user));
12173    if (!user) {
12174       return NULL;
12175    }
12176    memset(user, 0, sizeof(struct sip_user));
12177    suserobjs++;
12178    ASTOBJ_INIT(user);
12179    ast_copy_string(user->name, name, sizeof(user->name));
12180    oldha = user->ha;
12181    user->ha = NULL;
12182    ast_copy_flags(user, &global_flags, SIP_FLAGS_TO_COPY);
12183    user->capability = global_capability;
12184    user->prefs = prefs;
12185    /* set default context */
12186    strcpy(user->context, default_context);
12187    strcpy(user->language, default_language);
12188    strcpy(user->musicclass, global_musicclass);
12189    while(v) {
12190       if (handle_common_options(&userflags, &mask, v)) {
12191          v = v->next;
12192          continue;
12193       }
12194 
12195       if (!strcasecmp(v->name, "context")) {
12196          ast_copy_string(user->context, v->value, sizeof(user->context));
12197       } else if (!strcasecmp(v->name, "subscribecontext")) {
12198          ast_copy_string(user->subscribecontext, v->value, sizeof(user->subscribecontext));
12199       } else if (!strcasecmp(v->name, "setvar")) {
12200          varname = ast_strdupa(v->value);
12201          if (varname && (varval = strchr(varname,'='))) {
12202             *varval = '\0';
12203             varval++;
12204             if ((tmpvar = ast_variable_new(varname, varval))) {
12205                tmpvar->next = user->chanvars;
12206                user->chanvars = tmpvar;
12207             }
12208          }
12209       } else if (!strcasecmp(v->name, "permit") ||
12210                !strcasecmp(v->name, "deny")) {
12211          user->ha = ast_append_ha(v->name, v->value, user->ha);
12212       } else if (!strcasecmp(v->name, "secret")) {
12213          ast_copy_string(user->secret, v->value, sizeof(user->secret)); 
12214       } else if (!strcasecmp(v->name, "md5secret")) {
12215          ast_copy_string(user->md5secret, v->value, sizeof(user->md5secret));
12216       } else if (!strcasecmp(v->name, "callerid")) {
12217          ast_callerid_split(v->value, user->cid_name, sizeof(user->cid_name), user->cid_num, sizeof(user->cid_num));
12218       } else if (!strcasecmp(v->name, "callgroup")) {
12219          user->callgroup = ast_get_group(v->value);
12220       } else if (!strcasecmp(v->name, "pickupgroup")) {
12221          user->pickupgroup = ast_get_group(v->value);
12222       } else if (!strcasecmp(v->name, "language")) {
12223          ast_copy_string(user->language, v->value, sizeof(user->language));
12224       } else if (!strcasecmp(v->name, "musicclass") || !strcasecmp(v->name, "musiconhold")) {
12225          ast_copy_string(user->musicclass, v->value, sizeof(user->musicclass));
12226       } else if (!strcasecmp(v->name, "accountcode")) {
12227          ast_copy_string(user->accountcode, v->value, sizeof(user->accountcode));
12228       } else if (!strcasecmp(v->name, "call-limit") || !strcasecmp(v->name, "incominglimit")) {
12229          user->call_limit = atoi(v->value);
12230          if (user->call_limit < 0)
12231             user->call_limit = 0;
12232       } else if (!strcasecmp(v->name, "amaflags")) {
12233          format = ast_cdr_amaflags2int(v->value);
12234          if (format < 0) {
12235             ast_log(LOG_WARNING, "Invalid AMA Flags: %s at line %d\n", v->value, v->lineno);
12236          } else {
12237             user->amaflags = format;
12238          }
12239       } else if (!strcasecmp(v->name, "allow")) {
12240          ast_parse_allow_disallow(&user->prefs, &user->capability, v->value, 1);
12241       } else if (!strcasecmp(v->name, "disallow")) {
12242          ast_parse_allow_disallow(&user->prefs, &user->capability, v->value, 0);
12243       } else if (!strcasecmp(v->name, "callingpres")) {
12244          user->callingpres = ast_parse_caller_presentation(v->value);
12245          if (user->callingpres == -1)
12246             user->callingpres = atoi(v->value);
12247       }
12248       /*else if (strcasecmp(v->name,"type"))
12249        * ast_log(LOG_WARNING, "Ignoring %s\n", v->name);
12250        */
12251       v = v->next;
12252    }
12253    ast_copy_flags(user, &userflags, mask.flags);
12254    ast_free_ha(oldha);
12255    return user;
12256 }

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

References ast_inet_ntoa(), ast_test_flag, sip_pvt::branch, sip_pvt::ourip, 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(), transmit_register(), and transmit_response_using_temp().

01093 {
01094    char iabuf[INET_ADDRSTRLEN];
01095 
01096    /* z9hG4bK is a magic cookie.  See RFC 3261 section 8.1.1.7 */
01097    if (ast_test_flag(p, SIP_NAT) & SIP_NAT_RFC3581)
01098       snprintf(buf, len, "SIP/2.0/UDP %s:%d;branch=z9hG4bK%08x;rport", ast_inet_ntoa(iabuf, sizeof(iabuf), p->ourip), ourport, p->branch);
01099    else /* Work around buggy UNIDEN UIP200 firmware */
01100       snprintf(buf, len, "SIP/2.0/UDP %s:%d;branch=z9hG4bK%08x", ast_inet_ntoa(iabuf, sizeof(iabuf), p->ourip), ourport, p->branch);
01101 }

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 6471 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_verbose, 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().

06472 {
06473    struct sip_pvt *p = data;
06474 
06475    switch(state) {
06476    case AST_EXTENSION_DEACTIVATED:  /* Retry after a while */
06477    case AST_EXTENSION_REMOVED:   /* Extension is gone */
06478       if (p->autokillid > -1)
06479          sip_cancel_destroy(p);  /* Remove subscription expiry for renewals */
06480       sip_scheddestroy(p, 15000);   /* Delete subscription in 15 secs */
06481       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);
06482       p->stateid = -1;
06483       p->subscribed = NONE;
06484       append_history(p, "Subscribestatus", state == AST_EXTENSION_REMOVED ? "HintRemoved" : "Deactivated");
06485       break;
06486    default: /* Tell user */
06487       p->laststate = state;
06488       break;
06489    }
06490    transmit_state_notify(p, state, 1, 1);
06491 
06492    if (option_verbose > 1)
06493       ast_verbose(VERBOSE_PREFIX_1 "Extension Changed %s new state %s for Notify User %s\n", exten, ast_extension_state2str(state), p->username);
06494    return 0;
06495 }

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

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

06247 {
06248    int res = -1;
06249    char *response = "407 Proxy Authentication Required";
06250    char *reqheader = "Proxy-Authorization";
06251    char *respheader = "Proxy-Authenticate";
06252    char *authtoken;
06253 #ifdef OSP_SUPPORT
06254    char *osptoken;
06255 #endif
06256    /* Always OK if no secret */
06257    if (ast_strlen_zero(secret) && ast_strlen_zero(md5secret)
06258 #ifdef OSP_SUPPORT
06259        && !ast_test_flag(p, SIP_OSPAUTH)
06260        && global_allowguest != 2
06261 #endif
06262       )
06263       return 0;
06264    if (sipmethod == SIP_REGISTER || sipmethod == SIP_SUBSCRIBE) {
06265       /* On a REGISTER, we have to use 401 and its family of headers instead of 407 and its family
06266          of headers -- GO SIP!  Whoo hoo!  Two things that do the same thing but are used in
06267          different circumstances! What a surprise. */
06268       response = "401 Unauthorized";
06269       reqheader = "Authorization";
06270       respheader = "WWW-Authenticate";
06271    }
06272 #ifdef OSP_SUPPORT
06273    else {
06274       ast_log (LOG_DEBUG, "Checking OSP Authentication!\n");
06275       osptoken = get_header (req, "P-OSP-Auth-Token");
06276       switch (ast_test_flag (p, SIP_OSPAUTH)) {
06277          case SIP_OSPAUTH_NO:
06278             break;
06279          case SIP_OSPAUTH_GATEWAY:
06280             if (ast_strlen_zero (osptoken)) {
06281                if (ast_strlen_zero (secret) && ast_strlen_zero (md5secret)) {
06282                   return (0);
06283                }
06284             }
06285             else {
06286                return (check_osptoken (p, osptoken));
06287             }
06288             break;
06289          case SIP_OSPAUTH_PROXY:
06290             if (ast_strlen_zero (osptoken)) {
06291                return (0);
06292             } 
06293             else {
06294                return (check_osptoken (p, osptoken));
06295             }
06296             break;
06297          case SIP_OSPAUTH_EXCLUSIVE:
06298             if (ast_strlen_zero (osptoken)) {
06299                return (-1);
06300             }
06301             else {
06302                return (check_osptoken (p, osptoken));
06303             }
06304             break;
06305          default:
06306             return (-1);
06307       }
06308    }
06309 #endif   
06310    authtoken =  get_header(req, reqheader);  
06311    if (ignore && !ast_strlen_zero(randdata) && ast_strlen_zero(authtoken)) {
06312       /* This is a retransmitted invite/register/etc, don't reconstruct authentication
06313          information */
06314       if (!ast_strlen_zero(randdata)) {
06315          if (!reliable) {
06316             /* Resend message if this was NOT a reliable delivery.   Otherwise the
06317                retransmission should get it */
06318             transmit_response_with_auth(p, response, req, randdata, reliable, respheader, 0);
06319             /* Schedule auto destroy in 15 seconds */
06320             sip_scheddestroy(p, 15000);
06321          }
06322          res = 1;
06323       }
06324    } else if (ast_strlen_zero(randdata) || ast_strlen_zero(authtoken)) {
06325       snprintf(randdata, randlen, "%08x", thread_safe_rand());
06326       transmit_response_with_auth(p, response, req, randdata, reliable, respheader, 0);
06327       /* Schedule auto destroy in 15 seconds */
06328       sip_scheddestroy(p, 15000);
06329       res = 1;
06330    } else {
06331       /* Whoever came up with the authentication section of SIP can suck my %&#$&* for not putting
06332          an example in the spec of just what it is you're doing a hash on. */
06333       char a1[256];
06334       char a2[256];
06335       char a1_hash[256];
06336       char a2_hash[256];
06337       char resp[256];
06338       char resp_hash[256]="";
06339       char tmp[256];
06340       char *c;
06341       char *z;
06342       char *ua_hash ="";
06343       char *resp_uri ="";
06344       char *nonce = "";
06345       char *digestusername = "";
06346       int  wrongnonce = 0;
06347       char *usednonce = randdata;
06348 
06349       /* Find their response among the mess that we'r sent for comparison */
06350       ast_copy_string(tmp, authtoken, sizeof(tmp));
06351       c = tmp;
06352 
06353       while(c) {
06354          c = ast_skip_blanks(c);
06355          if (!*c)
06356             break;
06357          if (!strncasecmp(c, "response=", strlen("response="))) {
06358             c+= strlen("response=");
06359             if ((*c == '\"')) {
06360                ua_hash=++c;
06361                if ((c = strchr(c,'\"')))
06362                   *c = '\0';
06363 
06364             } else {
06365                ua_hash=c;
06366                if ((c = strchr(c,',')))
06367                   *c = '\0';
06368             }
06369 
06370          } else if (!strncasecmp(c, "uri=", strlen("uri="))) {
06371             c+= strlen("uri=");
06372             if ((*c == '\"')) {
06373                resp_uri=++c;
06374                if ((c = strchr(c,'\"')))
06375                   *c = '\0';
06376             } else {
06377                resp_uri=c;
06378                if ((c = strchr(c,',')))
06379                   *c = '\0';
06380             }
06381 
06382          } else if (!strncasecmp(c, "username=", strlen("username="))) {
06383             c+= strlen("username=");
06384             if ((*c == '\"')) {
06385                digestusername=++c;
06386                if((c = strchr(c,'\"')))
06387                   *c = '\0';
06388             } else {
06389                digestusername=c;
06390                if((c = strchr(c,',')))
06391                   *c = '\0';
06392             }
06393          } else if (!strncasecmp(c, "nonce=", strlen("nonce="))) {
06394             c+= strlen("nonce=");
06395             if ((*c == '\"')) {
06396                nonce=++c;
06397                if ((c = strchr(c,'\"')))
06398                   *c = '\0';
06399             } else {
06400                nonce=c;
06401                if ((c = strchr(c,',')))
06402                   *c = '\0';
06403             }
06404 
06405          } else
06406             if ((z = strchr(c,' ')) || (z = strchr(c,','))) c=z;
06407          if (c)
06408             c++;
06409       }
06410       /* Verify that digest username matches  the username we auth as */
06411       if (strcmp(username, digestusername)) {
06412          /* Oops, we're trying something here */
06413          return -2;
06414       }
06415 
06416       /* Verify nonce from request matches our nonce.  If not, send 401 with new nonce */
06417       if (strncasecmp(randdata, nonce, randlen)) {
06418          wrongnonce = 1;
06419          usednonce = nonce;
06420       }
06421 
06422       snprintf(a1, sizeof(a1), "%s:%s:%s", username, global_realm, secret);
06423 
06424       if (!ast_strlen_zero(resp_uri))
06425          snprintf(a2, sizeof(a2), "%s:%s", sip_methods[sipmethod].text, resp_uri);
06426       else
06427          snprintf(a2, sizeof(a2), "%s:%s", sip_methods[sipmethod].text, uri);
06428 
06429       if (!ast_strlen_zero(md5secret))
06430          snprintf(a1_hash, sizeof(a1_hash), "%s", md5secret);
06431       else
06432          ast_md5_hash(a1_hash, a1);
06433 
06434       ast_md5_hash(a2_hash, a2);
06435 
06436       snprintf(resp, sizeof(resp), "%s:%s:%s", a1_hash, usednonce, a2_hash);
06437       ast_md5_hash(resp_hash, resp);
06438 
06439       if (wrongnonce) {
06440 
06441          snprintf(randdata, randlen, "%08x", thread_safe_rand());
06442          if (ua_hash && !strncasecmp(ua_hash, resp_hash, strlen(resp_hash))) {
06443             if (sipdebug)
06444                ast_log(LOG_NOTICE, "stale nonce received from '%s'\n", get_header(req, "To"));
06445             /* We got working auth token, based on stale nonce . */
06446             transmit_response_with_auth(p, response, req, randdata, reliable, respheader, 1);
06447          } else {
06448             /* Everything was wrong, so give the device one more try with a new challenge */
06449             if (sipdebug)
06450                ast_log(LOG_NOTICE, "Bad authentication received from '%s'\n", get_header(req, "To"));
06451             transmit_response_with_auth(p, response, req, randdata, reliable, respheader, 0);
06452          }
06453 
06454          /* Schedule auto destroy in 15 seconds */
06455          sip_scheddestroy(p, 15000);
06456          return 1;
06457       } 
06458       /* resp_hash now has the expected response, compare the two */
06459       if (ua_hash && !strncasecmp(ua_hash, resp_hash, strlen(resp_hash))) {
06460          /* Auth is OK */
06461          res = 0;
06462       }
06463    }
06464    /* Failure */
06465    return res;
06466 }

static void check_pendings struct sip_pvt p  )  [static]
 

check_pendings: Check pending actions on SIP call ---

Definition at line 9612 of file chan_sip.c.

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

Referenced by handle_request(), and handle_response_invite().

09613 {
09614    if (ast_test_flag(p, SIP_PENDINGBYE)) {
09615       /* if we can't BYE, then this is really a pending CANCEL */
09616       if (!ast_test_flag(p, SIP_CAN_BYE))
09617          transmit_request_with_auth(p, SIP_CANCEL, p->ocseq, 1, 0);
09618          /* Actually don't destroy us yet, wait for the 487 on our original 
09619             INVITE, but do set an autodestruct just in case we never get it. */
09620       else 
09621          transmit_request_with_auth(p, SIP_BYE, 0, 1, 1);
09622       ast_clear_flag(p, SIP_PENDINGBYE);  
09623       sip_scheddestroy(p, 32000);
09624    } else if (ast_test_flag(p, SIP_NEEDREINVITE)) {
09625       ast_log(LOG_DEBUG, "Sending pending reinvite on '%s'\n", p->callid);
09626       /* Didn't get to reinvite yet, so do it now */
09627       transmit_reinvite_with_sdp(p);
09628       ast_clear_flag(p, SIP_NEEDREINVITE);   
09629    }
09630 }

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 12030 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().

12031 {
12032    struct domain *d;
12033    int result = 0;
12034 
12035    AST_LIST_LOCK(&domain_list);
12036    AST_LIST_TRAVERSE(&domain_list, d, list) {
12037       if (strcasecmp(d->domain, domain))
12038          continue;
12039 
12040       if (len && !ast_strlen_zero(d->context))
12041          ast_copy_string(context, d->context, len);
12042       
12043       result = 1;
12044       break;
12045    }
12046    AST_LIST_UNLOCK(&domain_list);
12047 
12048    return result;
12049 }

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

References check_user_full().

Referenced by handle_request_invite().

07397 {
07398    return check_user_full(p, req, sipmethod, uri, reliable, sin, ignore, NULL, 0);
07399 }

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

References sip_peer::accountcode, sip_peer::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_strdupa, ast_strlen_zero(), ast_test_flag, ast_uri_decode(), ast_variable_new(), ast_verbose(), ASTOBJ_UNREF, build_contact(), sip_peer::call_limit, sip_peer::callgroup, sip_peer::callingpres, sip_pvt::callingpres, sip_peer::capability, sip_peer::chanvars, check_auth(), sip_peer::cid_name, sip_pvt::cid_name, sip_peer::cid_num, sip_pvt::cid_num, sip_peer::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, global_flags, sip_peer::language, sip_peer::lastms, LOG_DEBUG, LOG_NOTICE, sip_peer::mailbox, sip_peer::maxms, sip_peer::md5secret, ast_variable::next, sip_pvt::our_contact, pedanticsipchecking, sip_pvt::peermd5secret, sip_pvt::peersecret, sip_peer::pickupgroup, sip_peer::prefs, sip_pvt::randdata, sip_pvt::recv, sip_pvt::rtp, sip_peer::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_peer::subscribecontext, sip_pvt::subscribecontext, t, sip_pvt::timer_t1, user, sip_peer::username, and sip_pvt::vrtp.

Referenced by check_user(), and handle_request_subscribe().

07129 {
07130    struct sip_user *user = NULL;
07131    struct sip_peer *peer;
07132    char *of, from[256], *c;
07133    char *rpid,rpid_num[50];
07134    char iabuf[INET_ADDRSTRLEN];
07135    int res = 0;
07136    char *t;
07137    char calleridname[50];
07138    int debug=sip_debug_test_addr(sin);
07139    struct ast_variable *tmpvar = NULL, *v = NULL;
07140    char *uri2 = ast_strdupa(uri);
07141 
07142    /* Terminate URI */
07143    t = uri2;
07144    while(*t && (*t > 32) && (*t != ';'))
07145       t++;
07146    *t = '\0';
07147    of = get_header(req, "From");
07148    if (pedanticsipchecking)
07149       ast_uri_decode(of);
07150 
07151    ast_copy_string(from, of, sizeof(from));
07152    
07153    memset(calleridname,0,sizeof(calleridname));
07154    get_calleridname(from, calleridname, sizeof(calleridname));
07155    if (calleridname[0])
07156       ast_copy_string(p->cid_name, calleridname, sizeof(p->cid_name));
07157 
07158    rpid = get_header(req, "Remote-Party-ID");
07159    memset(rpid_num, 0, sizeof(rpid_num));
07160    if (!ast_strlen_zero(rpid)) 
07161       p->callingpres = get_rpid_num(rpid, rpid_num, sizeof(rpid_num));
07162 
07163    of = get_in_brackets(from);
07164    if (ast_strlen_zero(p->exten)) {
07165       t = uri2;
07166       if (!strncmp(t, "sip:", 4))
07167          t+= 4;
07168       ast_copy_string(p->exten, t, sizeof(p->exten));
07169       t = strchr(p->exten, '@');
07170       if (t)
07171          *t = '\0';
07172       if (ast_strlen_zero(p->our_contact))
07173          build_contact(p);
07174    }
07175    /* save the URI part of the From header */
07176    ast_copy_string(p->from, of, sizeof(p->from));
07177    if (strncmp(of, "sip:", 4)) {
07178       ast_log(LOG_NOTICE, "From address missing 'sip:', using it anyway\n");
07179    } else
07180       of += 4;
07181    /* Get just the username part */
07182    if ((c = strchr(of, '@'))) {
07183       *c = '\0';
07184       if ((c = strchr(of, ':')))
07185          *c = '\0';
07186       ast_copy_string(p->cid_num, of, sizeof(p->cid_num));
07187       ast_shrink_phone_number(p->cid_num);
07188    }
07189    if (ast_strlen_zero(of))
07190       return 0;
07191 
07192    if (!mailbox)  /* If it's a mailbox SUBSCRIBE, don't check users */
07193       user = find_user(of, 1);
07194 
07195    /* Find user based on user name in the from header */
07196    if (user && ast_apply_ha(user->ha, sin)) {
07197       ast_copy_flags(p, user, SIP_FLAGS_TO_COPY);
07198       /* copy channel vars */
07199       for (v = user->chanvars ; v ; v = v->next) {
07200          if ((tmpvar = ast_variable_new(v->name, v->value))) {
07201             tmpvar->next = p->chanvars; 
07202             p->chanvars = tmpvar;
07203          }
07204       }
07205       p->prefs = user->prefs;
07206       /* replace callerid if rpid found, and not restricted */
07207       if (!ast_strlen_zero(rpid_num) && ast_test_flag(p, SIP_TRUSTRPID)) {
07208          if (*calleridname)
07209             ast_copy_string(p->cid_name, calleridname, sizeof(p->cid_name));
07210          ast_copy_string(p->cid_num, rpid_num, sizeof(p->cid_num));
07211          ast_shrink_phone_number(p->cid_num);
07212       }
07213 
07214       if (p->rtp) {
07215          ast_log(LOG_DEBUG, "Setting NAT on RTP to %d\n", (ast_test_flag(p, SIP_NAT) & SIP_NAT_ROUTE));
07216          ast_rtp_setnat(p->rtp, (ast_test_flag(p, SIP_NAT) & SIP_NAT_ROUTE));
07217       }
07218       if (p->vrtp) {
07219          ast_log(LOG_DEBUG, "Setting NAT on VRTP to %d\n", (ast_test_flag(p, SIP_NAT) & SIP_NAT_ROUTE));
07220          ast_rtp_setnat(p->vrtp, (ast_test_flag(p, SIP_NAT) & SIP_NAT_ROUTE));
07221       }
07222       if (!(res = check_auth(p, req, p->randdata, sizeof(p->randdata), user->name, user->secret, user->md5secret, sipmethod, uri2, reliable, ignore))) {
07223          sip_cancel_destroy(p);
07224          ast_copy_flags(p, user, SIP_FLAGS_TO_COPY);
07225          /* Copy SIP extensions profile from INVITE */
07226          if (p->sipoptions)
07227             user->sipoptions = p->sipoptions;
07228 
07229          /* If we have a call limit, set flag */
07230          if (user->call_limit)
07231             ast_set_flag(p, SIP_CALL_LIMIT);
07232          if (!ast_strlen_zero(user->context))
07233             ast_copy_string(p->context, user->context, sizeof(p->context));
07234          if (!ast_strlen_zero(user->cid_num) && !ast_strlen_zero(p->cid_num))  {
07235             ast_copy_string(p->cid_num, user->cid_num, sizeof(p->cid_num));
07236             ast_shrink_phone_number(p->cid_num);
07237          }
07238          if (!ast_strlen_zero(user->cid_name) && !ast_strlen_zero(p->cid_num)) 
07239             ast_copy_string(p->cid_name, user->cid_name, sizeof(p->cid_name));
07240          ast_copy_string(p->peername, user->name, sizeof(p->peername));
07241          ast_copy_string(p->username, user->name, sizeof(p->username));
07242          ast_copy_string(p->peersecret, user->secret, sizeof(p->peersecret));
07243          ast_copy_string(p->subscribecontext, user->subscribecontext, sizeof(p->subscribecontext));
07244          ast_copy_string(p->peermd5secret, user->md5secret, sizeof(p->peermd5secret));
07245          ast_copy_string(p->accountcode, user->accountcode, sizeof(p->accountcode));
07246          ast_copy_string(p->language, user->language, sizeof(p->language));
07247          ast_copy_string(p->musicclass, user->musicclass, sizeof(p->musicclass));
07248          p->amaflags = user->amaflags;
07249          p->callgroup = user->callgroup;
07250          p->pickupgroup = user->pickupgroup;
07251          p->callingpres = user->callingpres;
07252          p->capability = user->capability;
07253          p->jointcapability = user->capability;
07254          if (p->peercapability)
07255             p->jointcapability &= p->peercapability;
07256          if ((ast_test_flag(p, SIP_DTMF) == SIP_DTMF_RFC2833) || (ast_test_flag(p, SIP_DTMF) == SIP_DTMF_AUTO))
07257             p->noncodeccapability |= AST_RTP_DTMF;
07258          else
07259             p->noncodeccapability &= ~AST_RTP_DTMF;
07260       }
07261       if (user && debug)
07262          ast_verbose("Found user '%s'\n", user->name);
07263    } else {
07264       if (user) {
07265          if (!mailbox && debug)
07266             ast_verbose("Found user '%s', but fails host access\n", user->name);
07267          ASTOBJ_UNREF(user,sip_destroy_user);
07268       }
07269       user = NULL;
07270    }
07271 
07272    if (!user) {
07273       /* If we didn't find a user match, check for peers */
07274       if (sipmethod == SIP_SUBSCRIBE)
07275          /* For subscribes, match on peer name only */
07276          peer = find_peer(of, NULL, 1);
07277       else
07278          /* Look for peer based on the IP address we received data from */
07279          /* If peer is registered from this IP address or have this as a default
07280             IP address, this call is from the peer 
07281          */
07282          peer = find_peer(NULL, &p->recv, 1);
07283 
07284       if (peer) {
07285          if (debug)
07286             ast_verbose("Found peer '%s'\n", peer->name);
07287          /* Take the peer */
07288          ast_copy_flags(p, peer, SIP_FLAGS_TO_COPY);
07289 
07290          /* Copy SIP extensions profile to peer */
07291          if (p->sipoptions)
07292             peer->sipoptions = p->sipoptions;
07293 
07294          /* replace callerid if rpid found, and not restricted */
07295          if (!ast_strlen_zero(rpid_num) && ast_test_flag(p, SIP_TRUSTRPID)) {
07296             if (*calleridname)
07297                ast_copy_string(p->cid_name, calleridname, sizeof(p->cid_name));
07298             ast_copy_string(p->cid_num, rpid_num, sizeof(p->cid_num));
07299             ast_shrink_phone_number(p->cid_num);
07300          }
07301          if (p->rtp) {
07302             ast_log(LOG_DEBUG, "Setting NAT on RTP to %d\n", (ast_test_flag(p, SIP_NAT) & SIP_NAT_ROUTE));
07303             ast_rtp_setnat(p->rtp, (ast_test_flag(p, SIP_NAT) & SIP_NAT_ROUTE));
07304          }
07305          if (p->vrtp) {
07306             ast_log(LOG_DEBUG, "Setting NAT on VRTP to %d\n", (ast_test_flag(p, SIP_NAT) & SIP_NAT_ROUTE));
07307             ast_rtp_setnat(p->vrtp, (ast_test_flag(p, SIP_NAT) & SIP_NAT_ROUTE));
07308          }
07309          ast_copy_string(p->peersecret, peer->secret, sizeof(p->peersecret));
07310          p->peersecret[sizeof(p->peersecret)-1] = '\0';
07311          ast_copy_string(p->subscribecontext, peer->subscribecontext, sizeof(p->subscribecontext));
07312          ast_copy_string(p->peermd5secret, peer->md5secret, sizeof(p->peermd5secret));
07313          p->peermd5secret[sizeof(p->peermd5secret)-1] = '\0';
07314          p->callingpres = peer->callingpres;
07315          if (peer->maxms && peer->lastms)
07316             p->timer_t1 = peer->lastms;
07317          if (ast_test_flag(peer, SIP_INSECURE_INVITE)) {
07318             /* Pretend there is no required authentication */
07319             p->peersecret[0] = '\0';
07320             p->peermd5secret[0] = '\0';
07321          }
07322          if (!(res = check_auth(p, req, p->randdata, sizeof(p->randdata), peer->name, p->peersecret, p->peermd5secret, sipmethod, uri2, reliable, ignore))) {
07323             ast_copy_flags(p, peer, SIP_FLAGS_TO_COPY);
07324             /* If we have a call limit, set flag */
07325             if (peer->call_limit)
07326                ast_set_flag(p, SIP_CALL_LIMIT);
07327             ast_copy_string(p->peername, peer->name, sizeof(p->peername));
07328             ast_copy_string(p->authname, peer->name, sizeof(p->authname));
07329             /* copy channel vars */
07330             for (v = peer->chanvars ; v ; v = v->next) {
07331                if ((tmpvar = ast_variable_new(v->name, v->value))) {
07332                   tmpvar->next = p->chanvars; 
07333                   p->chanvars = tmpvar;
07334                }
07335             }
07336             if (mailbox)
07337                snprintf(mailbox, mailboxlen, ",%s,", peer->mailbox);
07338             if (!ast_strlen_zero(peer->username)) {
07339                ast_copy_string(p->username, peer->username, sizeof(p->username));
07340                /* Use the default username for authentication on outbound calls */
07341                ast_copy_string(p->authname, peer->username, sizeof(p->authname));
07342             }
07343             if (!ast_strlen_zero(peer->cid_num) && !ast_strlen_zero(p->cid_num))  {
07344                ast_copy_string(p->cid_num, peer->cid_num, sizeof(p->cid_num));
07345                ast_shrink_phone_number(p->cid_num);
07346             }
07347             if (!ast_strlen_zero(peer->cid_name) && !ast_strlen_zero(p->cid_name)) 
07348                ast_copy_string(p->cid_name, peer->cid_name, sizeof(p->cid_name));
07349             ast_copy_string(p->fullcontact, peer->fullcontact, sizeof(p->fullcontact));
07350             if (!ast_strlen_zero(peer->context))
07351                ast_copy_string(p->context, peer->context, sizeof(p->context));
07352             ast_copy_string(p->peersecret, peer->secret, sizeof(p->peersecret));
07353             ast_copy_string(p->peermd5secret, peer->md5secret, sizeof(p->peermd5secret));
07354             ast_copy_string(p->language, peer->language, sizeof(p->language));
07355             ast_copy_string(p->accountcode, peer->accountcode, sizeof(p->accountcode));
07356             p->amaflags = peer->amaflags;
07357             p->callgroup = peer->callgroup;
07358             p->pickupgroup = peer->pickupgroup;
07359             p->capability = peer->capability;
07360             p->prefs = peer->prefs;
07361             p->jointcapability = peer->capability;
07362             if (p->peercapability)
07363                p->jointcapability &= p->peercapability;
07364             if ((ast_test_flag(p, SIP_DTMF) == SIP_DTMF_RFC2833) || (ast_test_flag(p, SIP_DTMF) == SIP_DTMF_AUTO))
07365                p->noncodeccapability |= AST_RTP_DTMF;
07366             else
07367                p->noncodeccapability &= ~AST_RTP_DTMF;
07368          }
07369          ASTOBJ_UNREF(peer,sip_destroy_peer);
07370       } else { 
07371          if (debug)
07372             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));
07373 
07374          /* do we allow guests? */
07375          if (!global_allowguest) {
07376             if (global_alwaysauthreject)
07377                res = -4; /* reject with fake authorization request */
07378             else
07379                res = -1; /* we don't want any guests, authentication will fail */
07380 #ifdef OSP_SUPPORT         
07381          } else if (global_allowguest == 2) {
07382             ast_copy_flags(p, &global_flags, SIP_OSPAUTH);
07383             res = check_auth(p, req, p->randdata, sizeof(p->randdata), "", "", "", sipmethod, uri2, reliable, ignore); 
07384 #endif
07385          }
07386       }
07387 
07388    }
07389 
07390    if (user)
07391       ASTOBJ_UNREF(user,sip_destroy_user);
07392    return res;
07393 }

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

References ahp, ast_gethostbyname(), ast_inet_ntoa(), ast_log(), ast_set_flag, ast_test_flag, ast_verbose(), DEFAULT_SIP_PORT, get_header(), hp, LOG_WARNING, sip_pvt::sa, 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().

07005 {
07006    char via[256];
07007    char iabuf[INET_ADDRSTRLEN];
07008    char *c, *pt;
07009    struct hostent *hp;
07010    struct ast_hostent ahp;
07011 
07012    ast_copy_string(via, get_header(req, "Via"), sizeof(via));
07013 
07014    /* Check for rport */
07015    c = strstr(via, ";rport");
07016    if (c && (c[6] != '=')) /* rport query, not answer */
07017       ast_set_flag(p, SIP_NAT_ROUTE);
07018 
07019    c = strchr(via, ';');
07020    if (c) 
07021       *c = '\0';
07022 
07023    c = strchr(via, ' ');
07024    if (c) {
07025       *c = '\0';
07026       c = ast_skip_blanks(c+1);
07027       if (strcasecmp(via, "SIP/2.0/UDP")) {
07028          ast_log(LOG_WARNING, "Don't know how to respond via '%s'\n", via);
07029          return -1;
07030       }
07031       pt = strchr(c, ':');
07032       if (pt)
07033          *pt++ = '\0';  /* remember port pointer */
07034       hp = ast_gethostbyname(c, &ahp);
07035       if (!hp) {
07036          ast_log(LOG_WARNING, "'%s' is not a valid host\n", c);
07037          return -1;
07038       }
07039       memset(&p->sa, 0, sizeof(p->sa));
07040       p->sa.sin_family = AF_INET;
07041       memcpy(&p->sa.sin_addr, hp->h_addr, sizeof(p->sa.sin_addr));
07042       p->sa.sin_port = htons(pt ? atoi(pt) : DEFAULT_SIP_PORT);
07043 
07044       if (sip_debug_test_pvt(p)) {
07045          c = (ast_test_flag(p, SIP_NAT) & SIP_NAT_ROUTE) ? "NAT" : "non-NAT";
07046          ast_verbose("Sending to %s : %d (%s)\n", ast_inet_ntoa(iabuf, sizeof(iabuf), p->sa.sin_addr), ntohs(p->sa.sin_port), c);
07047       }
07048    }
07049    return 0;
07050 }

static int clear_realm_authentication struct sip_auth authlist  )  [static]
 

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

Definition at line 12131 of file chan_sip.c.

References free, and sip_auth::next.

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

12132 {
12133    struct sip_auth *a = authlist;
12134    struct sip_auth *b;
12135 
12136    while (a) {
12137       b = a;
12138       a = a->next;
12139       free(b);
12140    }
12141 
12142    return 1;
12143 }

static void clear_sip_domains void   )  [static]
 

clear_sip_domains: Clear our domain list (at reload)

Definition at line 12052 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().

12053 {
12054    struct domain *d;
12055 
12056    AST_LIST_LOCK(&domain_list);
12057    while ((d = AST_LIST_REMOVE_HEAD(&domain_list, list)))
12058       free(d);
12059    AST_LIST_UNLOCK(&domain_list);
12060 }

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

References complete_sip_peer().

08557 {
08558    if (pos == 3)
08559       return complete_sip_peer(word, state, 0);
08560 
08561    return NULL;
08562 }

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

complete_sip_peer: Do completion on peer name ---

Definition at line 8527 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().

08528 {
08529    char *result = NULL;
08530    int wordlen = strlen(word);
08531    int which = 0;
08532 
08533    ASTOBJ_CONTAINER_TRAVERSE(&peerl, !result, do {
08534       /* locking of the object is not required because only the name and flags are being compared */
08535       if (!strncasecmp(word, iterator->name, wordlen)) {
08536          if (flags2 && !ast_test_flag((&iterator->flags_page2), flags2))
08537             continue;
08538          if (++which > state) {
08539             result = strdup(iterator->name);
08540          }
08541       }
08542    } while(0) );
08543    return result;
08544 }

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

References complete_sip_peer(), and SIP_PAGE2_RTCACHEFRIENDS.

08628 {
08629    if (pos == 4)
08630       return complete_sip_peer(word, state, SIP_PAGE2_RTCACHEFRIENDS);
08631    return NULL;
08632 }

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

References complete_sip_user(), and SIP_PAGE2_RTCACHEFRIENDS.

08636 {
08637    if (pos == 4)
08638       return complete_sip_user(word, state, SIP_PAGE2_RTCACHEFRIENDS);
08639 
08640    return NULL;
08641 }

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

References complete_sip_peer().

08548 {
08549    if (pos == 3)
08550       return complete_sip_peer(word, state, 0);
08551 
08552    return NULL;
08553 }

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

References complete_sip_user().

08586 {
08587    if (pos == 3)
08588       return complete_sip_user(word, state, 0);
08589 
08590    return NULL;
08591 }

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

complete_sip_user: Do completion on user name ---

Definition at line 8565 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().

08566 {
08567    char *result = NULL;
08568    int wordlen = strlen(word);
08569    int which = 0;
08570 
08571    ASTOBJ_CONTAINER_TRAVERSE(&userl, !result, do {
08572       /* locking of the object is not required because only the name and flags are being compared */
08573       if (!strncasecmp(word, iterator->name, wordlen)) {
08574          if (flags2 && !ast_test_flag(&(iterator->flags_page2), flags2))
08575             continue;
08576          if (++which > state) {
08577             result = strdup(iterator->name);
08578          }
08579       }
08580    } while(0) );
08581    return result;
08582 }

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

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

08506 {
08507    int which=0;
08508    struct sip_pvt *cur;
08509    char *c = NULL;
08510 
08511    ast_mutex_lock(&iflock);
08512    cur = iflist;
08513    while(cur) {
08514       if (!strncasecmp(word, cur->callid, strlen(word))) {
08515          if (++which > state) {
08516             c = strdup(cur->callid);
08517             break;
08518          }
08519       }
08520       cur = cur->next;
08521    }
08522    ast_mutex_unlock(&iflock);
08523    return c;
08524 }

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

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

Definition at line 8594 of file chan_sip.c.

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

08595 {
08596    char *c = NULL;
08597 
08598    if (pos == 2) {
08599       int which = 0;
08600       char *cat;
08601 
08602       /* do completion for notify type */
08603 
08604       if (!notify_types)
08605          return NULL;
08606       
08607       cat = ast_category_browse(notify_types, NULL);
08608       while(cat) {
08609          if (!strncasecmp(word, cat, strlen(word))) {
08610             if (++which > state) {
08611                c = strdup(cat);
08612                break;
08613             }
08614          }
08615          cat = ast_category_browse(notify_types, cat);
08616       }
08617       return c;
08618    }
08619 
08620    if (pos > 2)
08621       return complete_sip_peer(word, state, 0);
08622 
08623    return NULL;
08624 }

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

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

Referenced by respprep().

03887 {
03888    char *tmp;
03889    int start = 0;
03890    int copied = 0;
03891    for (;;) {
03892       tmp = __get_header(orig, field, &start);
03893       if (!ast_strlen_zero(tmp)) {
03894          /* Add what we're responding to */
03895          add_header(req, field, tmp);
03896          copied++;
03897       } else
03898          break;
03899    }
03900    return copied ? 0 : -1;
03901 }

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

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

Referenced by reqprep(), and respprep().

03874 {
03875    char *tmp;
03876    tmp = get_header(orig, field);
03877    if (!ast_strlen_zero(tmp)) {
03878       /* Add what we're responding to */
03879       return add_header(req, field, tmp);
03880    }
03881    ast_log(LOG_NOTICE, "No field '%s' present to copy\n", field);
03882    return -1;
03883 }

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 4643 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().

04644 {
04645    long offset;
04646    int x;
04647    offset = ((void *)dst) - ((void *)src);
04648    /* First copy stuff */
04649    memcpy(dst, src, sizeof(*dst));
04650    /* Now fix pointer arithmetic */
04651    for (x=0; x < src->headers; x++)
04652       dst->header[x] += offset;
04653    for (x=0; x < src->lines; x++)
04654       dst->line[x] += offset;
04655 }

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

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

Referenced by respprep().

03910 {
03911    char tmp[256], *oh, *end;
03912    int start = 0;
03913    int copied = 0;
03914    char iabuf[INET_ADDRSTRLEN];
03915 
03916    for (;;) {
03917       oh = __get_header(orig, field, &start);
03918       if (!ast_strlen_zero(oh)) {
03919          if (!copied) { /* Only check for empty rport in topmost via header */
03920             char *rport;
03921             char new[256];
03922 
03923             /* Find ;rport;  (empty request) */
03924             rport = strstr(oh, ";rport");
03925             if (rport && *(rport+6) == '=') 
03926                rport = NULL;     /* We already have a parameter to rport */
03927 
03928             if (rport && (ast_test_flag(p, SIP_NAT) == SIP_NAT_ALWAYS)) {
03929                /* We need to add received port - rport */
03930                ast_copy_string(tmp, oh, sizeof(tmp));
03931 
03932                rport = strstr(tmp, ";rport");
03933 
03934                if (rport) {
03935                   end = strchr(rport + 1, ';');
03936                   if (end)
03937                      memmove(rport, end, strlen(end) + 1);
03938                   else
03939                      *rport = '\0';
03940                }
03941 
03942                /* Add rport to first VIA header if requested */
03943                /* Whoo hoo!  Now we can indicate port address translation too!  Just
03944                      another RFC (RFC3581). I'll leave the original comments in for
03945                      posterity.  */
03946                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));
03947             } else {
03948                /* We should *always* add a received to the topmost via */
03949                snprintf(new, sizeof(new), "%s;received=%s", oh, ast_inet_ntoa(iabuf, sizeof(iabuf), p->recv.sin_addr));
03950             }
03951             add_header(req, field, new);
03952          } else {
03953             /* Add the following via headers untouched */
03954             add_header(req, field, oh);
03955          }
03956          copied++;
03957       } else
03958          break;
03959    }
03960    if (!copied) {
03961       ast_log(LOG_NOTICE, "No header field '%s' present to copy\n", field);
03962       return -1;
03963    }
03964    return 0;
03965 }

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

References ahp, 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(), sip_pvt::timer_t1, and sip_pvt::tohost.

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

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 1861 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().

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

char* description void   ) 
 

Provides a description of the module.

Returns:
a short description of your module

Definition at line 13581 of file chan_sip.c.

References desc.

13582 {
13583    return (char *) desc;
13584 }

static void destroy_association struct sip_peer peer  )  [static]
 

Definition at line 5765 of file chan_sip.c.

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

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

05766 {
05767    if (!ast_test_flag((&global_flags_page2), SIP_PAGE2_IGNOREREGEXPIRE)) {
05768       if (ast_test_flag(&(peer->flags_page2), SIP_PAGE2_RT_FROMCONTACT)) {
05769          ast_update_realtime("sippeers", "name", peer->name, "fullcontact", "", "ipaddr", "", "port", "", "regseconds", "0", "username", "", NULL);
05770       } else {
05771          ast_db_del("SIP/Registry", peer->name);
05772       }
05773    }
05774 }

static int determine_firstline_parts struct sip_request req  )  [static]
 

determine_firstline_parts: parse first line of incoming SIP request

Definition at line 4678 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().

04679 {
04680    char *e, *cmd;
04681    int len;
04682   
04683    cmd = ast_skip_blanks(req->header[0]);
04684    if (!*cmd)
04685       return -1;
04686    req->rlPart1 = cmd;
04687    e = ast_skip_nonblanks(cmd);
04688    /* Get the command */
04689    if (*e)
04690       *e++ = '\0';
04691    e = ast_skip_blanks(e);
04692    if ( !*e )
04693       return -1;
04694 
04695    if ( !strcasecmp(cmd, "SIP/2.0") ) {
04696       /* We have a response */
04697       req->rlPart2 = e;
04698       len = strlen( req->rlPart2 );
04699       if ( len < 2 ) { 
04700          return -1;
04701       }
04702       ast_trim_blanks(e);
04703    } else {
04704       /* We have a request */
04705       if ( *e == '<' ) { 
04706          e++;
04707          if ( !*e ) { 
04708             return -1; 
04709          }  
04710       }
04711       req->rlPart2 = e; /* URI */
04712       if ( ( e= strrchr( req->rlPart2, 'S' ) ) == NULL ) {
04713          return -1;
04714       }
04715       /* XXX maybe trim_blanks() ? */
04716       while( isspace( *(--e) ) ) {}
04717       if ( *e == '>' ) {
04718          *e = '\0';
04719       } else {
04720          *(++e)= '\0';
04721       }
04722    }
04723    return 1;
04724 }

static void* do_monitor void *  data  )  [static]
 

do_monitor: The SIP monitoring thread ---

Definition at line 11478 of file chan_sip.c.

References __sip_destroy(), ast_channel::_state, ast_io_add(), ast_io_change(), 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_DEV, ast_softhangup_nolock(), AST_STATE_UP, ast_strlen_zero(), ast_test_flag, ast_verbose(), ASTOBJ_CONTAINER_TRAVERSE, ASTOBJ_REF, global_mwitime, iflist, io, 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_do_reload(), SIP_NEEDDESTROY, sip_reloading, sipsock, sipsock_read(), sipsock_read_id, t, and VERBOSE_PREFIX_1.

11479 {
11480    int res;
11481    struct sip_pvt *sip;
11482    struct sip_peer *peer = NULL;
11483    time_t t;
11484    int fastrestart =0;
11485    int lastpeernum = -1;
11486    int curpeernum;
11487    int reloading;
11488 
11489    /* Add an I/O event to our UDP socket */
11490    if (sipsock > -1) 
11491       sipsock_read_id = ast_io_add(io, sipsock, sipsock_read, AST_IO_IN, NULL);
11492    
11493    /* This thread monitors all the frame relay interfaces which are not yet in use
11494       (and thus do not have a separate thread) indefinitely */
11495    /* From here on out, we die whenever asked */
11496    for(;;) {
11497       /* Check for a reload request */
11498       ast_mutex_lock(&sip_reload_lock);
11499       reloading = sip_reloading;
11500       sip_reloading = 0;
11501       ast_mutex_unlock(&sip_reload_lock);
11502       if (reloading) {
11503          if (option_verbose > 0)
11504             ast_verbose(VERBOSE_PREFIX_1 "Reloading SIP\n");
11505          sip_do_reload();
11506 
11507          /* Change the I/O fd of our UDP socket */
11508          if (sipsock > -1)
11509             sipsock_read_id = ast_io_change(io, sipsock_read_id, sipsock, NULL, 0, NULL);
11510       }
11511       /* Check for interfaces needing to be killed */
11512       ast_mutex_lock(&iflock);
11513 restartsearch:    
11514       time(&t);
11515       sip = iflist;
11516       /* don't scan the interface list if it hasn't been a reasonable period
11517          of time since the last time we did it (when MWI is being sent, we can
11518          get back to this point every millisecond or less)
11519       */
11520       while(!fastrestart && sip) {
11521          ast_mutex_lock(&sip->lock);
11522          if (sip->rtp && sip->owner && (sip->owner->_state == AST_STATE_UP) && !sip->redirip.sin_addr.s_addr) {
11523             if (sip->lastrtptx && sip->rtpkeepalive && t > sip->lastrtptx + sip->rtpkeepalive) {
11524                /* Need to send an empty RTP packet */
11525                time(&sip->lastrtptx);
11526                ast_rtp_sendcng(sip->rtp, 0);
11527             }
11528             if (sip->lastrtprx && (sip->rtptimeout || sip->rtpholdtimeout) && t > sip->lastrtprx + sip->rtptimeout) {
11529                /* Might be a timeout now -- see if we're on hold */
11530                struct sockaddr_in sin;
11531                ast_rtp_get_peer(sip->rtp, &sin);
11532                if (sin.sin_addr.s_addr || 
11533                      (sip->rtpholdtimeout && 
11534                        (t > sip->lastrtprx + sip->rtpholdtimeout))) {
11535                   /* Needs a hangup */
11536                   if (sip->rtptimeout) {
11537                      while(sip->owner && ast_mutex_trylock(&sip->owner->lock)) {
11538                         ast_mutex_unlock(&sip->lock);
11539                         usleep(1);
11540                         ast_mutex_lock(&sip->lock);
11541                      }
11542                      if (sip->owner) {
11543                         ast_log(LOG_NOTICE, "Disconnecting call '%s' for lack of RTP activity in %ld seconds\n", sip->owner->name, (long)(t - sip->lastrtprx));
11544                         /* Issue a softhangup */
11545                         ast_softhangup_nolock(sip->owner, AST_SOFTHANGUP_DEV);
11546                         ast_mutex_unlock(&sip->owner->lock);
11547                         /* forget the timeouts for this call, since a hangup
11548                            has already been requested and we don't want to
11549                            repeatedly request hangups
11550                         */
11551                         sip->rtptimeout = 0;
11552                         sip->rtpholdtimeout = 0;
11553                      }
11554                   }
11555                }
11556             }
11557          }
11558          if (ast_test_flag(sip, SIP_NEEDDESTROY) && !sip->packets && !sip->owner) {
11559             ast_mutex_unlock(&sip->lock);
11560             __sip_destroy(sip, 1);
11561             goto restartsearch;
11562          }
11563          ast_mutex_unlock(&sip->lock);
11564          sip = sip->next;
11565       }
11566       ast_mutex_unlock(&iflock);
11567       /* Don't let anybody kill us right away.  Nobody should lock the interface list
11568          and wait for the monitor list, but the other way around is okay. */
11569       ast_mutex_lock(&monlock);
11570       /* Lock the network interface */
11571       ast_mutex_lock(&netlock);
11572       /* Okay, now that we know what to do, release the network lock */
11573       ast_mutex_unlock(&netlock);
11574       /* And from now on, we're okay to be killed, so release the monitor lock as well */
11575       ast_mutex_unlock(&monlock);
11576       pthread_testcancel();
11577       /* Wait for sched or io */
11578       res = ast_sched_wait(sched);
11579       if ((res < 0) || (res > 1000))
11580          res = 1000;
11581       /* If we might need to send more mailboxes, don't wait long at all.*/
11582       if (fastrestart)
11583          res = 1;
11584       res = ast_io_wait(io, res);
11585       if (res > 20)
11586          ast_log(LOG_DEBUG, "chan_sip: ast_io_wait ran %d all at once\n", res);
11587       ast_mutex_lock(&monlock);
11588       if (res >= 0)  {
11589          res = ast_sched_runq(sched);
11590          if (res >= 20)
11591             ast_log(LOG_DEBUG, "chan_sip: ast_sched_runq ran %d all at once\n", res);
11592       }
11593 
11594       /* needs work to send mwi to realtime peers */
11595       time(&t);
11596       fastrestart = 0;
11597       curpeernum = 0;
11598       peer = NULL;
11599       ASTOBJ_CONTAINER_TRAVERSE(&peerl, !peer, do {
11600          if ((curpeernum > lastpeernum) && !ast_strlen_zero(iterator->mailbox) && ((t - iterator->lastmsgcheck) > global_mwitime)) {
11601             fastrestart = 1;
11602             lastpeernum = curpeernum;
11603             peer = ASTOBJ_REF(iterator);
11604          };
11605          curpeernum++;
11606       } while (0)
11607       );
11608       if (peer) {
11609          ASTOBJ_WRLOCK(peer);
11610          sip_send_mwi_to_peer(peer);
11611          ASTOBJ_UNLOCK(peer);
11612          ASTOBJ_UNREF(peer,sip_destroy_peer);
11613       } else {
11614          /* Reset where we come from */
11615          lastpeernum = -1;
11616       }
11617       ast_mutex_unlock(&monlock);
11618    }
11619    /* Never reached */
11620    return NULL;
11621    
11622 }

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 9067 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().

09068 {
09069    char digest[1024];
09070 
09071    if (!p->options) {
09072       p->options = calloc(1, sizeof(*p->options));
09073       if (!p->options) {
09074          ast_log(LOG_ERROR, "Out of memory\n");
09075          return -2;
09076       }
09077    }
09078 
09079    p->authtries++;
09080    if (option_debug > 1)
09081       ast_log(LOG_DEBUG, "Auth attempt %d on %s\n", p->authtries, sip_methods[sipmethod].text);
09082    memset(digest, 0, sizeof(digest));
09083    if (reply_digest(p, req, header, sipmethod, digest, sizeof(digest) )) {
09084       /* No way to authenticate */
09085       return -1;
09086    }
09087    /* Now we have a reply digest */
09088    p->options->auth = digest;
09089    p->options->authheader = respheader;
09090    return transmit_invite(p, sipmethod, sipmethod == SIP_INVITE, init); 
09091 }

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 9043 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().

09044 {
09045    char digest[1024];
09046    p->authtries++;
09047    memset(digest,0,sizeof(digest));
09048    if (reply_digest(p, req, header, SIP_REGISTER, digest, sizeof(digest))) {
09049       /* There's nothing to use for authentication */
09050       /* No digest challenge in request */
09051       if (sip_debug_test_pvt(p) && p->registry)
09052          ast_verbose("No authentication challenge, sending blank registration to domain/host name %s\n", p->registry->hostname);
09053          /* No old challenge */
09054       return -1;
09055    }
09056    if (recordhistory) {
09057       char tmp[80];
09058       snprintf(tmp, sizeof(tmp), "Try: %d", p->authtries);
09059       append_history(p, "RegistryAuth", tmp);
09060    }
09061    if (sip_debug_test_pvt(p) && p->registry)
09062       ast_verbose("Responding to challenge, registration to domain/host name %s\n", p->registry->hostname);
09063    return transmit_register(p->registry, SIP_REGISTER, digest, respheader); 
09064 }

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

Definition at line 7986 of file chan_sip.c.

References SIP_DOMAIN_AUTO, and SIP_DOMAIN_CONFIG.

Referenced by sip_show_domains().

07987 {
07988    switch (mode) {
07989    case SIP_DOMAIN_AUTO:
07990       return "[Automatic]";
07991    case SIP_DOMAIN_CONFIG:
07992       return "[Configured]";
07993    }
07994 
07995    return "";
07996 }

static const char* dtmfmode2str int  mode  )  [static]
 

dtmfmode2str: Convert DTMF mode to printable string ---

Definition at line 7794 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().

07795 {
07796    switch (mode) {
07797    case SIP_DTMF_RFC2833:
07798       return "rfc2833";
07799    case SIP_DTMF_INFO:
07800       return "info";
07801    case SIP_DTMF_INBAND:
07802       return "inband";
07803    case SIP_DTMF_AUTO:
07804       return "auto";
07805    }
07806    return "<error>";
07807 }

static int expire_register void *  data  )  [static]
 

expire_register: Expire registration of SIP peer ---

Definition at line 5777 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().

05778 {
05779    struct sip_peer *peer = data;
05780    
05781    if (!peer)     /* Hmmm. We have no peer. Weird. */
05782       return 0;
05783 
05784    memset(&peer->addr, 0, sizeof(peer->addr));
05785 
05786    destroy_association(peer);
05787    
05788    manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: SIP/%s\r\nPeerStatus: Unregistered\r\nCause: Expired\r\n", peer->name);
05789    register_peer_exten(peer, 0); /* Remove regexten */
05790    peer->expire = -1;
05791    ast_device_state_changed("SIP/%s", peer->name);
05792 
05793    /* Do we need to release this peer from memory? 
05794       Only for realtime peers and autocreated peers
05795    */
05796    if (ast_test_flag(peer, SIP_SELFDESTRUCT) || ast_test_flag((&peer->flags_page2), SIP_PAGE2_RTAUTOCLEAR)) {
05797       peer = ASTOBJ_CONTAINER_UNLINK(&peerl, peer);   /* Remove from peer list */
05798       ASTOBJ_UNREF(peer, sip_destroy_peer);
05799    }
05800 
05801    return 0;
05802 }

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

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

Definition at line 4756 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().

04757 {
04758    char stripped[256];
04759    char *c, *n;
04760    ast_copy_string(stripped, get_header(req, "Contact"), sizeof(stripped));
04761    c = get_in_brackets(stripped);
04762    n = strchr(c, ';');
04763    if (n)
04764       *n = '\0';
04765    if (!ast_strlen_zero(c))
04766       ast_copy_string(p->uri, c, sizeof(p->uri));
04767 }

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

Definition at line 2942 of file chan_sip.c.

References aliases.

02943 {
02944    int x;
02945    for (x=0;x<sizeof(aliases) / sizeof(aliases[0]); x++) 
02946       if (!strcasecmp(aliases[x].fullname, name))
02947          return aliases[x].shortname;
02948    return _default;
02949 }

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 3174 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, sip_pvt::theirtag, and transmit_response_using_temp().

Referenced by sipsock_read().

03175 {
03176    struct sip_pvt *p = NULL;
03177    char *callid;
03178    char *tag = "";
03179    char totag[128];
03180    char fromtag[128];
03181 
03182    callid = get_header(req, "Call-ID");
03183 
03184    if (pedanticsipchecking) {
03185       /* In principle Call-ID's uniquely identify a call, but with a forking SIP proxy
03186          we need more to identify a branch - so we have to check branch, from
03187          and to tags to identify a call leg.
03188          For Asterisk to behave correctly, you need to turn on pedanticsipchecking
03189          in sip.conf
03190          */
03191       if (gettag(req, "To", totag, sizeof(totag)))
03192          ast_set_flag(req, SIP_PKT_WITH_TOTAG); /* Used in handle_request/response */
03193       gettag(req, "From", fromtag, sizeof(fromtag));
03194 
03195       if (req->method == SIP_RESPONSE)
03196          tag = totag;
03197       else
03198          tag = fromtag;
03199          
03200 
03201       if (option_debug > 4 )
03202          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);
03203    }
03204 
03205    ast_mutex_lock(&iflock);
03206    p = iflist;
03207    while(p) {  /* In pedantic, we do not want packets with bad syntax to be connected to a PVT */
03208       int found = 0;
03209       if (req->method == SIP_REGISTER)
03210          found = (!strcmp(p->callid, callid));
03211       else 
03212          found = (!strcmp(p->callid, callid) && 
03213          (!pedanticsipchecking || !tag || ast_strlen_zero(p->theirtag) || !strcmp(p->theirtag, tag))) ;
03214 
03215       if (option_debug > 4)
03216          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);
03217 
03218       /* If we get a new request within an existing to-tag - check the to tag as well */
03219       if (pedanticsipchecking && found  && req->method != SIP_RESPONSE) {  /* SIP Request */
03220          if (p->tag[0] == '\0' && totag[0]) {
03221             /* We have no to tag, but they have. Wrong dialog */
03222             found = 0;
03223          } else if (totag[0]) {        /* Both have tags, compare them */
03224             if (strcmp(totag, p->tag)) {
03225                found = 0;     /* This is not our packet */
03226             }
03227          }
03228          if (!found && option_debug > 4)
03229             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);
03230       }
03231 
03232 
03233       if (found) {
03234          /* Found the call */
03235          ast_mutex_lock(&p->lock);
03236          ast_mutex_unlock(&iflock);
03237          return p;
03238       }
03239       p = p->next;
03240    }
03241    ast_mutex_unlock(&iflock);
03242 
03243    /* If this is a response and we have ignoring of out of dialog responses turned on, then drop it */
03244    if (!sip_methods[intended_method].can_create) {
03245       if (intended_method != SIP_RESPONSE)
03246          transmit_response_using_temp(callid, sin, 1, intended_method, req, "481 Call leg/transaction does not exist");
03247    } else {
03248       p = sip_alloc(callid, sin, 1, intended_method);
03249       if (p)
03250          ast_mutex_lock(&p->lock);
03251    }
03252 
03253    return p;
03254 }

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

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

01769 {
01770    struct sip_peer *p = NULL;
01771 
01772    if (peer)
01773       p = ASTOBJ_CONTAINER_FIND(&peerl,peer);
01774    else
01775       p = ASTOBJ_CONTAINER_FIND_FULL(&peerl,sin,name,sip_addr_hashfunc,1,sip_addrcmp);
01776 
01777    if (!p && realtime) {
01778       p = realtime_peer(peer, sin);
01779    }
01780 
01781    return p;
01782 }

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

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

Referenced by build_reply_digest().

12147 {
12148    struct sip_auth *a = authlist;   /* First entry in auth list */
12149 
12150    while (a) {
12151       if (!strcasecmp(a->realm, realm)){
12152          break;
12153       }
12154       a = a->next;
12155    }
12156    
12157    return a;
12158 }

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 3454 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().

03455 {
03456    char *content_type;
03457    char *search;
03458    char *boundary;
03459    unsigned int x;
03460 
03461    content_type = get_header(req, "Content-Type");
03462 
03463    /* if the body contains only SDP, this is easy */
03464    if (!strcasecmp(content_type, "application/sdp")) {
03465       req->sdp_start = 0;
03466       req->sdp_end = req->lines;
03467       return 1;
03468    }
03469 
03470    /* if it's not multipart/mixed, there cannot be an SDP */
03471    if (strncasecmp(content_type, "multipart/mixed", 15))
03472       return 0;
03473 
03474    /* if there is no boundary marker, it's invalid */
03475    if (!(search = strcasestr(content_type, ";boundary=")))
03476       return 0;
03477 
03478    search += 10;
03479 
03480    if (ast_strlen_zero(search))
03481       return 0;
03482 
03483    /* make a duplicate of the string, with two extra characters
03484       at the beginning */
03485    boundary = ast_strdupa(search - 2);
03486    boundary[0] = boundary[1] = '-';
03487 
03488    /* search for the boundary marker, but stop when there are not enough
03489       lines left for it, the Content-Type header and at least one line of
03490       body */
03491    for (x = 0; x < (req->lines - 2); x++) {
03492       if (!strncasecmp(req->line[x], boundary, strlen(boundary)) &&
03493           !strcasecmp(req->line[x + 1], "Content-Type: application/sdp")) {
03494          req->sdp_start = x + 2;
03495          /* search for the end of the body part */
03496          for ( ; x < req->lines; x++) {
03497             if (!strncasecmp(req->line[x], boundary, strlen(boundary)))
03498                break;
03499          }
03500          req->sdp_end = x;
03501          return 1;
03502       }
03503    }
03504 
03505    return 0;
03506 }

static int find_sip_method char *  msg  )  [static]
 

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

References ast_strlen_zero(), sip_methods, and text.

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

00989 {
00990    int i, res = 0;
00991    
00992    if (ast_strlen_zero(msg))
00993       return 0;
00994 
00995    for (i = 1; (i < (sizeof(sip_methods) / sizeof(sip_methods[0]))) && !res; i++) {
00996       if (!strcasecmp(sip_methods[i].text, msg)) 
00997          res = sip_methods[i].id;
00998    }
00999    return res;
01000 }

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

find_subscription_type: Find subscription type in array

Definition at line 8430 of file chan_sip.c.

References subscription_types, and type.

Referenced by transmit_state_notify().

08430                                                                                                 {
08431    int i;
08432 
08433    for (i = 1; (i < (sizeof(subscription_types) / sizeof(subscription_types[0]))); i++) {
08434       if (subscription_types[i].type == subtype) {
08435          return &subscription_types[i];
08436       }
08437    }
08438    return &subscription_types[0];
08439 }

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

References ASTOBJ_CONTAINER_FIND, realtime_user(), and userl.

01851 {
01852    struct sip_user *u = NULL;
01853    u = ASTOBJ_CONTAINER_FIND(&userl,name);
01854    if (!u && realtime) {
01855       u = realtime_user(name);
01856    }
01857    return u;
01858 }

static void free_old_route struct sip_route route  )  [static]
 

free_old_route: Remove route from route list ---

Definition at line 6104 of file chan_sip.c.

References free, and sip_route::next.

Referenced by __sip_destroy(), and build_route().

06105 {
06106    struct sip_route *next;
06107    while (route) {
06108       next = route->next;
06109       free(route);
06110       route = next;
06111    }
06112 }

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

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

09385 {
09386    if (ast_strlen_zero(data)) {
09387       ast_log(LOG_WARNING, "CHECKSIPDOMAIN requires an argument - A domain name\n");
09388       return buf;
09389    }
09390    if (check_sip_domain(data, NULL, 0))
09391       ast_copy_string(buf, data, len);
09392    else
09393       buf[0] = '\0';
09394    return buf;
09395 }

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

09338 {
09339    struct sip_pvt *p;
09340    char *content;
09341    
09342    if (!data) {
09343       ast_log(LOG_WARNING, "This function requires a header name.\n");
09344       return NULL;
09345    }
09346 
09347    ast_mutex_lock(&chan->lock);
09348    if (chan->type != channeltype) {
09349       ast_log(LOG_WARNING, "This function can only be used on SIP channels.\n");
09350       ast_mutex_unlock(&chan->lock);
09351       return NULL;
09352    }
09353 
09354    p = chan->tech_pvt;
09355 
09356    /* If there is no private structure, this channel is no longer alive */
09357    if (!p) {
09358       ast_mutex_unlock(&chan->lock);
09359       return NULL;
09360    }
09361 
09362    content = get_header(&p->initreq, data);
09363 
09364    if (ast_strlen_zero(content)) {
09365       ast_mutex_unlock(&chan->lock);
09366       return NULL;
09367    }
09368 
09369    ast_copy_string(buf, content, len);
09370    ast_mutex_unlock(&chan->lock);
09371 
09372    return buf;
09373 }

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

09512 {
09513    struct sip_pvt *p;
09514    char iabuf[INET_ADDRSTRLEN];
09515 
09516    *buf = 0;
09517    
09518    if (!data) {
09519       ast_log(LOG_WARNING, "This function requires a parameter name.\n");
09520       return NULL;
09521    }
09522 
09523    ast_mutex_lock(&chan->lock);
09524    if (chan->type != channeltype) {
09525       ast_log(LOG_WARNING, "This function can only be used on SIP channels.\n");
09526       ast_mutex_unlock(&chan->lock);
09527       return NULL;
09528    }
09529 
09530 /*    ast_verbose("function_sipchaninfo_read: %s\n", data); */
09531    p = chan->tech_pvt;
09532 
09533    /* If there is no private structure, this channel is no longer alive */
09534    if (!p) {
09535       ast_mutex_unlock(&chan->lock);
09536       return NULL;
09537    }
09538 
09539    if (!strcasecmp(data, "peerip")) {
09540       ast_copy_string(buf, p->sa.sin_addr.s_addr ? ast_inet_ntoa(iabuf, sizeof(iabuf), p->sa.sin_addr) : "", len);
09541    } else  if (!strcasecmp(data, "recvip")) {
09542       ast_copy_string(buf, p->recv.sin_addr.s_addr ? ast_inet_ntoa(iabuf, sizeof(iabuf), p->recv.sin_addr) : "", len);
09543    } else  if (!strcasecmp(data, "from")) {
09544       ast_copy_string(buf, p->from, len);
09545    } else  if (!strcasecmp(data, "uri")) {
09546       ast_copy_string(buf, p->uri, len);
09547    } else  if (!strcasecmp(data, "useragent")) {
09548       ast_copy_string(buf, p->useragent, len);
09549    } else  if (!strcasecmp(data, "peername")) {
09550       ast_copy_string(buf, p->peername, len);
09551    } else {
09552       ast_mutex_unlock(&chan->lock);
09553       return NULL;
09554    }
09555    ast_mutex_unlock(&chan->lock);
09556 
09557    return buf;
09558 }

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

09411 {
09412    char *ret = NULL;
09413    struct sip_peer *peer;
09414    char *peername, *colname;
09415    char iabuf[INET_ADDRSTRLEN];
09416 
09417    if (!(peername = ast_strdupa(data))) {
09418       ast_log(LOG_ERROR, "Memory Error!\n");
09419       return ret;
09420    }
09421 
09422    if ((colname = strchr(peername, ':'))) {
09423       *colname = '\0';
09424       colname++;
09425    } else {
09426       colname = "ip";
09427    }
09428    if (!(peer = find_peer(peername, NULL, 1)))
09429       return ret;
09430 
09431    if (!strcasecmp(colname, "ip")) {
09432       ast_copy_string(buf, peer->addr.sin_addr.s_addr ? ast_inet_ntoa(iabuf, sizeof(iabuf), peer->addr.sin_addr) : "", len);
09433    } else  if (!strcasecmp(colname, "status")) {
09434       peer_status(peer, buf, len);
09435    } else  if (!strcasecmp(colname, "language")) {
09436       ast_copy_string(buf, peer->language, len);
09437    } else  if (!strcasecmp(colname, "regexten")) {
09438       ast_copy_string(buf, peer->regexten, len);
09439    } else  if (!strcasecmp(colname, "limit")) {
09440       snprintf(buf, len, "%d", peer->call_limit);
09441    } else  if (!strcasecmp(colname, "curcalls")) {
09442       snprintf(buf, len, "%d", peer->inUse);
09443    } else  if (!strcasecmp(colname, "accountcode")) {
09444       ast_copy_string(buf, peer->accountcode, len);
09445    } else  if (!strcasecmp(colname, "useragent")) {
09446       ast_copy_string(buf, peer->useragent, len);
09447    } else  if (!strcasecmp(colname, "mailbox")) {
09448       ast_copy_string(buf, peer->mailbox, len);
09449    } else  if (!strcasecmp(colname, "context")) {
09450       ast_copy_string(buf, peer->context, len);
09451    } else  if (!strcasecmp(colname, "expire")) {
09452       snprintf(buf, len, "%d", peer->expire);
09453    } else  if (!strcasecmp(colname, "dynamic")) {
09454       ast_copy_string(buf, (ast_test_flag(&peer->flags_page2, SIP_PAGE2_DYNAMIC) ? "yes" : "no"), len);
09455    } else  if (!strcasecmp(colname, "callerid_name")) {
09456       ast_copy_string(buf, peer->cid_name, len);
09457    } else  if (!strcasecmp(colname, "callerid_num")) {
09458       ast_copy_string(buf, peer->cid_num, len);
09459    } else  if (!strcasecmp(colname, "codecs")) {
09460       ast_getformatname_multiple(buf, len -1, peer->capability);
09461    } else  if (!strncasecmp(colname, "codec[", 6)) {
09462       char *codecnum, *ptr;
09463       int index = 0, codec = 0;
09464       
09465       codecnum = strchr(colname, '[');
09466       *codecnum = '\0';
09467       codecnum++;
09468       if ((ptr = strchr(codecnum, ']'))) {
09469          *ptr = '\0';
09470       }
09471       index = atoi(codecnum);
09472       if((codec = ast_codec_pref_index(&peer->prefs, index))) {
09473          ast_copy_string(buf, ast_getformatname(codec), len);
09474       }
09475    }
09476    ret = buf;
09477 
09478    ASTOBJ_UNREF(peer, sip_destroy_peer);
09479 
09480    return ret;
09481 }

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

References ast_canmatch_extension(), ast_exists_extension(), ast_log(), ast_verbose(), sip_pvt::context, get_header(), get_in_brackets(), sip_pvt::initreq, LOG_DEBUG, LOG_WARNING, sip_pvt::refer_call, sip_pvt::refer_contact, sip_pvt::refer_to, sip_pvt::referred_by, and sip_debug_test_pvt().

Referenced by handle_request_bye().

06963 {
06964    char tmp[256], *c, *a;
06965    struct sip_request *req;
06966    
06967    req = oreq;
06968    if (!req)
06969       req = &p->initreq;
06970    ast_copy_string(tmp, get_header(req, "Also"), sizeof(tmp));
06971    
06972    c = get_in_brackets(tmp);
06973    
06974       
06975    if (strncmp(c, "sip:", 4)) {
06976       ast_log(LOG_WARNING, "Huh?  Not a SIP header (%s)?\n", c);
06977       return -1;
06978    }
06979    c += 4;
06980    if ((a = strchr(c, '@')))
06981       *a = '\0';
06982    if ((a = strchr(c, ';'))) 
06983       *a = '\0';
06984    
06985    if (sip_debug_test_pvt(p)) {
06986       ast_verbose("Looking for %s in %s\n", c, p->context);
06987    }
06988    if (ast_exists_extension(NULL, p->context, c, 1, NULL)) {
06989       /* This is an unsupervised transfer */
06990       ast_log(LOG_DEBUG,"Assigning Extension %s to REFER-TO\n", c);
06991       ast_copy_string(p->refer_to, c, sizeof(p->refer_to));
06992       ast_copy_string(p->referred_by, "", sizeof(p->referred_by));
06993       ast_copy_string(p->refer_contact, "", sizeof(p->refer_contact));
06994       p->refer_call = NULL;
06995       return 0;
06996    } else if (ast_canmatch_extension(NULL, p->context, c, 1, NULL)) {
06997       return 1;
06998    }
06999 
07000    return -1;
07001 }

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

get_body: get a specific line from the message body

Definition at line 2928 of file chan_sip.c.

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

Referenced by handle_request_info().

02929 {
02930    int x;
02931    int len = strlen(name);
02932    char *r;
02933 
02934    for (x = 0; x < req->lines; x++) {
02935       r = get_body_by_line(req->line[x], name, len);
02936       if (r[0] != '\0')
02937          return r;
02938    }
02939    return "";
02940 }

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

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

02886 {
02887    if (strncasecmp(line, name, nameLen) == 0 && line[nameLen] == '=') {
02888       return ast_skip_blanks(line + nameLen + 1);
02889    }
02890    return "";
02891 }

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

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

Definition at line 7053 of file chan_sip.c.

Referenced by check_user_full().

07054 {
07055    char *end = strchr(input,'<');
07056    char *tmp = strchr(input,'\"');
07057    int bytes = 0;
07058    int maxbytes = outputsize - 1;
07059 
07060    if (!end || (end == input)) return NULL;
07061    /* move away from "<" */
07062    end--;
07063    /* we found "name" */
07064    if (tmp && tmp < end) {
07065       end = strchr(tmp+1, '\"');
07066       if (!end) return NULL;
07067       bytes = (int) (end - tmp);
07068       /* protect the output buffer */
07069       if (bytes > maxbytes)
07070          bytes = maxbytes;
07071       ast_copy_string(output, tmp + 1, bytes);
07072    } else {
07073       /* we didn't find "name" */
07074       /* clear the empty characters in the begining*/
07075       input = ast_skip_blanks(input);
07076       /* clear the empty characters in the end */
07077       while(*end && (*end < 33) && end > input)
07078          end--;
07079       if (end >= input) {
07080          bytes = (int) (end - input) + 2;
07081          /* protect the output buffer */
07082          if (bytes > maxbytes) {
07083             bytes = maxbytes;
07084          }
07085          ast_copy_string(output, input, bytes);
07086       }
07087       else
07088          return NULL;
07089    }
07090    return output;
07091 }

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 6688 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, SIP_REFER, and user.

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

06689 {
06690    char tmp[256] = "", *uri, *a, *user, *domain, *opts;
06691    char tmpf[256], *from;
06692    struct sip_request *req;
06693    char *colon;
06694    
06695    req = oreq;
06696    if (!req)
06697       req = &p->initreq;
06698    if (req->rlPart2)
06699       ast_copy_string(tmp, req->rlPart2, sizeof(tmp));
06700    uri = get_in_brackets(tmp);
06701    
06702    ast_copy_string(tmpf, get_header(req, "From"), sizeof(tmpf));
06703 
06704    from = get_in_brackets(tmpf);
06705    
06706    if (strncmp(uri, "sip:", 4)) {
06707       ast_log(LOG_WARNING, "Huh?  Not a SIP header (%s)?\n", uri);
06708       return -1;
06709    }
06710    uri += 4;
06711    if (!ast_strlen_zero(from)) {
06712       if (strncmp(from, "sip:", 4)) {
06713          ast_log(LOG_WARNING, "Huh?  Not a SIP header (%s)?\n", from);
06714          return -1;
06715       }
06716       from += 4;
06717    } else
06718       from = NULL;
06719 
06720    if (pedanticsipchecking) {
06721       ast_uri_decode(uri);
06722       ast_uri_decode(from);
06723    }
06724 
06725    /* Get the target domain first and user */
06726    if ((domain = strchr(uri, '@'))) {
06727       *domain++ = '\0';
06728       user = uri;
06729    } else {
06730       /* No user portion present */
06731       domain = uri;
06732       user = "s";
06733    }
06734 
06735    /* Strip port from domain if present */
06736    if ((colon = strchr(domain, ':'))) {
06737       *colon = '\0';
06738    }
06739 
06740    /* Strip any params or options from user */
06741    if ((opts = strchr(user, ';'))) {
06742       *opts = '\0';
06743    }
06744 
06745    ast_copy_string(p->domain, domain, sizeof(p->domain));
06746 
06747    if (!AST_LIST_EMPTY(&domain_list)) {
06748       char domain_context[AST_MAX_EXTENSION];
06749 
06750       domain_context[0] = '\0';
06751       if (!check_sip_domain(p->domain, domain_context, sizeof(domain_context))) {
06752          if (!allow_external_domains && (req->method == SIP_INVITE || req->method == SIP_REFER)) {
06753             ast_log(LOG_DEBUG, "Got SIP %s to non-local domain '%s'; refusing request.\n", sip_methods[req->method].text, p->domain);
06754             return -2;
06755          }
06756       }
06757       /* If we have a context defined, overwrite the original context */
06758       if (!ast_strlen_zero(domain_context))
06759          ast_copy_string(p->context, domain_context, sizeof(p->context));
06760    }
06761 
06762    if (from) {
06763       if ((a = strchr(from, ';')))
06764          *a = '\0';
06765       if ((a = strchr(from, '@'))) {
06766          *a = '\0';
06767          ast_copy_string(p->fromdomain, a + 1, sizeof(p->fromdomain));
06768       } else
06769          ast_copy_string(p->fromdomain, from, sizeof(p->fromdomain));
06770    }
06771    if (sip_debug_test_pvt(p))
06772       ast_verbose("Looking for %s in %s (domain %s)\n", user, p->context, p->domain);
06773 
06774    /* Return 0 if we have a matching extension */
06775    if (ast_exists_extension(NULL, p->context, user, 1, from) ||
06776       !strcmp(uri, ast_pickup_ext())) {
06777       if (!oreq)
06778          ast_copy_string(p->exten, user, sizeof(p->exten));
06779       return 0;
06780    }
06781 
06782    /* Return 1 for overlap dialling support */
06783    if (ast_canmatch_extension(NULL, p->context, user, 1, from) ||
06784        !strncmp(user, ast_pickup_ext(),strlen(user))) {
06785       return 1;
06786    }
06787    
06788    return -1;
06789 }

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

get_header: Get header from SIP request ---

Definition at line 2987 of file chan_sip.c.

References __get_header().

02988 {
02989    int start = 0;
02990    return __get_header(req, name, &start);
02991 }

static char* get_in_brackets char *  tmp  )  [static]
 

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

Definition at line 1550 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().

01551 {
01552    char *parse;
01553    char *first_quote;
01554    char *first_bracket;
01555    char *second_bracket;
01556    char last_char;
01557 
01558    parse = tmp;
01559    while (1) {
01560       first_quote = strchr(parse, '"');
01561       first_bracket = strchr(parse, '<');
01562       if (first_quote && first_bracket && (first_quote < first_bracket)) {
01563          last_char = '\0';
01564          for (parse = first_quote + 1; *parse; parse++) {
01565             if ((*parse == '"') && (last_char != '\\'))
01566                break;
01567             last_char = *parse;
01568          }
01569          if (!*parse) {
01570             ast_log(LOG_WARNING, "No closing quote found in '%s'\n", tmp);
01571             return tmp;
01572          }
01573          parse++;
01574          continue;
01575       }
01576       if (first_bracket) {
01577          second_bracket = strchr(first_bracket + 1, '>');
01578          if (second_bracket) {
01579             *second_bracket = '\0';
01580             return first_bracket + 1;
01581          } else {
01582             ast_log(LOG_WARNING, "No closing bracket found in '%s'\n", tmp);
01583             return tmp;
01584          }
01585       }
01586       return tmp;
01587    }
01588 }

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

References sip_request::line, and sip_request::lines.

Referenced by receive_message().

07403 {
07404    int x;
07405    int y;
07406 
07407    buf[0] = '\0';
07408    y = len - strlen(buf) - 5;
07409    if (y < 0)
07410       y = 0;
07411    for (x=0;x<req->lines;x++) {
07412       strncat(buf, req->line[x], y); /* safe */
07413       y -= strlen(req->line[x]) + 1;
07414       if (y < 0)
07415          y = 0;
07416       if (y != 0)
07417          strcat(buf, "\n"); /* safe */
07418    }
07419    return 0;
07420 }

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

get_rdnis: get referring dnis ---

Definition at line 6660 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().

06661 {
06662    char tmp[256], *c, *a;
06663    struct sip_request *req;
06664    
06665    req = oreq;
06666    if (!req)
06667       req = &p->initreq;
06668    ast_copy_string(tmp, get_header(req, "Diversion"), sizeof(tmp));
06669    if (ast_strlen_zero(tmp))
06670       return 0;
06671    c = get_in_brackets(tmp);
06672    if (strncmp(c, "sip:", 4)) {
06673       ast_log(LOG_WARNING, "Huh?  Not an RDNIS SIP header (%s)?\n", c);
06674       return -1;
06675    }
06676    c += 4;
06677    if ((a = strchr(c, '@')) || (a = strchr(c, ';'))) {
06678       *a = '\0';
06679    }
06680    if (sip_debug_test_pvt(p))
06681       ast_verbose("RDNIS is %s\n", c);
06682    ast_copy_string(p->rdnis, c, sizeof(p->rdnis));
06683 
06684    return 0;
06685 }

static int get_refer_info struct sip_pvt sip_pvt,
struct sip_request outgoing_req,
char **  transfercontext
[static]
 

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

Definition at line 6821 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::callid, 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_call, sip_pvt::refer_contact, sip_pvt::refer_to, sip_pvt::referred_by, and sip_debug_test_pvt().

Referenced by handle_request_refer().

06822 {
06823 
06824    char *p_refer_to = NULL, *p_referred_by = NULL, *h_refer_to = NULL, *h_referred_by = NULL, *h_contact = NULL;
06825    char *replace_callid = "", *refer_to = NULL, *referred_by = NULL, *ptr = NULL;
06826    struct sip_request *req = NULL;
06827    struct sip_pvt *sip_pvt_ptr = NULL;
06828    struct ast_channel *chan = NULL, *peer = NULL;
06829 
06830    req = outgoing_req;
06831 
06832    if (!req) {
06833       req = &sip_pvt->initreq;
06834    }
06835    
06836    if (!( (p_refer_to = get_header(req, "Refer-To")) && (h_refer_to = ast_strdupa(p_refer_to)) )) {
06837       ast_log(LOG_WARNING, "No Refer-To Header That's illegal\n");
06838       return -1;
06839    }
06840 
06841    refer_to = get_in_brackets(h_refer_to);
06842 
06843    if (!( (p_referred_by = get_header(req, "Referred-By")) && (h_referred_by = ast_strdupa(p_referred_by)) )) {
06844       ast_log(LOG_WARNING, "No Referrred-By Header That's not illegal\n");
06845       return -1;
06846    } else {
06847       if (pedanticsipchecking) {
06848          ast_uri_decode(h_referred_by);
06849       }
06850       referred_by = get_in_brackets(h_referred_by);
06851    }
06852    h_contact = get_header(req, "Contact");
06853    
06854    if (strncmp(refer_to, "sip:", 4)) {
06855       ast_log(LOG_WARNING, "Refer-to: Huh?  Not a SIP header (%s)?\n", refer_to);
06856       return -1;
06857    }
06858 
06859    if (strncmp(referred_by, "sip:", 4)) {
06860       ast_log(LOG_WARNING, "Referred-by: Huh?  Not a SIP header (%s) Ignoring?\n", referred_by);
06861       referred_by = NULL;
06862    }
06863 
06864    if (refer_to)
06865       refer_to += 4;
06866 
06867    if (referred_by)
06868       referred_by += 4;
06869    
06870    if ((ptr = strchr(refer_to, '?'))) {
06871       /* Search for arguments */
06872       *ptr = '\0';
06873       ptr++;
06874       if (!strncasecmp(ptr, "REPLACES=", 9)) {
06875          char *p;
06876          replace_callid = ast_strdupa(ptr + 9);
06877          /* someday soon to support invite/replaces properly!
06878             replaces_header = ast_strdupa(replace_callid); 
06879             -anthm
06880          */
06881          ast_uri_decode(replace_callid);
06882          if ((ptr = strchr(replace_callid, '%'))) 
06883             *ptr = '\0';
06884          if ((ptr = strchr(replace_callid, ';'))) 
06885             *ptr = '\0';
06886          /* Skip leading whitespace XXX memmove behaviour with overlaps ? */
06887          p = ast_skip_blanks(replace_callid);
06888          if (p != replace_callid)
06889             memmove(replace_callid, p, strlen(p));
06890       }
06891    }
06892    
06893    if ((ptr = strchr(refer_to, '@')))  /* Skip domain (should be saved in SIPDOMAIN) */
06894       *ptr = '\0';
06895    if ((ptr = strchr(refer_to, ';'))) 
06896       *ptr = '\0';
06897    
06898    if (referred_by) {
06899       if ((ptr = strchr(referred_by, '@')))
06900          *ptr = '\0';
06901       if ((ptr = strchr(referred_by, ';'))) 
06902          *ptr = '\0';
06903    }
06904    
06905    *transfercontext = pbx_builtin_getvar_helper(sip_pvt->owner, "TRANSFER_CONTEXT");
06906    if (ast_strlen_zero(*transfercontext))
06907       *transfercontext = sip_pvt->context;
06908 
06909    if (sip_debug_test_pvt(sip_pvt)) {
06910       ast_verbose("Transfer to %s in %s\n", refer_to, *transfercontext);
06911       if (referred_by)
06912          ast_verbose("Transfer from %s in %s\n", referred_by, sip_pvt->context);
06913    }
06914    if (!ast_strlen_zero(replace_callid)) {   
06915       /* This is a supervised transfer */
06916       ast_log(LOG_DEBUG,"Assigning Replace-Call-ID Info %s to REPLACE_CALL_ID\n",replace_callid);
06917       
06918       ast_copy_string(sip_pvt->refer_to, "", sizeof(sip_pvt->refer_to));
06919       ast_copy_string(sip_pvt->referred_by, "", sizeof(sip_pvt->referred_by));
06920       ast_copy_string(sip_pvt->refer_contact, "", sizeof(sip_pvt->refer_contact));
06921       sip_pvt->refer_call = NULL;
06922       if ((sip_pvt_ptr = get_sip_pvt_byid_locked(replace_callid))) {
06923          sip_pvt->refer_call = sip_pvt_ptr;
06924          if (sip_pvt->refer_call == sip_pvt) {
06925             ast_log(LOG_NOTICE, "Supervised transfer attempted to transfer into same call id (%s == %s)!\n", replace_callid, sip_pvt->callid);
06926             sip_pvt->refer_call = NULL;
06927          } else
06928             return 0;
06929       } else {
06930          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);
06931          /* XXX The refer_to could contain a call on an entirely different machine, requiring an 
06932               INVITE with a replaces header -anthm XXX */
06933          /* The only way to find out is to use the dialplan - oej */
06934       }
06935    } else if (ast_exists_extension(NULL, *transfercontext, refer_to, 1, NULL) || !strcmp(refer_to, ast_parking_ext())) {
06936       /* This is an unsupervised transfer (blind transfer) */
06937       
06938       ast_log(LOG_DEBUG,"Unsupervised transfer to (Refer-To): %s\n", refer_to);
06939       if (referred_by)
06940          ast_log(LOG_DEBUG,"Transferred by  (Referred-by: ) %s \n", referred_by);
06941       ast_log(LOG_DEBUG,"Transfer Contact Info %s (REFER_CONTACT)\n", h_contact);
06942       ast_copy_string(sip_pvt->refer_to, refer_to, sizeof(sip_pvt->refer_to));
06943       if (referred_by)
06944          ast_copy_string(sip_pvt->referred_by, referred_by, sizeof(sip_pvt->referred_by));
06945       if (h_contact) {
06946          ast_copy_string(sip_pvt->refer_contact, h_contact, sizeof(sip_pvt->refer_contact));
06947       }
06948       sip_pvt->refer_call = NULL;
06949       if ((chan = sip_pvt->owner) && (peer = ast_bridged_channel(sip_pvt->owner))) {
06950          pbx_builtin_setvar_helper(chan, "BLINDTRANSFER", peer->name);
06951          pbx_builtin_setvar_helper(peer, "BLINDTRANSFER", chan->name);
06952       }
06953       return 0;
06954    } else if (ast_canmatch_extension(NULL, *transfercontext, refer_to, 1, NULL)) {
06955       return 1;
06956    }
06957 
06958    return -1;
06959 }

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

References AST_PRES_PROHIB_USER_NUMBER_NOT_SCREENED.

Referenced by check_user_full().

07098 {
07099    char *start;
07100    char *end;
07101 
07102    start = strchr(input,':');
07103    if (!start) {
07104       output[0] = '\0';
07105       return 0;
07106    }
07107    start++;
07108 
07109    /* we found "number" */
07110    ast_copy_string(output,start,maxlen);
07111    output[maxlen-1] = '\0';
07112 
07113    end = strchr(output,'@');
07114    if (end)
07115       *end = '\0';
07116    else
07117       output[0] = '\0';
07118    if (strstr(input,"privacy=full") || strstr(input,"privacy=uri"))
07119       return AST_PRES_PROHIB_USER_NUMBER_NOT_SCREENED;
07120 
07121    return 0;
07122 }

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

get_sdp: get a specific line from the SDP

Definition at line 2894 of file chan_sip.c.

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

02895 {
02896    int x;
02897    int len = strlen(name);
02898    char *r;
02899 
02900    for (x = req->sdp_start; x < req->sdp_end; x++) {
02901       r = get_body_by_line(req->line[x], name, len);
02902       if (r[0] != '\0')
02903          return r;
02904    }
02905    return "";
02906 }

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

Definition at line 2913 of file chan_sip.c.

References get_body_by_line(), and sip_request::line.

02915 {
02916    int len = strlen(name);
02917    char *r;
02918 
02919    while (*iterator < req->sdp_end) {
02920       r = get_body_by_line(req->line[(*iterator)++], name, len);
02921       if (r[0] != '\0')
02922          return r;
02923    }
02924    return "";
02925 }

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 6792 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().

06793 {
06794    struct sip_pvt *sip_pvt_ptr = NULL;
06795    
06796    /* Search interfaces and find the match */
06797    ast_mutex_lock(&iflock);
06798    sip_pvt_ptr = iflist;
06799    while(sip_pvt_ptr) {
06800       if (!strcmp(sip_pvt_ptr->callid, callid)) {
06801          /* Go ahead and lock it (and its owner) before returning */
06802          ast_mutex_lock(&sip_pvt_ptr->lock);
06803          if (sip_pvt_ptr->owner) {
06804             while(ast_mutex_trylock(&sip_pvt_ptr->owner->lock)) {
06805                ast_mutex_unlock(&sip_pvt_ptr->lock);
06806                usleep(1);
06807                ast_mutex_lock(&sip_pvt_ptr->lock);
06808                if (!sip_pvt_ptr->owner)
06809                   break;
06810             }
06811          }
06812          break;
06813       }
06814       sip_pvt_ptr = sip_pvt_ptr->next;
06815    }
06816    ast_mutex_unlock(&iflock);
06817    return sip_pvt_ptr;
06818 }

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

gettag: Get tag from packet

Definition at line 10419 of file chan_sip.c.

References get_header(), and strcasestr().

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

10420 {
10421 
10422    char *thetag, *sep;
10423    
10424 
10425    if (!tagbuf)
10426       return NULL;
10427    tagbuf[0] = '\0';    /* reset the buffer */
10428    thetag = get_header(req, header);
10429    thetag = strcasestr(thetag, ";tag=");
10430    if (thetag) {
10431       thetag += 5;
10432       ast_copy_string(tagbuf, thetag, tagbufsize);
10433       sep = strchr(tagbuf, ';');
10434       if (sep)
10435          *sep = '\0';
10436    }
10437    return thetag;
10438 }

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

References ast_clear_flag, ast_false(), ast_log(), ast_set2_flag, ast_set_flag, ast_true(), ast_channel::flags, 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_NAT_ROUTE, 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().

11889 {
11890    int res = 0;
11891 
11892    if (!strcasecmp(v->name, "trustrpid")) {
11893       ast_set_flag(mask, SIP_TRUSTRPID);
11894       ast_set2_flag(flags, ast_true(v->value), SIP_TRUSTRPID);
11895       res = 1;
11896    } else if (!strcasecmp(v->name, "sendrpid")) {
11897       ast_set_flag(mask, SIP_SENDRPID);
11898       ast_set2_flag(flags, ast_true(v->value), SIP_SENDRPID);
11899       res = 1;
11900    } else if (!strcasecmp(v->name, "useclientcode")) {
11901       ast_set_flag(mask, SIP_USECLIENTCODE);
11902       ast_set2_flag(flags, ast_true(v->value), SIP_USECLIENTCODE);
11903       res = 1;
11904    } else if (!strcasecmp(v->name, "dtmfmode")) {
11905       ast_set_flag(mask, SIP_DTMF);
11906       ast_clear_flag(flags, SIP_DTMF);
11907       if (!strcasecmp(v->value, "inband"))
11908          ast_set_flag(flags, SIP_DTMF_INBAND);
11909       else if (!strcasecmp(v->value, "rfc2833"))
11910          ast_set_flag(flags, SIP_DTMF_RFC2833);
11911       else if (!strcasecmp(v->value, "info"))
11912          ast_set_flag(flags, SIP_DTMF_INFO);
11913       else if (!strcasecmp(v->value, "auto"))
11914          ast_set_flag(flags, SIP_DTMF_AUTO);
11915       else {
11916          ast_log(LOG_WARNING, "Unknown dtmf mode '%s' on line %d, using rfc2833\n", v->value, v->lineno);
11917          ast_set_flag(flags, SIP_DTMF_RFC2833);
11918       }
11919    } else if (!strcasecmp(v->name, "nat")) {
11920       ast_set_flag(mask, SIP_NAT);
11921       ast_clear_flag(flags, SIP_NAT);
11922       if (!strcasecmp(v->value, "never"))
11923          ast_set_flag(flags, SIP_NAT_NEVER);
11924       else if (!strcasecmp(v->value, "route"))
11925          ast_set_flag(flags, SIP_NAT_ROUTE);
11926       else if (ast_true(v->value))
11927          ast_set_flag(flags, SIP_NAT_ALWAYS);
11928       else
11929          ast_set_flag(flags, SIP_NAT_RFC3581);
11930    } else if (!strcasecmp(v->name, "canreinvite")) {
11931       ast_set_flag(mask, SIP_REINVITE);
11932       ast_clear_flag(flags, SIP_REINVITE);
11933       if (!strcasecmp(v->value, "update"))
11934          ast_set_flag(flags, SIP_REINVITE_UPDATE | SIP_CAN_REINVITE);
11935       else
11936          ast_set2_flag(flags, ast_true(v->value), SIP_CAN_REINVITE);
11937    } else if (!strcasecmp(v->name, "insecure")) {
11938       ast_set_flag(mask, SIP_INSECURE_PORT | SIP_INSECURE_INVITE);
11939       ast_clear_flag(flags, SIP_INSECURE_PORT | SIP_INSECURE_INVITE);
11940       if (!strcasecmp(v->value, "very"))
11941          ast_set_flag(flags, SIP_INSECURE_PORT | SIP_INSECURE_INVITE);
11942       else if (ast_true(v->value))
11943          ast_set_flag(flags, SIP_INSECURE_PORT);
11944       else if (!ast_false(v->value)) {
11945          char buf[64];
11946          char *word, *next;
11947 
11948          ast_copy_string(buf, v->value, sizeof(buf));
11949          next = buf;
11950          while ((word = strsep(&next, ","))) {
11951             if (!strcasecmp(word, "port"))
11952                ast_set_flag(flags, SIP_INSECURE_PORT);
11953             else if (!strcasecmp(word, "invite"))
11954                ast_set_flag(flags, SIP_INSECURE_INVITE);
11955             else
11956                ast_log(LOG_WARNING, "Unknown insecure mode '%s' on line %d\n", v->value, v->lineno);
11957          }
11958       }
11959    } else if (!strcasecmp(v->name, "progressinband")) {
11960       ast_set_flag(mask, SIP_PROG_INBAND);
11961       ast_clear_flag(flags, SIP_PROG_INBAND);
11962       if (ast_true(v->value))
11963          ast_set_flag(flags, SIP_PROG_INBAND_YES);
11964       else if (strcasecmp(v->value, "never"))
11965          ast_set_flag(flags, SIP_PROG_INBAND_NO);
11966    } else if (!strcasecmp(v->name, "allowguest")) {
11967 #ifdef OSP_SUPPORT
11968       if (!strcasecmp(v->value, "osp"))
11969          global_allowguest = 2;
11970       else 
11971 #endif
11972          if (ast_true(v->value)) 
11973             global_allowguest = 1;
11974          else
11975             global_allowguest = 0;
11976 #ifdef OSP_SUPPORT
11977    } else if (!strcasecmp(v->name, "ospauth")) {
11978       ast_set_flag(mask, SIP_OSPAUTH);
11979       ast_clear_flag(flags, SIP_OSPAUTH);
11980       if (!strcasecmp(v->value, "proxy"))
11981          ast_set_flag(flags, SIP_OSPAUTH_PROXY);
11982       else if (!strcasecmp(v->value, "gateway"))
11983          ast_set_flag(flags, SIP_OSPAUTH_GATEWAY);
11984       else if(!strcasecmp (v->value, "exclusive"))
11985          ast_set_flag(flags, SIP_OSPAUTH_EXCLUSIVE);
11986 #endif
11987    } else if (!strcasecmp(v->name, "promiscredir")) {
11988       ast_set_flag(mask, SIP_PROMISCREDIR);
11989       ast_set2_flag(flags, ast_true(v->value), SIP_PROMISCREDIR);
11990       res = 1;
11991    }
11992 
11993    return res;
11994 }

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

11143 {
11144    /* Called with p->lock held, as well as p->owner->lock if appropriate, keeping things
11145       relatively static */
11146    struct sip_request resp;
11147    char *cmd;
11148    char *cseq;
11149    char *useragent;
11150    int seqno;
11151    int len;
11152    int ignore=0;
11153    int respid;
11154    int res = 0;
11155    char iabuf[INET_ADDRSTRLEN];
11156    int debug = sip_debug_test_pvt(p);
11157    char *e;
11158    int error = 0;
11159 
11160    /* Clear out potential response */
11161    memset(&resp, 0, sizeof(resp));
11162 
11163    /* Get Method and Cseq */
11164    cseq = get_header(req, "Cseq");
11165    cmd = req->header[0];
11166 
11167    /* Must have Cseq */
11168    if (ast_strlen_zero(cmd) || ast_strlen_zero(cseq)) {
11169       ast_log(LOG_ERROR, "Missing Cseq. Dropping this SIP message, it's incomplete.\n");
11170       error = 1;
11171    }
11172    if (!error && sscanf(cseq, "%d%n", &seqno, &len) != 1) {
11173       ast_log(LOG_ERROR, "No seqno in '%s'. Dropping incomplete message.\n", cmd);
11174       error = 1;
11175    }
11176    if (error) {
11177       if (!p->initreq.header) /* New call */
11178          ast_set_flag(p, SIP_NEEDDESTROY);   /* Make sure we destroy this dialog */
11179       return -1;
11180    }
11181    /* Get the command XXX */
11182 
11183    cmd = req->rlPart1;
11184    e = req->rlPart2;
11185 
11186    /* Save useragent of the client */
11187    useragent = get_header(req, "User-Agent");
11188    if (!ast_strlen_zero(useragent))
11189       ast_copy_string(p->useragent, useragent, sizeof(p->useragent));
11190 
11191    /* Find out SIP method for incoming request */
11192    if (req->method == SIP_RESPONSE) {  /* Response to our request */
11193       /* Response to our request -- Do some sanity checks */   
11194       if (!p->initreq.headers) {
11195          ast_log(LOG_DEBUG, "That's odd...  Got a response on a call we dont know about. Cseq %d Cmd %s\n", seqno, cmd);
11196          ast_set_flag(p, SIP_NEEDDESTROY);   
11197          return 0;
11198       } else if (p->ocseq && (p->ocseq < seqno)) {
11199          ast_log(LOG_DEBUG, "Ignoring out of order response %d (expecting %d)\n", seqno, p->ocseq);
11200          return -1;
11201       } else if (p->ocseq && (p->ocseq != seqno)) {
11202          /* ignore means "don't do anything with it" but still have to 
11203             respond appropriately  */
11204          ignore=1;
11205       }
11206    
11207       e = ast_skip_blanks(e);
11208       if (sscanf(e, "%d %n", &respid, &len) != 1) {
11209          ast_log(LOG_WARNING, "Invalid response: '%s'\n", e);
11210       } else {
11211          /* More SIP ridiculousness, we have to ignore bogus contacts in 100 etc responses */
11212          if ((respid == 200) || ((respid >= 300) && (respid <= 399)))
11213             extract_uri(p, req);
11214          handle_response(p, respid, e + len, req, ignore, seqno);
11215       }
11216       return 0;
11217    }
11218 
11219    /* New SIP request coming in 
11220       (could be new request in existing SIP dialog as well...) 
11221     */         
11222    
11223    p->method = req->method;   /* Find out which SIP method they are using */
11224    if (option_debug > 2)
11225       ast_log(LOG_DEBUG, "**** Received %s (%d) - Command in SIP %s\n", sip_methods[p->method].text, sip_methods[p->method].id, cmd); 
11226 
11227    if (p->icseq && (p->icseq > seqno)) {
11228       if (option_debug)
11229          ast_log(LOG_DEBUG, "Ignoring too old SIP packet packet %d (expecting >= %d)\n", seqno, p->icseq);
11230       if (req->method != SIP_ACK)
11231          transmit_response(p, "503 Server error", req);  /* We must respond according to RFC 3261 sec 12.2 */
11232       return -1;
11233    } else if (p->icseq && (p->icseq == seqno) && req->method != SIP_ACK &&(p->method != SIP_CANCEL|| ast_test_flag(p, SIP_ALREADYGONE))) {
11234       /* ignore means "don't do anything with it" but still have to 
11235          respond appropriately.  We do this if we receive a repeat of
11236          the last sequence number  */
11237       ignore=2;
11238       if (option_debug > 2)
11239          ast_log(LOG_DEBUG, "Ignoring SIP message because of retransmit (%s Seqno %d, ours %d)\n", sip_methods[p->method].text, p->icseq, seqno);
11240    }
11241       
11242    if (seqno >= p->icseq)
11243       /* Next should follow monotonically (but not necessarily 
11244          incrementally -- thanks again to the genius authors of SIP --
11245          increasing */
11246       p->icseq = seqno;
11247 
11248    /* Find their tag if we haven't got it */
11249    if (ast_strlen_zero(p->theirtag)) {
11250       gettag(req, "From", p->theirtag, sizeof(p->theirtag));
11251    }
11252    snprintf(p->lastmsg, sizeof(p->lastmsg), "Rx: %s", cmd);
11253 
11254    if (pedanticsipchecking) {
11255       /* If this is a request packet without a from tag, it's not
11256          correct according to RFC 3261  */
11257       /* Check if this a new request in a new dialog with a totag already attached to it,
11258          RFC 3261 - section 12.2 - and we don't want to mess with recovery  */
11259       if (!p->initreq.headers && ast_test_flag(req, SIP_PKT_WITH_TOTAG)) {
11260          /* If this is a first request and it got a to-tag, it is not for us */
11261          if (!ignore && req->method == SIP_INVITE) {
11262             transmit_response_reliable(p, "481 Call/Transaction Does Not Exist", req, 1);
11263             /* Will cease to exist after ACK */
11264          } else if (req->method != SIP_ACK) {
11265             transmit_response(p, "481 Call/Transaction Does Not Exist", req);
11266             ast_set_flag(p, SIP_NEEDDESTROY);
11267          }
11268          return res;
11269       }
11270    }
11271 
11272    /* Handle various incoming SIP methods in requests */
11273    switch (p->method) {
11274    case SIP_OPTIONS:
11275       res = handle_request_options(p, req, debug);
11276       break;
11277    case SIP_INVITE:
11278       res = handle_request_invite(p, req, debug, ignore, seqno, sin, recount, e);
11279       break;
11280    case SIP_REFER:
11281       res = handle_request_refer(p, req, debug, ignore, seqno, nounlock);
11282       break;
11283    case SIP_CANCEL:
11284       res = handle_request_cancel(p, req, debug, ignore);
11285       break;
11286    case SIP_BYE:
11287       res = handle_request_bye(p, req, debug, ignore);
11288       break;
11289    case SIP_MESSAGE:
11290       res = handle_request_message(p, req, debug, ignore);
11291       break;
11292    case SIP_SUBSCRIBE:
11293       res = handle_request_subscribe(p, req, debug, ignore, sin, seqno, e);
11294       break;
11295    case SIP_REGISTER:
11296       res = handle_request_register(p, req, debug, ignore, sin, e);
11297       break;
11298    case SIP_INFO:
11299       if (!ignore) {
11300          if (debug)
11301             ast_verbose("Receiving INFO!\n");
11302          handle_request_info(p, req);
11303       } else { /* if ignoring, transmit response */
11304          transmit_response(p, "200 OK", req);
11305       }
11306       break;
11307    case SIP_NOTIFY:
11308       /* XXX we get NOTIFY's from some servers. WHY?? Maybe we should
11309          look into this someday XXX */
11310       transmit_response(p, "200 OK", req);
11311       if (!p->lastinvite) 
11312          ast_set_flag(p, SIP_NEEDDESTROY);   
11313       break;
11314    case SIP_ACK:
11315       /* Make sure we don't ignore this */
11316       if (seqno == p->pendinginvite) {
11317          p->pendinginvite = 0;
11318          __sip_ack(p, seqno, FLAG_RESPONSE, 0);
11319          if (find_sdp(req)) {
11320             if (process_sdp(p, req))
11321                return -1;
11322          } 
11323          check_pendings(p);
11324       }
11325       if (!p->lastinvite && ast_strlen_zero(p->randdata))
11326          ast_set_flag(p, SIP_NEEDDESTROY);   
11327       break;
11328    default:
11329       transmit_response_with_allow(p, "501 Method Not Implemented", req, 0);
11330       ast_log(LOG_NOTICE, "Unknown SIP command '%s' from '%s'\n", 
11331          cmd, ast_inet_ntoa(iabuf, sizeof(iabuf), p->sa.sin_addr));
11332       /* If this is some new method, and we don't have a call, destroy it now */
11333       if (!p->initreq.headers)
11334          ast_set_flag(p, SIP_NEEDDESTROY);   
11335       break;
11336    }
11337    return res;
11338 }

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 10830 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_DEBUG, LOG_NOTICE, LOG_WARNING, option_debug, sip_pvt::pendinginvite, SIP_ALREADYGONE, SIP_NEEDDESTROY, SIP_OUTGOING, transmit_response(), and transmit_response_reliable().

Referenced by handle_request().

10831 {
10832    struct ast_channel *c=NULL;
10833    int res;
10834    struct ast_channel *bridged_to;
10835    char iabuf[INET_ADDRSTRLEN];
10836    
10837    if (p->pendinginvite && !ast_test_flag(p, SIP_OUTGOING) && !ignore)
10838       transmit_response_reliable(p, "487 Request Terminated", &p->initreq, 1);
10839 
10840    copy_request(&p->initreq, req);
10841    check_via(p, req);
10842    ast_set_flag(p, SIP_ALREADYGONE);   
10843    if (p->rtp) {
10844       /* Immediately stop RTP */
10845       ast_rtp_stop(p->rtp);
10846    }
10847    if (p->vrtp) {
10848       /* Immediately stop VRTP */
10849       ast_rtp_stop(p->vrtp);
10850    }
10851    if (!ast_strlen_zero(get_header(req, "Also"))) {
10852       ast_log(LOG_NOTICE, "Client '%s' using deprecated BYE/Also transfer method.  Ask vendor to support REFER instead\n",
10853          ast_inet_ntoa(iabuf, sizeof(iabuf), p->recv.sin_addr));
10854       if (ast_strlen_zero(p->context))
10855          strcpy(p->context, default_context);
10856       res = get_also_info(p, req);
10857       if (!res) {
10858          c = p->owner;
10859          if (c) {
10860             bridged_to = ast_bridged_channel(c);
10861             if (bridged_to) {
10862                /* Don't actually hangup here... */
10863                ast_moh_stop(bridged_to);
10864                ast_async_goto(bridged_to, p->context, p->refer_to,1);
10865             } else
10866                ast_queue_hangup(p->owner);
10867          }
10868       } else {
10869          ast_log(LOG_WARNING, "Invalid transfer information from '%s'\n", ast_inet_ntoa(iabuf, sizeof(iabuf), p->recv.sin_addr));
10870          if (p->owner)
10871             ast_queue_hangup(p->owner);
10872       }
10873    } else if (p->owner) {
10874       ast_queue_hangup(p->owner);
10875       if (option_debug > 2)
10876          ast_log(LOG_DEBUG, "Received bye, issuing owner hangup\n.");
10877    } else {
10878       ast_set_flag(p, SIP_NEEDDESTROY);   
10879       if (option_debug > 2)
10880          ast_log(LOG_DEBUG, "Received bye, no owner, selfdestruct soon.\n.");
10881    }
10882    transmit_response(p, "200 OK", req);
10883 
10884    return 1;
10885 }

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 10801 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().

10802 {
10803       
10804    check_via(p, req);
10805    ast_set_flag(p, SIP_ALREADYGONE);   
10806    if (p->rtp) {
10807       /* Immediately stop RTP */
10808       ast_rtp_stop(p->rtp);
10809    }
10810    if (p->vrtp) {
10811       /* Immediately stop VRTP */
10812       ast_rtp_stop(p->vrtp);
10813    }
10814    if (p->owner)
10815       ast_queue_hangup(p->owner);
10816    else
10817       ast_set_flag(p, SIP_NEEDDESTROY);   
10818    if (p->initreq.len > 0) {
10819       if (!ignore)
10820          transmit_response_reliable(p, "487 Request Terminated", &p->initreq, 1);
10821       transmit_response(p, "200 OK", req);
10822       return 1;
10823    } else {
10824       transmit_response(p, "481 Call Leg Does Not Exist", req);
10825       return 0;
10826    }
10827 }

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

handle_request_info: Receive SIP INFO Message ---

Definition at line 8783 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().

08784 {
08785    char buf[1024];
08786    unsigned int event;
08787    char *c;
08788    
08789    /* Need to check the media/type */
08790    if (!strcasecmp(get_header(req, "Content-Type"), "application/dtmf-relay") ||
08791        !strcasecmp(get_header(req, "Content-Type"), "application/vnd.nortelnetworks.digits")) {
08792 
08793       /* Try getting the "signal=" part */
08794       if (ast_strlen_zero(c = get_body(req, "Signal")) && ast_strlen_zero(c = get_body(req, "d"))) {
08795          ast_log(LOG_WARNING, "Unable to retrieve DTMF signal from INFO message from %s\n", p->callid);
08796          transmit_response(p, "200 OK", req); /* Should return error */
08797          return;
08798       } else {
08799          ast_copy_string(buf, c, sizeof(buf));
08800       }
08801    
08802       if (!p->owner) {  /* not a PBX call */
08803          transmit_response(p, "481 Call leg/transaction does not exist", req);
08804          ast_set_flag(p, SIP_NEEDDESTROY);
08805          return;
08806       }
08807 
08808       if (ast_strlen_zero(buf)) {
08809          transmit_response(p, "200 OK", req);
08810          return;
08811       }
08812 
08813       if (buf[0] == '*')
08814          event = 10;
08815       else if (buf[0] == '#')
08816          event = 11;
08817       else if ((buf[0] >= 'A') && (buf[0] <= 'D'))
08818          event = 12 + buf[0] - 'A';
08819       else
08820          event = atoi(buf);
08821       if (event == 16) {
08822          /* send a FLASH event */
08823          struct ast_frame f = { AST_FRAME_CONTROL, AST_CONTROL_FLASH, };
08824          ast_queue_frame(p->owner, &f);
08825          if (sipdebug)
08826             ast_verbose("* DTMF-relay event received: FLASH\n");
08827       } else {
08828          /* send a DTMF event */
08829          struct ast_frame f = { AST_FRAME_DTMF, };
08830          if (event < 10) {
08831             f.subclass = '0' + event;
08832          } else if (event < 11) {
08833             f.subclass = '*';
08834          } else if (event < 12) {
08835             f.subclass = '#';
08836          } else if (event < 16) {
08837             f.subclass = 'A' + (event - 12);
08838          }
08839          ast_queue_frame(p->owner, &f);
08840          if (sipdebug)
08841             ast_verbose("* DTMF-relay event received: %c\n", f.subclass);
08842       }
08843       transmit_response(p, "200 OK", req);
08844       return;
08845    } else if (!strcasecmp(get_header(req, "Content-Type"), "application/media_control+xml")) {
08846       /* Eh, we'll just assume it's a fast picture update for now */
08847       if (p->owner)
08848          ast_queue_control(p->owner, AST_CONTROL_VIDUPDATE);
08849       transmit_response(p, "200 OK", req);
08850       return;
08851    } else if ((c = get_header(req, "X-ClientCode"))) {
08852       /* Client code (from SNOM phone) */
08853       if (ast_test_flag(p, SIP_USECLIENTCODE)) {
08854          if (p->owner && p->owner->cdr)
08855             ast_cdr_setuserfield(p->owner, c);
08856          if (p->owner && ast_bridged_channel(p->owner) && ast_bridged_channel(p->owner)->cdr)
08857             ast_cdr_setuserfield(ast_bridged_channel(p->owner), c);
08858          transmit_response(p, "200 OK", req);
08859       } else {
08860          transmit_response(p, "403 Unauthorized", req);
08861       }
08862       return;
08863    }
08864    /* Other type of INFO message, not really understood by Asterisk */
08865    /* if (get_msg_text(buf, sizeof(buf), req)) { */
08866 
08867    ast_log(LOG_WARNING, "Unable to parse INFO message from %s. Content %s\n", p->callid, buf);
08868    transmit_response(p, "415 Unsupported media type", req);
08869    return;
08870 }

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 10465 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().

10466 {
10467    int res = 1;
10468    struct ast_channel *c=NULL;
10469    int gotdest;
10470    struct ast_frame af = { AST_FRAME_NULL, };
10471    char *supported;
10472    char *required;
10473    unsigned int required_profile = 0;
10474 
10475    /* Find out what they support */
10476    if (!p->sipoptions) {
10477       supported = get_header(req, "Supported");
10478       if (supported)
10479          parse_sip_options(p, supported);
10480    }
10481    required = get_header(req, "Require");
10482    if (!ast_strlen_zero(required)) {
10483       required_profile = parse_sip_options(NULL, required);
10484       if (required_profile) {    /* They require something */
10485          /* At this point we support no extensions, so fail */
10486          transmit_response_with_unsupported(p, "420 Bad extension", req, required);
10487          if (!p->lastinvite)
10488             ast_set_flag(p, SIP_NEEDDESTROY);   
10489          return -1;
10490          
10491       }
10492    }
10493 
10494    /* Check if this is a loop */
10495    /* This happens since we do not properly support SIP domain
10496       handling yet... -oej */
10497    if (ast_test_flag(p, SIP_OUTGOING) && p->owner && (p->owner->_state != AST_STATE_UP)) {
10498       /* This is a call to ourself.  Send ourselves an error code and stop
10499          processing immediately, as SIP really has no good mechanism for
10500          being able to call yourself */
10501       transmit_response(p, "482 Loop Detected", req);
10502       /* We do NOT destroy p here, so that our response will be accepted */
10503       return 0;
10504    }
10505    if (!ignore) {
10506       /* Use this as the basis */
10507       if (debug)
10508          ast_verbose("Using INVITE request as basis request - %s\n", p->callid);
10509       sip_cancel_destroy(p);
10510       /* This call is no longer outgoing if it ever was */
10511       ast_clear_flag(p, SIP_OUTGOING);
10512       /* This also counts as a pending invite */
10513       p->pendinginvite = seqno;
10514       copy_request(&p->initreq, req);
10515       check_via(p, req);
10516       if (p->owner) {
10517          /* Handle SDP here if we already have an owner */
10518          if (find_sdp(req)) {
10519             if (process_sdp(p, req)) {
10520                transmit_response(p, "488 Not acceptable here", req);
10521                if (!p->lastinvite)
10522                   ast_set_flag(p, SIP_NEEDDESTROY);   
10523                return -1;
10524             }
10525          } else {
10526             p->jointcapability = p->capability;
10527             ast_log(LOG_DEBUG, "Hm....  No sdp for the moment\n");
10528          }
10529       }
10530    } else if (debug)
10531       ast_verbose("Ignoring this INVITE request\n");
10532    if (!p->lastinvite && !ignore && !p->owner) {
10533       /* Handle authentication if this is our first invite */
10534       res = check_user(p, req, SIP_INVITE, e, 1, sin, ignore);
10535       /* if an authentication challenge was sent, we are done here */
10536       if (res > 0)
10537          return 0;
10538       if (res < 0) {
10539          if (res == -4) {
10540             ast_log(LOG_NOTICE, "Sending fake auth rejection for user %s\n", get_header(req, "From"));
10541             transmit_fake_auth_response(p, req, p->randdata, sizeof(p->randdata), 1);
10542          } else {
10543             ast_log(LOG_NOTICE, "Failed to authenticate user %s\n", get_header(req, "From"));
10544             if (ignore)
10545                transmit_response(p, "403 Forbidden", req);
10546             else
10547                transmit_response_reliable(p, "403 Forbidden", req, 1);
10548          }
10549          ast_set_flag(p, SIP_NEEDDESTROY);   
10550          p->theirtag[0] = '\0'; /* Forget their to-tag, we'll get a new one */
10551          return 0;
10552       }
10553       /* Process the SDP portion */
10554       if (find_sdp(req)) {
10555          if (process_sdp(p, req)) {
10556             transmit_response(p, "488 Not acceptable here", req);
10557             ast_set_flag(p, SIP_NEEDDESTROY);   
10558             return -1;
10559          }
10560       } else {
10561          p->jointcapability = p->capability;
10562          ast_log(LOG_DEBUG, "Hm....  No sdp for the moment\n");
10563       }
10564       /* Queue NULL frame to prod ast_rtp_bridge if appropriate */
10565       if (p->owner)
10566          ast_queue_frame(p->owner, &af);
10567       /* Initialize the context if it hasn't been already */
10568       if (ast_strlen_zero(p->context))
10569          strcpy(p->context, default_context);
10570       /* Check number of concurrent calls -vs- incoming limit HERE */
10571       ast_log(LOG_DEBUG, "Checking SIP call limits for device %s\n", p->username);
10572       res = update_call_counter(p, INC_CALL_LIMIT);
10573       if (res) {
10574          if (res < 0) {
10575             ast_log(LOG_NOTICE, "Failed to place call for user %s, too many calls\n", p->username);
10576             if (ignore)
10577                transmit_response(p, "480 Temporarily Unavailable (Call limit)", req);
10578             else
10579                transmit_response_reliable(p, "480 Temporarily Unavailable (Call limit) ", req, 1);
10580             ast_set_flag(p, SIP_NEEDDESTROY);   
10581          }
10582          return 0;
10583       }
10584       /* Get destination right away */
10585       gotdest = get_destination(p, NULL);
10586 
10587       get_rdnis(p, NULL);
10588       extract_uri(p, req);
10589       build_contact(p);
10590 
10591       if (gotdest) {
10592          if (gotdest < 0) {
10593             if (ignore)
10594                transmit_response(p, "404 Not Found", req);
10595             else
10596                transmit_response_reliable(p, "404 Not Found", req, 1);
10597             update_call_counter(p, DEC_CALL_LIMIT);
10598          } else {
10599             if (ignore)
10600                transmit_response(p, "484 Address Incomplete", req);
10601             else
10602                transmit_response_reliable(p, "484 Address Incomplete", req, 1);
10603             update_call_counter(p, DEC_CALL_LIMIT);
10604          }
10605          ast_set_flag(p, SIP_NEEDDESTROY);      
10606       } else {
10607          /* If no extension was specified, use the s one */
10608          if (ast_strlen_zero(p->exten))
10609             ast_copy_string(p->exten, "s", sizeof(p->exten));
10610          /* Initialize tag */ 
10611          make_our_tag(p->tag, sizeof(p->tag));
10612          /* First invitation */
10613          c = sip_new(p, AST_STATE_DOWN, ast_strlen_zero(p->username) ? NULL : p->username );
10614          *recount = 1;
10615          /* Save Record-Route for any later requests we make on this dialogue */
10616          build_route(p, req, 0);
10617          if (c) {
10618             /* Pre-lock the call */
10619             ast_mutex_lock(&c->lock);
10620          }
10621       }
10622       
10623    } else {
10624       if (option_debug > 1 && sipdebug)
10625          ast_log(LOG_DEBUG, "Got a SIP re-invite for call %s\n", p->callid);
10626       c = p->owner;
10627    }
10628    if (!ignore && p)
10629       p->lastinvite = seqno;
10630    if (c) {
10631 #ifdef OSP_SUPPORT
10632       ast_channel_setwhentohangup (c, p->osptimelimit);
10633 #endif
10634       switch(c->_state) {
10635       case AST_STATE_DOWN:
10636          transmit_response(p, "100 Trying", req);
10637          ast_setstate(c, AST_STATE_RING);
10638          if (strcmp(p->exten, ast_pickup_ext())) {
10639             enum ast_pbx_result res;
10640 
10641             res = ast_pbx_start(c);
10642 
10643             switch (res) {
10644             case AST_PBX_FAILED:
10645                ast_log(LOG_WARNING, "Failed to start PBX :(\n");
10646                if (ignore)
10647                   transmit_response(p, "503 Unavailable", req);
10648                else
10649                   transmit_response_reliable(p, "503 Unavailable", req, 1);
10650                break;
10651             case AST_PBX_CALL_LIMIT:
10652                ast_log(LOG_WARNING, "Failed to start PBX (call limit reached) \n");
10653                if (ignore)
10654                   transmit_response(p, "480 Temporarily Unavailable", req);
10655                else
10656                   transmit_response_reliable(p, "480 Temporarily Unavailable", req, 1);
10657                break;
10658             case AST_PBX_SUCCESS:
10659                /* nothing to do */
10660                break;
10661             }
10662 
10663             if (res) {
10664                ast_log(LOG_WARNING, "Failed to start PBX :(\n");
10665                /* Unlock locks so ast_hangup can do its magic */
10666                ast_mutex_unlock(&c->lock);
10667                ast_mutex_unlock(&p->lock);
10668                ast_hangup(c);
10669                ast_mutex_lock(&p->lock);
10670                c = NULL;
10671             }
10672          } else {
10673             ast_mutex_unlock(&c->lock);
10674             if (ast_pickup_call(c)) {
10675                ast_log(LOG_NOTICE, "Nothing to pick up\n");
10676                if (ignore)
10677                   transmit_response(p, "503 Unavailable", req);
10678                else
10679                   transmit_response_reliable(p, "503 Unavailable", req, 1);
10680                ast_set_flag(p, SIP_ALREADYGONE);   
10681                /* Unlock locks so ast_hangup can do its magic */
10682                ast_mutex_unlock(&p->lock);
10683                ast_hangup(c);
10684                ast_mutex_lock(&p->lock);
10685                c = NULL;
10686             } else {
10687                ast_mutex_unlock(&p->lock);
10688                ast_setstate(c, AST_STATE_DOWN);
10689                ast_hangup(c);
10690                ast_mutex_lock(&p->lock);
10691                c = NULL;
10692             }
10693          }
10694          break;
10695       case AST_STATE_RING:
10696          transmit_response(p, "100 Trying", req);
10697          break;
10698       case AST_STATE_RINGING:
10699          transmit_response(p, "180 Ringing", req);
10700          break;
10701       case AST_STATE_UP:
10702          transmit_response_with_sdp(p, "200 OK", req, 1);
10703          break;
10704       default:
10705          ast_log(LOG_WARNING, "Don't know how to handle INVITE in state %d\n", c->_state);
10706          transmit_response(p, "100 Trying", req);
10707       }
10708    } else {
10709       if (p && !ast_test_flag(p, SIP_NEEDDESTROY) && !ignore) {
10710          if (!p->jointcapability) {
10711             if (ignore)
10712                transmit_response(p, "488 Not Acceptable Here (codec error)", req);
10713             else
10714                transmit_response_reliable(p, "488 Not Acceptable Here (codec error)", req, 1);
10715             ast_set_flag(p, SIP_NEEDDESTROY);   
10716          } else {
10717             ast_log(LOG_NOTICE, "Unable to create/find channel\n");
10718             if (ignore)
10719                transmit_response(p, "503 Unavailable", req);
10720             else
10721                transmit_response_reliable(p, "503 Unavailable", req, 1);
10722             ast_set_flag(p, SIP_NEEDDESTROY);   
10723          }
10724       }
10725    }
10726    return res;
10727 }

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

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

Referenced by handle_request().

10889 {
10890    if (!ignore) {
10891       if (debug)
10892          ast_verbose("Receiving message!\n");
10893       receive_message(p, req);
10894    } else {
10895       transmit_response(p, "202 Accepted", req);
10896    }
10897    return 1;
10898 }

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

References ast_set_flag, ast_strlen_zero(), build_contact(), sip_pvt::context, default_context, get_destination(), sip_pvt::lastinvite, SIP_NEEDDESTROY, and transmit_response_with_allow().

Referenced by handle_request().

10442 {
10443    int res;
10444 
10445    res = get_destination(p, req);
10446    build_contact(p);
10447    /* XXX Should we authenticate OPTIONS? XXX */
10448    if (ast_strlen_zero(p->context))
10449       strcpy(p->context, default_context);
10450    if (res < 0)
10451       transmit_response_with_allow(p, "404 Not Found", req, 0);
10452    else if (res > 0)
10453       transmit_response_with_allow(p, "484 Address Incomplete", req, 0);
10454    else 
10455       transmit_response_with_allow(p, "200 OK", req, 0);
10456    /* Destroy if this OPTIONS was the opening request, but not if
10457       it's in the middle of a normal call flow. */
10458    if (!p->lastinvite)
10459       ast_set_flag(p, SIP_NEEDDESTROY);   
10460 
10461    return res;
10462 }

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 10730 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().

10731 {
10732    struct ast_channel *c=NULL;
10733    int res;
10734    struct ast_channel *transfer_to;
10735    char *transfercontext = NULL;
10736 
10737    if (option_debug > 2)
10738       ast_log(LOG_DEBUG, "SIP call transfer received for call %s (REFER)!\n", p->callid);
10739    res = get_refer_info(p, req, &transfercontext);
10740    if (ast_strlen_zero(p->context))
10741       strcpy(p->context, default_context);
10742    if (ast_strlen_zero(transfercontext))
10743       transfercontext = p->context;
10744    if (res < 0)
10745       transmit_response(p, "603 Declined", req);
10746    else if (res > 0)
10747       transmit_response(p, "484 Address Incomplete", req);
10748    else {
10749       int nobye = 0;
10750       if (!ignore) {
10751          if (p->refer_call) {
10752             ast_log(LOG_DEBUG,"202 Accepted (supervised)\n");
10753             attempt_transfer(p, p->refer_call);
10754             if (p->refer_call->owner)
10755                ast_mutex_unlock(&p->refer_call->owner->lock);
10756             ast_mutex_unlock(&p->refer_call->lock);
10757             p->refer_call = NULL;
10758             ast_set_flag(p, SIP_GOTREFER);   
10759          } else {
10760             ast_log(LOG_DEBUG,"202 Accepted (blind)\n");
10761             c = p->owner;
10762             if (c) {
10763                transfer_to = ast_bridged_channel(c);
10764                if (transfer_to) {
10765                   ast_log(LOG_DEBUG, "Got SIP blind transfer, applying to '%s'\n", transfer_to->name);
10766                   ast_moh_stop(transfer_to);
10767                   if (!strcmp(p->refer_to, ast_parking_ext())) {
10768                      /* Must release c's lock now, because it will not longer
10769                          be accessible after the transfer! */
10770                      *nounlock = 1;
10771                      ast_mutex_unlock(&c->lock);
10772                      sip_park(transfer_to, c, req);
10773                      nobye = 1;
10774                   } else {
10775                      /* Must release c's lock now, because it will not longer
10776                          be accessible after the transfer! */
10777                      *nounlock = 1;
10778                      ast_mutex_unlock(&c->lock);
10779                      ast_async_goto(transfer_to, transfercontext, p->refer_to,1);
10780                   }
10781                } else {
10782                   ast_log(LOG_DEBUG, "Got SIP blind transfer but nothing to transfer to.\n");
10783                   ast_queue_hangup(p->owner);
10784                }
10785             }
10786             ast_set_flag(p, SIP_GOTREFER);   
10787          }
10788          transmit_response(p, "202 Accepted", req);
10789          transmit_notify_with_sipfrag(p, seqno);
10790          /* Always increment on a BYE */
10791          if (!nobye) {
10792             transmit_request_with_auth(p, SIP_BYE, 0, 1, 1);
10793             ast_set_flag(p, SIP_ALREADYGONE);   
10794          }
10795       }
10796    }
10797    return res;
10798 }

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 11120 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().

11121 {
11122    int res = 0;
11123    char iabuf[INET_ADDRSTRLEN];
11124 
11125    /* Use this as the basis */
11126    if (debug)
11127       ast_verbose("Using latest REGISTER request as basis request\n");
11128    copy_request(&p->initreq, req);
11129    check_via(p, req);
11130    if ((res = register_verify(p, sin, req, e, ignore)) < 0) 
11131       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"));
11132    if (res < 1) {
11133       /* Destroy the session, but keep us around for just a bit in case they don't
11134          get our 200 OK */
11135       sip_scheddestroy(p, 15*1000);
11136    }
11137    return res;
11138 }

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 10900 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().

10901 {
10902    int gotdest;
10903    int res = 0;
10904    int firststate = AST_EXTENSION_REMOVED;
10905 
10906    if (p->initreq.headers) {  
10907       /* We already have a dialog */
10908       if (p->initreq.method != SIP_SUBSCRIBE) {
10909          /* This is a SUBSCRIBE within another SIP dialog, which we do not support */
10910          /* For transfers, this could happen, but since we haven't seen it happening, let us just refuse this */
10911          transmit_response(p, "403 Forbidden (within dialog)", req);
10912          /* Do not destroy session, since we will break the call if we do */
10913          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);
10914          return 0;
10915       } else {
10916          if (debug)
10917             ast_log(LOG_DEBUG, "Got a re-subscribe on existing subscription %s\n", p->callid);
10918       }
10919    }
10920    if (!ignore && !p->initreq.headers) {
10921       /* Use this as the basis */
10922       if (debug)
10923          ast_verbose("Using latest SUBSCRIBE request as basis request\n");
10924       /* This call is no longer outgoing if it ever was */
10925       ast_clear_flag(p, SIP_OUTGOING);
10926       copy_request(&p->initreq, req);
10927       check_via(p, req);
10928    } else if (debug && ignore)
10929       ast_verbose("Ignoring this SUBSCRIBE request\n");
10930 
10931    if (!p->lastinvite) {
10932       char mailboxbuf[256]="";
10933       int found = 0;
10934       char *mailbox = NULL;
10935       int mailboxsize = 0;
10936       char *eventparam;
10937 
10938       char *event = get_header(req, "Event");   /* Get Event package name */
10939       char *accept = get_header(req, "Accept");
10940 
10941       /* Find parameters to Event: header value and remove them for now */
10942       eventparam = strchr(event, ';');
10943       if (eventparam) {
10944          *eventparam = '\0';
10945          eventparam++;
10946       }
10947 
10948       if (!strcmp(event, "message-summary") && !strcmp(accept, "application/simple-message-summary")) {
10949          mailbox = mailboxbuf;
10950          mailboxsize = sizeof(mailboxbuf);
10951       }
10952       /* Handle authentication if this is our first subscribe */
10953       res = check_user_full(p, req, SIP_SUBSCRIBE, e, 0, sin, ignore, mailbox, mailboxsize);
10954       /* if an authentication challenge was sent, we are done here */
10955       if (res > 0)
10956          return 0;
10957       if (res < 0) {
10958          if (res == -4) {
10959             ast_log(LOG_NOTICE, "Sending fake auth rejection for user %s\n", get_header(req, "From"));
10960             transmit_fake_auth_response(p, req, p->randdata, sizeof(p->randdata), 1);
10961          } else {
10962             ast_log(LOG_NOTICE, "Failed to authenticate user %s for SUBSCRIBE\n", get_header(req, "From"));
10963             if (ignore)
10964                transmit_response(p, "403 Forbidden", req);
10965             else
10966                transmit_response_reliable(p, "403 Forbidden", req, 1);
10967          }
10968          ast_set_flag(p, SIP_NEEDDESTROY);   
10969          return 0;
10970       }
10971       gotdest = get_destination(p, NULL);
10972       /* Initialize the context if it hasn't been already;
10973          note this is done _after_ handling any domain lookups,
10974          because the context specified there is for calls, not
10975          subscriptions
10976       */
10977       if (!ast_strlen_zero(p->subscribecontext))
10978          ast_copy_string(p->context, p->subscribecontext, sizeof(p->context));
10979       else if (ast_strlen_zero(p->context))
10980          strcpy(p->context, default_context);
10981       /* Get destination right away */
10982       build_contact(p);
10983       if (gotdest) {
10984          if (gotdest < 0)
10985             transmit_response(p, "404 Not Found", req);
10986          else
10987             transmit_response(p, "484 Address Incomplete", req);  /* Overlap dialing on SUBSCRIBE?? */
10988          ast_set_flag(p, SIP_NEEDDESTROY);   
10989       } else {
10990 
10991          /* Initialize tag for new subscriptions */   
10992          if (ast_strlen_zero(p->tag))
10993             make_our_tag(p->tag, sizeof(p->tag));
10994 
10995          if (!strcmp(event, "presence") || !strcmp(event, "dialog")) { /* Presence, RFC 3842 */
10996 
10997             /* Header from Xten Eye-beam Accept: multipart/related, application/rlmi+xml, application/pidf+xml, application/xpidf+xml */
10998             /* Polycom phones only handle xpidf+xml, even if they say they can
10999                handle pidf+xml as well
11000             */
11001             if (strstr(p->useragent, "Polycom")) {
11002                p->subscribed = XPIDF_XML;
11003             } else if (strstr(accept, "application/pidf+xml")) {
11004                p->subscribed = PIDF_XML;         /* RFC 3863 format */
11005             } else if (strstr(accept, "application/dialog-info+xml")) {
11006                p->subscribed = DIALOG_INFO_XML;
11007                /* IETF draft: draft-ietf-sipping-dialog-package-05.txt */
11008             } else if (strstr(accept, "application/cpim-pidf+xml")) {
11009                p->subscribed = CPIM_PIDF_XML;    /* RFC 3863 format */
11010             } else if (strstr(accept, "application/xpidf+xml")) {
11011                p->subscribed = XPIDF_XML;        /* Early pre-RFC 3863 format with MSN additions (Microsoft Messenger) */
11012             } else {
11013                /* Can't find a format for events that we know about */
11014                transmit_response(p, "489 Bad Event", req);
11015                ast_set_flag(p, SIP_NEEDDESTROY);   
11016                return 0;
11017             }
11018          } else if (!strcmp(event, "message-summary") && !strcmp(accept, "application/simple-message-summary")) {
11019             /* Looks like they actually want a mailbox status */
11020 
11021             /* At this point, we should check if they subscribe to a mailbox that
11022               has the same extension as the peer or the mailbox id. If we configure
11023               the context to be the same as a SIP domain, we could check mailbox
11024               context as well. To be able to securely accept subscribes on mailbox
11025               IDs, not extensions, we need to check the digest auth user to make
11026               sure that the user has access to the mailbox.
11027              
11028               Since we do not act on this subscribe anyway, we might as well 
11029               accept any authenticated peer with a mailbox definition in their 
11030               config section.
11031             
11032             */
11033             if (!ast_strlen_zero(mailbox)) {
11034                found++;
11035             }
11036 
11037             if (found){
11038                transmit_response(p, "200 OK", req);
11039                ast_set_flag(p, SIP_NEEDDESTROY);   
11040             } else {
11041                transmit_response(p, "404 Not found", req);
11042                ast_set_flag(p, SIP_NEEDDESTROY);   
11043             }
11044             return 0;
11045          } else { /* At this point, Asterisk does not understand the specified event */
11046             transmit_response(p, "489 Bad Event", req);
11047             if (option_debug > 1)
11048                ast_log(LOG_DEBUG, "Received SIP subscribe for unknown event package: %s\n", event);
11049             ast_set_flag(p, SIP_NEEDDESTROY);   
11050             return 0;
11051          }
11052          if (p->subscribed != NONE)
11053             p->stateid = ast_extension_state_add(p->context, p->exten, cb_extensionstate, p);
11054       }
11055    }
11056 
11057    if (!ignore && p)
11058       p->lastinvite = seqno;
11059    if (p && !ast_test_flag(p, SIP_NEEDDESTROY)) {
11060       p->expiry = atoi(get_header(req, "Expires"));
11061 
11062       /* The next 4 lines can be removed if the SNOM Expires bug is fixed */
11063       if (p->subscribed == DIALOG_INFO_XML) {  
11064          if (p->expiry > max_expiry)
11065             p->expiry = max_expiry;
11066       }
11067       if (sipdebug || option_debug > 1)
11068          ast_log(LOG_DEBUG, "Adding subscription for extension %s context %s for peer %s\n", p->exten, p->context, p->username);
11069       if (p->autokillid > -1)
11070          sip_cancel_destroy(p);  /* Remove subscription expiry for renewals */
11071       sip_scheddestroy(p, (p->expiry + 10) * 1000);   /* Set timer for destruction of call at expiration */
11072 
11073       if ((firststate = ast_extension_state(NULL, p->context, p->exten)) < 0) {
11074          char iabuf[INET_ADDRSTRLEN];
11075 
11076          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));
11077          transmit_response(p, "404 Not found", req);
11078          ast_set_flag(p, SIP_NEEDDESTROY);   
11079          return 0;
11080       } else {
11081          struct sip_pvt *p_old;
11082 
11083          transmit_response(p, "200 OK", req);
11084          transmit_state_notify(p, firststate, 1, 1);  /* Send first notification */
11085          append_history(p, "Subscribestatus", ast_extension_state2str(firststate));
11086 
11087          /* remove any old subscription from this peer for the same exten/context,
11088             as the peer has obviously forgotten about it and it's wasteful to wait
11089             for it to expire and send NOTIFY messages to the peer only to have them
11090             ignored (or generate errors)
11091          */
11092          ast_mutex_lock(&iflock);
11093          for (p_old = iflist; p_old; p_old = p_old->next) {
11094             if (p_old == p)
11095                continue;
11096             if (p_old->initreq.method != SIP_SUBSCRIBE)
11097                continue;
11098             if (p_old->subscribed == NONE)
11099                continue;
11100             ast_mutex_lock(&p_old->lock);
11101             if (!strcmp(p_old->username, p->username)) {
11102                if (!strcmp(p_old->exten, p->exten) &&
11103                    !strcmp(p_old->context, p->context)) {
11104                   ast_set_flag(p_old, SIP_NEEDDESTROY);
11105                   ast_mutex_unlock(&p_old->lock);
11106                   break;
11107                }
11108             }
11109             ast_mutex_unlock(&p_old->lock);
11110          }
11111          ast_mutex_unlock(&iflock);
11112       }
11113       if (!p->expiry)
11114          ast_set_flag(p, SIP_NEEDDESTROY);
11115    }
11116    return 1;
11117 }

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

09964 {
09965    char *msg, *c;
09966    struct ast_channel *owner;
09967    char iabuf[INET_ADDRSTRLEN];
09968    int sipmethod;
09969    int res = 1;
09970 
09971    c = get_header(req, "Cseq");
09972    msg = strchr(c, ' ');
09973    if (!msg)
09974       msg = "";
09975    else
09976       msg++;
09977    sipmethod = find_sip_method(msg);
09978 
09979    owner = p->owner;
09980    if (owner) 
09981       owner->hangupcause = hangup_sip2cause(resp);
09982 
09983    /* Acknowledge whatever it is destined for */
09984    if ((resp >= 100) && (resp <= 199))
09985       __sip_semi_ack(p, seqno, 0, sipmethod);
09986    else
09987       __sip_ack(p, seqno, 0, sipmethod);
09988 
09989    /* Get their tag if we haven't already */
09990    if (ast_strlen_zero(p->theirtag) || (resp >= 200)) {
09991       gettag(req, "To", p->theirtag, sizeof(p->theirtag));
09992    }
09993    if (p->peerpoke) {
09994       /* We don't really care what the response is, just that it replied back. 
09995          Well, as long as it's not a 100 response...  since we might
09996          need to hang around for something more "definitive" */
09997 
09998       res = handle_response_peerpoke(p, resp, rest, req, ignore, seqno, sipmethod);
09999    } else if (ast_test_flag(p, SIP_OUTGOING)) {
10000       /* Acknowledge sequence number */
10001       if (p->initid > -1) {
10002          /* Don't auto congest anymore since we've gotten something useful back */
10003          ast_sched_del(sched, p->initid);
10004          p->initid = -1;
10005       }
10006       switch(resp) {
10007       case 100:   /* 100 Trying */
10008          if (sipmethod == SIP_INVITE) 
10009             handle_response_invite(p, resp, rest, req, ignore, seqno);
10010          break;
10011       case 183:   /* 183 Session Progress */
10012          if (sipmethod == SIP_INVITE) 
10013             handle_response_invite(p, resp, rest, req, ignore, seqno);
10014          break;
10015       case 180:   /* 180 Ringing */
10016          if (sipmethod == SIP_INVITE) 
10017             handle_response_invite(p, resp, rest, req, ignore, seqno);
10018          break;
10019       case 200:   /* 200 OK */
10020          p->authtries = 0; /* Reset authentication counter */
10021          if (sipmethod == SIP_MESSAGE) {
10022             /* We successfully transmitted a message */
10023             ast_set_flag(p, SIP_NEEDDESTROY);   
10024          } else if (sipmethod == SIP_NOTIFY) {
10025             /* They got the notify, this is the end */
10026             if (p->owner) {
10027                ast_log(LOG_WARNING, "Notify answer on an owned channel?\n");
10028                ast_queue_hangup(p->owner);
10029             } else {
10030                if (p->subscribed == NONE) {
10031                   ast_set_flag(p, SIP_NEEDDESTROY); 
10032                }
10033             }
10034          } else if (sipmethod == SIP_INVITE) {
10035             handle_response_invite(p, resp, rest, req, ignore, seqno);
10036          } else if (sipmethod == SIP_REGISTER) {
10037             res = handle_response_register(p, resp, rest, req, ignore, seqno);
10038          } else if (sipmethod == SIP_BYE) {
10039             /* Ok, we're ready to go */
10040             ast_set_flag(p, SIP_NEEDDESTROY);   
10041          } 
10042          break;
10043       case 401: /* Not www-authorized on SIP method */
10044          if (sipmethod == SIP_INVITE) {
10045             handle_response_invite(p, resp, rest, req, ignore, seqno);
10046          } else if (p->registry && sipmethod == SIP_REGISTER) {
10047             res = handle_response_register(p, resp, rest, req, ignore, seqno);
10048          } else {
10049             ast_log(LOG_WARNING, "Got authentication request (401) on unknown %s to '%s'\n", sip_methods[sipmethod].text, get_header(req, "To"));
10050             ast_set_flag(p, SIP_NEEDDESTROY);   
10051          }
10052          break;
10053       case 403: /* Forbidden - we failed authentication */
10054          if (sipmethod == SIP_INVITE) {
10055             handle_response_invite(p, resp, rest, req, ignore, seqno);
10056          } else if (p->registry && sipmethod == SIP_REGISTER) {
10057             res = handle_response_register(p, resp, rest, req, ignore, seqno);
10058          } else {
10059             ast_log(LOG_WARNING, "Forbidden - wrong password on authentication for %s\n", msg);
10060          }
10061          break;
10062       case 404: /* Not found */
10063          if (p->registry && sipmethod == SIP_REGISTER) {
10064             res = handle_response_register(p, resp, rest, req, ignore, seqno);
10065          } else if (sipmethod == SIP_INVITE) {
10066             handle_response_invite(p, resp, rest, req, ignore, seqno);
10067          } else if (owner)
10068             ast_queue_control(p->owner, AST_CONTROL_CONGESTION);
10069          break;
10070       case 407: /* Proxy auth required */
10071          if (sipmethod == SIP_INVITE) {
10072             handle_response_invite(p, resp, rest, req, ignore, seqno);
10073          } else if (sipmethod == SIP_BYE || sipmethod == SIP_REFER) {
10074             if (ast_strlen_zero(p->authname))
10075                ast_log(LOG_WARNING, "Asked to authenticate %s, to %s:%d but we have no matching peer!\n",
10076                      msg, ast_inet_ntoa(iabuf, sizeof(iabuf), p->recv.sin_addr), ntohs(p->recv.sin_port));
10077                ast_set_flag(p, SIP_NEEDDESTROY);   
10078             if ((p->authtries == MAX_AUTHTRIES) || do_proxy_auth(p, req, "Proxy-Authenticate", "Proxy-Authorization", sipmethod, 0)) {
10079                ast_log(LOG_NOTICE, "Failed to authenticate on %s to '%s'\n", msg, get_header(&p->initreq, "From"));
10080                ast_set_flag(p, SIP_NEEDDESTROY);   
10081             }
10082          } else if (p->registry && sipmethod == SIP_REGISTER) {
10083             res = handle_response_register(p, resp, rest, req, ignore, seqno);
10084          } else   /* We can't handle this, giving up in a bad way */
10085             ast_set_flag(p, SIP_NEEDDESTROY);   
10086 
10087          break;
10088       case 491: /* Pending */
10089          if (sipmethod == SIP_INVITE) {
10090             handle_response_invite(p, resp, rest, req, ignore, seqno);
10091          }
10092       case 501: /* Not Implemented */
10093          if (sipmethod == SIP_INVITE) {
10094             handle_response_invite(p, resp, rest, req, ignore, seqno);
10095          } else
10096             ast_log(LOG_WARNING, "Host '%s' does not implement '%s'\n", ast_inet_ntoa(iabuf, sizeof(iabuf), p->sa.sin_addr), msg);
10097          break;
10098       default:
10099          if ((resp >= 300) && (resp < 700)) {
10100             if ((option_verbose > 2) && (resp != 487))
10101                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));
10102             ast_set_flag(p, SIP_ALREADYGONE);   
10103             if (p->rtp) {
10104                /* Immediately stop RTP */
10105                ast_rtp_stop(p->rtp);
10106             }
10107             if (p->vrtp) {
10108                /* Immediately stop VRTP */
10109                ast_rtp_stop(p->vrtp);
10110             }
10111             /* XXX Locking issues?? XXX */
10112             switch(resp) {
10113             case 300: /* Multiple Choices */
10114             case 301: /* Moved permenantly */
10115             case 302: /* Moved temporarily */
10116             case 305: /* Use Proxy */
10117                parse_moved_contact(p, req);
10118                /* Fall through */
10119             case 486: /* Busy here */
10120             case 600: /* Busy everywhere */
10121             case 603: /* Decline */
10122                if (p->owner)
10123                   ast_queue_control(p->owner, AST_CONTROL_BUSY);
10124                break;
10125             case 487:
10126                /* channel now destroyed - dec the inUse counter */
10127                if (owner)
10128                   ast_queue_hangup(p->owner);
10129                update_call_counter(p, DEC_CALL_LIMIT);
10130                break;
10131             case 482: /* SIP is incapable of performing a hairpin call, which
10132                          is yet another failure of not having a layer 2 (again, YAY
10133                       IETF for thinking ahead).  So we treat this as a call
10134                       forward and hope we end up at the right place... */
10135                ast_log(LOG_DEBUG, "Hairpin detected, setting up call forward for what it's worth\n");
10136                if (p->owner)
10137                   snprintf(p->owner->call_forward, sizeof(p->owner->call_forward), "Local/%s@%s", p->username, p->context);
10138                /* Fall through */
10139             case 488: /* Not acceptable here - codec error */
10140             case 480: /* Temporarily Unavailable */
10141             case 404: /* Not Found */
10142             case 410: /* Gone */
10143             case 400: /* Bad Request */
10144             case 500: /* Server error */
10145             case 503: /* Service Unavailable */
10146                if (owner)
10147                   ast_queue_control(p->owner, AST_CONTROL_CONGESTION);
10148                break;
10149             default:
10150                /* Send hangup */ 
10151                if (owner)
10152                   ast_queue_hangup(p->owner);
10153                break;
10154             }
10155             /* ACK on invite */
10156             if (sipmethod == SIP_INVITE) 
10157                transmit_request(p, SIP_ACK, seqno, 0, 0);
10158             ast_set_flag(p, SIP_ALREADYGONE);   
10159             if (!p->owner)
10160                ast_set_flag(p, SIP_NEEDDESTROY);   
10161          } else if ((resp >= 100) && (resp < 200)) {
10162             if (sipmethod == SIP_INVITE) {
10163                if (!ignore)
10164                   sip_cancel_destroy(p);
10165                if (find_sdp(req))
10166                   process_sdp(p, req);
10167                if (p->owner) {
10168                   /* Queue a progress frame */
10169                   ast_queue_control(p->owner, AST_CONTROL_PROGRESS);
10170                }
10171             }
10172          } else
10173             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));
10174       }
10175    } else { 
10176       /* Responses to OUTGOING SIP requests on INCOMING calls 
10177          get handled here. As well as out-of-call message responses */
10178       if (req->debug)
10179          ast_verbose("SIP Response message for INCOMING dialog %s arrived\n", msg);
10180       if (resp == 200) {
10181          /* Tags in early session is replaced by the tag in 200 OK, which is 
10182          the final reply to our INVITE */
10183          gettag(req, "To", p->theirtag, sizeof(p->theirtag));
10184       }
10185 
10186       switch(resp) {
10187       case 200:
10188          if (sipmethod == SIP_INVITE) {
10189             handle_response_invite(p, resp, rest, req, ignore, seqno);
10190          } else if (sipmethod == SIP_CANCEL) {
10191             ast_log(LOG_DEBUG, "Got 200 OK on CANCEL\n");
10192          } else if (sipmethod == SIP_MESSAGE) 
10193             /* We successfully transmitted a message */
10194             ast_set_flag(p, SIP_NEEDDESTROY);   
10195          else if (sipmethod == SIP_BYE) 
10196             /* Ok, we're ready to go */
10197             ast_set_flag(p, SIP_NEEDDESTROY);   
10198          break;
10199       case 401:   /* www-auth */
10200       case 407:
10201          if (sipmethod == SIP_BYE || sipmethod == SIP_REFER) {
10202             char *auth, *auth2;
10203 
10204             if (resp == 407) {
10205                auth = "Proxy-Authenticate";
10206                auth2 = "Proxy-Authorization";
10207             } else {
10208                auth = "WWW-Authenticate";
10209                auth2 = "Authorization";
10210             }
10211             if ((p->authtries == MAX_AUTHTRIES) || do_proxy_auth(p, req, auth, auth2, sipmethod, 0)) {
10212                ast_log(LOG_NOTICE, "Failed to authenticate on %s to '%s'\n", msg, get_header(&p->initreq, "From"));
10213                ast_set_flag(p, SIP_NEEDDESTROY);   
10214             }
10215          } else if (sipmethod == SIP_INVITE) {
10216             handle_response_invite(p, resp, rest, req, ignore, seqno);
10217          }
10218          break;
10219       case 481:   /* Call leg does not exist */
10220          if (sipmethod == SIP_INVITE) {
10221             /* Re-invite failed */
10222             handle_response_invite(p, resp, rest, req, ignore, seqno);
10223          }
10224          break;
10225       default: /* Errors without handlers */
10226          if ((resp >= 100) && (resp < 200)) {
10227             if (sipmethod == SIP_INVITE && !ignore)   /* re-invite */
10228                sip_cancel_destroy(p);
10229             
10230          }
10231          if ((resp >= 300) && (resp < 700)) {
10232             if ((option_verbose > 2) && (resp != 487))
10233                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));
10234             switch(resp) {
10235             case 488: /* Not acceptable here - codec error */
10236             case 603: /* Decline */
10237             case 500: /* Server error */
10238             case 503: /* Service Unavailable */
10239 
10240                if (sipmethod == SIP_INVITE && !ignore) { /* re-invite failed */
10241                   sip_cancel_destroy(p);
10242                }
10243                break;
10244             }
10245          }
10246          break;
10247       }
10248    }
10249 }

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 9633 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().

09634 {
09635    int outgoing = ast_test_flag(p, SIP_OUTGOING);
09636    
09637    if (option_debug > 3) {
09638       int reinvite = (p->owner && p->owner->_state == AST_STATE_UP);
09639       if (reinvite)
09640          ast_log(LOG_DEBUG, "SIP response %d to RE-invite on %s call %s\n", resp, outgoing ? "outgoing" : "incoming", p->callid);
09641       else
09642          ast_log(LOG_DEBUG, "SIP response %d to standard invite\n", resp);
09643    }
09644 
09645    if (ast_test_flag(p, SIP_ALREADYGONE)) { /* This call is already gone */
09646       ast_log(LOG_DEBUG, "Got response on call that is already terminated: %s (ignoring)\n", p->callid);
09647       return;
09648    }
09649 
09650    /* RFC3261 says we must treat every 1xx response (but not 100)
09651       that we don't recognize as if it was 183.
09652    */
09653    if ((resp > 100) &&
09654        (resp < 200) &&
09655        (resp != 180) &&
09656        (resp != 183))
09657       resp = 183;
09658 
09659    switch (resp) {
09660    case 100:   /* Trying */
09661       if (!ignore)
09662          sip_cancel_destroy(p);
09663       check_pendings(p);
09664       break;
09665    case 180:   /* 180 Ringing */
09666       if (!ignore)
09667          sip_cancel_destroy(p);
09668       if (!ignore && p->owner) {
09669          ast_queue_control(p->owner, AST_CONTROL_RINGING);
09670          if (p->owner->_state != AST_STATE_UP)
09671             ast_setstate(p->owner, AST_STATE_RINGING);
09672       }
09673       if (find_sdp(req)) {
09674          process_sdp(p, req);
09675          if (!ignore && p->owner) {
09676             /* Queue a progress frame only if we have SDP in 180 */
09677             ast_queue_control(p->owner, AST_CONTROL_PROGRESS);
09678          }
09679       }
09680       ast_set_flag(p, SIP_CAN_BYE);
09681       check_pendings(p);
09682       break;
09683    case 183:   /* Session progress */
09684       if (!ignore)
09685          sip_cancel_destroy(p);
09686       /* Ignore 183 Session progress without SDP */
09687       if (find_sdp(req)) {
09688          process_sdp(p, req);
09689          if (!ignore && p->owner) {
09690             /* Queue a progress frame */
09691             ast_queue_control(p->owner, AST_CONTROL_PROGRESS);
09692          }
09693       }
09694       ast_set_flag(p, SIP_CAN_BYE);
09695       check_pendings(p);
09696       break;
09697    case 200:   /* 200 OK on invite - someone's answering our call */
09698       if (!ignore)
09699          sip_cancel_destroy(p);
09700       p->authtries = 0;
09701       if (find_sdp(req)) {
09702          process_sdp(p, req);
09703       }
09704 
09705       /* Parse contact header for continued conversation */
09706       /* When we get 200 OK, we know which device (and IP) to contact for this call */
09707       /* This is important when we have a SIP proxy between us and the phone */
09708       if (outgoing) {
09709          parse_ok_contact(p, req);
09710 
09711          /* Save Record-Route for any later requests we make on this dialogue */
09712          build_route(p, req, 1);
09713       }
09714       
09715       if (!ignore && p->owner) {
09716          if (p->owner->_state != AST_STATE_UP) {
09717 #ifdef OSP_SUPPORT   
09718             time(&p->ospstart);
09719 #endif
09720             ast_queue_control(p->owner, AST_CONTROL_ANSWER);
09721          } else { /* RE-invite */
09722             struct ast_frame af = { AST_FRAME_NULL, };
09723             ast_queue_frame(p->owner, &af);
09724          }
09725       } else {
09726           /* It's possible we're getting an ACK after we've tried to disconnect
09727               by sending CANCEL */
09728          /* THIS NEEDS TO BE CHECKED: OEJ */
09729          if (!ignore)
09730             ast_set_flag(p, SIP_PENDINGBYE); 
09731       }
09732       /* If I understand this right, the branch is different for a non-200 ACK only */
09733       transmit_request(p, SIP_ACK, seqno, 0, 1);
09734       ast_set_flag(p, SIP_CAN_BYE);
09735       check_pendings(p);
09736       break;
09737    case 407: /* Proxy authentication */
09738    case 401: /* Www auth */
09739       /* First we ACK */
09740       transmit_request(p, SIP_ACK, seqno, 0, 0);
09741       if (p->options)
09742          p->options->auth_type = (resp == 401 ? WWW_AUTH : PROXY_AUTH);
09743 
09744       /* Then we AUTH */
09745       p->theirtag[0]='\0'; /* forget their old tag, so we don't match tags when getting response */
09746       if (!ignore) {
09747          char *authenticate = (resp == 401 ? "WWW-Authenticate" : "Proxy-Authenticate");
09748          char *authorization = (resp == 401 ? "Authorization" : "Proxy-Authorization");
09749          if ((p->authtries == MAX_AUTHTRIES) || do_proxy_auth(p, req, authenticate, authorization, SIP_INVITE, 1)) {
09750             ast_log(LOG_NOTICE, "Failed to authenticate on INVITE to '%s'\n", get_header(&p->initreq, "From"));
09751             ast_set_flag(p, SIP_NEEDDESTROY);   
09752             ast_set_flag(p, SIP_ALREADYGONE);   
09753             if (p->owner)
09754                ast_queue_control(p->owner, AST_CONTROL_CONGESTION);
09755          }
09756       }
09757       break;
09758    case 403: /* Forbidden */
09759       /* First we ACK */
09760       transmit_request(p, SIP_ACK, seqno, 0, 0);
09761       ast_log(LOG_WARNING, "Forbidden - wrong password on authentication for INVITE to '%s'\n", get_header(&p->initreq, "From"));
09762       if (!ignore && p->owner)
09763          ast_queue_control(p->owner, AST_CONTROL_CONGESTION);
09764       ast_set_flag(p, SIP_NEEDDESTROY);   
09765       ast_set_flag(p, SIP_ALREADYGONE);   
09766       break;
09767    case 404: /* Not found */
09768       transmit_request(p, SIP_ACK, seqno, 0, 0);
09769       if (p->owner && !ignore)
09770          ast_queue_control(p->owner, AST_CONTROL_CONGESTION);
09771       ast_set_flag(p, SIP_ALREADYGONE);   
09772       break;
09773    case 481: /* Call leg does not exist */
09774       /* Could be REFER or INVITE */
09775       ast_log(LOG_WARNING, "Re-invite to non-existing call leg on other UA. SIP dialog '%s'. Giving up.\n", p->callid);
09776       transmit_request(p, SIP_ACK, seqno, 0, 0);
09777       break;
09778    case 491: /* Pending */
09779       /* we have to wait a while, then retransmit */
09780       /* Transmission is rescheduled, so everything should be taken care of.
09781          We should support the retry-after at some point */
09782       break;
09783    case 501: /* Not implemented */
09784       if (p->owner)
09785          ast_queue_control(p->owner, AST_CONTROL_CONGESTION);
09786       break;
09787    }
09788 }

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 9907 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().

09908 {
09909    struct sip_peer *peer;
09910    int pingtime;
09911    struct timeval tv;
09912 
09913    if (resp != 100) {
09914       int statechanged = 0;
09915       int newstate = 0;
09916       peer = p->peerpoke;
09917       gettimeofday(&tv, NULL);
09918       pingtime = ast_tvdiff_ms(tv, peer->ps);
09919       if (pingtime < 1)
09920          pingtime = 1;
09921       if ((peer->lastms < 0)  || (peer->lastms > peer->maxms)) {
09922          if (pingtime <= peer->maxms) {
09923             ast_log(LOG_NOTICE, "Peer '%s' is now REACHABLE! (%dms / %dms)\n", peer->name, pingtime, peer->maxms);
09924             statechanged = 1;
09925             newstate = 1;
09926          }
09927       } else if ((peer->lastms > 0) && (peer->lastms <= peer->maxms)) {
09928          if (pingtime > peer->maxms) {
09929             ast_log(LOG_NOTICE, "Peer '%s' is now TOO LAGGED! (%dms / %dms)\n", peer->name, pingtime, peer->maxms);
09930             statechanged = 1;
09931             newstate = 2;
09932          }
09933       }
09934       if (!peer->lastms)
09935          statechanged = 1;
09936       peer->lastms = pingtime;
09937       peer->call = NULL;
09938       if (statechanged) {
09939          ast_device_state_changed("SIP/%s", peer->name);
09940          if (newstate == 2) {
09941             manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: SIP/%s\r\nPeerStatus: Lagged\r\nTime: %d\r\n", peer->name, pingtime);
09942          } else {
09943             manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: SIP/%s\r\nPeerStatus: Reachable\r\nTime: %d\r\n", peer->name, pingtime);
09944          }
09945       }
09946 
09947       if (peer->pokeexpire > -1)
09948          ast_sched_del(sched, peer->pokeexpire);
09949       if (sipmethod == SIP_INVITE)  /* Does this really happen? */
09950          transmit_request(p, SIP_ACK, seqno, 0, 0);
09951       ast_set_flag(p, SIP_NEEDDESTROY);   
09952 
09953       /* Try again eventually */
09954       if ((peer->lastms < 0)  || (peer->lastms > peer->maxms))
09955          peer->pokeexpire = ast_sched_add(sched, DEFAULT_FREQ_NOTOK, sip_poke_peer_s, peer);
09956       else
09957          peer->pokeexpire = ast_sched_add(sched, DEFAULT_FREQ_OK, sip_poke_peer_s, peer);
09958    }
09959    return 1;
09960 }

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

References __get_header(), ast_log(), ast_sched_del(), ast_set_flag, ast_strlen_zero(), sip_pvt::authtries, sip_registry::call, sip_registry::contact, do_register_auth(), EVENT_FLAG_SYSTEM, sip_registry::expire, get_header(), global_regattempts_max, sip_registry::hostname, sip_pvt::initreq, LOG_DEBUG, LOG_NOTICE, LOG_WARNING, manager_event(), MAX_AUTHTRIES, sip_pvt::our_contact, REG_STATE_REGISTERED, sip_registry::regattempts, sip_pvt::registry, sip_registry::regstate, regstate2str(), SIP_NEEDDESTROY, sip_scheddestroy(), sip_registry::timeout, and sip_registry::username.

Referenced by handle_response().

09792 {
09793    int expires, expires_ms;
09794    struct sip_registry *r;
09795    r=p->registry;
09796 
09797    switch (resp) {
09798    case 401:   /* Unauthorized */
09799       if ((p->authtries == MAX_AUTHTRIES) || do_register_auth(p, req, "WWW-Authenticate", "Authorization")) {
09800          ast_log(LOG_NOTICE, "Failed to authenticate on REGISTER to '%s@%s' (Tries %d)\n", p->registry->username, p->registry->hostname, p->authtries);
09801          ast_set_flag(p, SIP_NEEDDESTROY);   
09802          }
09803       break;
09804    case 403:   /* Forbidden */
09805       ast_log(LOG_WARNING, "Forbidden - wrong password on authentication for REGISTER for '%s' to '%s'\n", p->registry->username, p->registry->hostname);
09806       if (global_regattempts_max)
09807          p->registry->regattempts = global_regattempts_max+1;
09808       ast_sched_del(sched, r->timeout);
09809       ast_set_flag(p, SIP_NEEDDESTROY);   
09810       break;
09811    case 404:   /* Not found */
09812       ast_log(LOG_WARNING, "Got 404 Not found on SIP register to service %s@%s, giving up\n", p->registry->username,p->registry->hostname);
09813       if (global_regattempts_max)
09814          p->registry->regattempts = global_regattempts_max+1;
09815       ast_set_flag(p, SIP_NEEDDESTROY);   
09816       r->call = NULL;
09817       ast_sched_del(sched, r->timeout);
09818       break;
09819    case 407:   /* Proxy auth */
09820       if ((p->authtries == MAX_AUTHTRIES) || do_register_auth(p, req, "Proxy-Authenticate", "Proxy-Authorization")) {
09821          ast_log(LOG_NOTICE, "Failed to authenticate on REGISTER to '%s' (tries '%d')\n", get_header(&p->initreq, "From"), p->authtries);
09822          ast_set_flag(p, SIP_NEEDDESTROY);   
09823       }
09824       break;
09825    case 479:   /* SER: Not able to process the URI - address is wrong in register*/
09826       ast_log(LOG_WARNING, "Got error 479 on register to %s@%s, giving up (check config)\n", p->registry->username,p->registry->hostname);
09827       if (global_regattempts_max)
09828          p->registry->regattempts = global_regattempts_max+1;
09829       ast_set_flag(p, SIP_NEEDDESTROY);   
09830       r->call = NULL;
09831       ast_sched_del(sched, r->timeout);
09832       break;
09833    case 200:   /* 200 OK */
09834       if (!r) {
09835          ast_log(LOG_WARNING, "Got 200 OK on REGISTER that isn't a register\n");
09836          ast_set_flag(p, SIP_NEEDDESTROY);   
09837          return 0;
09838       }
09839 
09840       r->regstate=REG_STATE_REGISTERED;
09841       manager_event(EVENT_FLAG_SYSTEM, "Registry", "Channel: SIP\r\nDomain: %s\r\nStatus: %s\r\n", r->hostname, regstate2str(r->regstate));
09842       r->regattempts = 0;
09843       ast_log(LOG_DEBUG, "Registration successful\n");
09844       if (r->timeout > -1) {
09845          ast_log(LOG_DEBUG, "Cancelling timeout %d\n", r->timeout);
09846          ast_sched_del(sched, r->timeout);
09847       }
09848       r->timeout=-1;
09849       r->call = NULL;
09850       p->registry = NULL;
09851       /* Let this one hang around until we have all the responses */
09852       sip_scheddestroy(p, 32000);
09853       /* ast_set_flag(p, SIP_NEEDDESTROY);   */
09854 
09855       /* set us up for re-registering */
09856       /* figure out how long we got registered for */
09857       if (r->expire > -1)
09858          ast_sched_del(sched, r->expire);
09859       /* according to section 6.13 of RFC, contact headers override
09860          expires headers, so check those first */
09861       expires = 0;
09862       if (!ast_strlen_zero(get_header(req, "Contact"))) {
09863          char *contact = NULL;
09864          char *tmptmp = NULL;
09865          int start = 0;
09866          for(;;) {
09867             contact = __get_header(req, "Contact", &start);
09868             /* this loop ensures we get a contact header about our register request */
09869             if(!ast_strlen_zero(contact)) {
09870                if( (tmptmp=strstr(contact, p->our_contact))) {
09871                   contact=tmptmp;
09872                   break;
09873                }
09874             } else
09875                break;
09876          }
09877          tmptmp = strcasestr(contact, "expires=");
09878          if (tmptmp) {
09879             if (sscanf(tmptmp + 8, "%d;", &expires) != 1)
09880                expires = 0;
09881          }
09882 
09883       }
09884       if (!expires) 
09885          expires=atoi(get_header(req, "expires"));
09886       if (!expires)
09887          expires=default_expiry;
09888 
09889       expires_ms = expires * 1000;
09890       if (expires <= EXPIRY_GUARD_LIMIT)
09891          expires_ms -= MAX((expires_ms * EXPIRY_GUARD_PCT),EXPIRY_GUARD_MIN);
09892       else
09893          expires_ms -= EXPIRY_GUARD_SECS * 1000;
09894       if (sipdebug)
09895          ast_log(LOG_NOTICE, "Outbound Registration: Expiry for %s is %d sec (Scheduling reregistration in %d s)\n", r->hostname, expires, expires_ms/1000); 
09896 
09897       r->refresh= (int) expires_ms / 1000;
09898 
09899       /* Schedule re-registration before we expire */
09900       r->expire=ast_sched_add(sched, expires_ms, sip_reregister, r); 
09901       ASTOBJ_UNREF(r, sip_registry_destroy);
09902    }
09903    return 1;
09904 }

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 2366 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().

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

static int hangup_sip2cause int  cause  )  [static]
 

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

Definition at line 2297 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().

02298 {
02299 /* Possible values taken from causes.h */
02300 
02301    switch(cause) {
02302       case 603:   /* Declined */
02303       case 403:   /* Not found */
02304       case 487:   /* Call cancelled */
02305          return AST_CAUSE_CALL_REJECTED;
02306       case 404:   /* Not found */
02307          return AST_CAUSE_UNALLOCATED;
02308       case 408:   /* No reaction */
02309          return AST_CAUSE_NO_USER_RESPONSE;
02310       case 480:   /* No answer */
02311          return AST_CAUSE_FAILURE;
02312       case 483:   /* Too many hops */
02313          return AST_CAUSE_NO_ANSWER;
02314       case 486:   /* Busy everywhere */
02315          return AST_CAUSE_BUSY;
02316       case 488:   /* No codecs approved */
02317          return AST_CAUSE_BEARERCAPABILITY_NOTAVAIL;
02318       case 500:   /* Server internal failure */
02319          return AST_CAUSE_FAILURE;
02320       case 501:   /* Call rejected */
02321          return AST_CAUSE_FACILITY_REJECTED;
02322       case 502:   
02323          return AST_CAUSE_DESTINATION_OUT_OF_ORDER;
02324       case 503:   /* Service unavailable */
02325          return AST_CAUSE_CONGESTION;
02326       default:
02327          return AST_CAUSE_NORMAL;
02328    }
02329    /* Never reached */
02330    return 0;
02331 }

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

init_req: Initialize SIP request ---

Definition at line 4073 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.

04074 {
04075    /* Initialize a response */
04076    if (req->headers || req->len) {
04077       ast_log(LOG_WARNING, "Request already initialized?!?\n");
04078       return -1;
04079    }
04080    req->header[req->headers] = req->data + req->len;
04081    snprintf(req->header[req->headers], sizeof(req->data) - req->len, "%s %s SIP/2.0\r\n", sip_methods[sipmethod].text, recip);
04082    req->len += strlen(req->header[req->headers]);
04083    req->headers++;
04084    req->method = sipmethod;
04085    return 0;
04086 }

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

04058 {
04059    /* Initialize a response */
04060    if (req->headers || req->len) {
04061       ast_log(LOG_WARNING, "Request already initialized?!?\n");
04062       return -1;
04063    }
04064    req->method = SIP_RESPONSE;
04065    req->header[req->headers] = req->data + req->len;
04066    snprintf(req->header[req->headers], sizeof(req->data) - req->len, "SIP/2.0 %s\r\n", resp);
04067    req->len += strlen(req->header[req->headers]);
04068    req->headers++;
04069    return 0;
04070 }

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

References AST_DIGIT_ANYNUM, ast_test_flag, n, SIP_USEREQPHONE, and sip_pvt::username.

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

04864 {
04865    char invite_buf[256] = "";
04866    char *invite = invite_buf;
04867    size_t invite_max = sizeof(invite_buf);
04868    char from[256];
04869    char to[256];
04870    char tmp[BUFSIZ/2];
04871    char tmp2[BUFSIZ/2];
04872    char iabuf[INET_ADDRSTRLEN];
04873    char *l = NULL, *n = NULL;
04874    int x;
04875    char urioptions[256]="";
04876 
04877    if (ast_test_flag(p, SIP_USEREQPHONE)) {
04878       char onlydigits = 1;
04879       x=0;
04880 
04881       /* Test p->username against allowed characters in AST_DIGIT_ANY
04882       If it matches the allowed characters list, then sipuser = ";user=phone"
04883       If not, then sipuser = ""
04884          */
04885          /* + is allowed in first position in a tel: uri */
04886          if (p->username && p->username[0] == '+')
04887          x=1;
04888 
04889       for (; x < strlen(p->username); x++) {
04890          if (!strchr(AST_DIGIT_ANYNUM, p->username[x])) {
04891                      onlydigits = 0;
04892             break;
04893          }
04894       }
04895 
04896       /* If we have only digits, add ;user=phone to the uri */
04897       if (onlydigits)
04898          strcpy(urioptions, ";user=phone");
04899    }
04900 
04901 
04902    snprintf(p->lastmsg, sizeof(p->lastmsg), "Init: %s", sip_methods[sipmethod].text);
04903 
04904    if (p->owner) {
04905       l = p->owner->cid.cid_num;
04906       n = p->owner->cid.cid_name;
04907    }
04908    /* if we are not sending RPID and user wants his callerid restricted */
04909    if (!ast_test_flag(p, SIP_SENDRPID) && ((p->callingpres & AST_PRES_RESTRICTION) != AST_PRES_ALLOWED)) {
04910       l = CALLERID_UNKNOWN;
04911       n = l;
04912    }
04913    if (ast_strlen_zero(l))
04914       l = default_callerid;
04915    if (ast_strlen_zero(n))
04916       n = l;
04917    /* Allow user to be overridden */
04918    if (!ast_strlen_zero(p->fromuser))
04919       l = p->fromuser;
04920    else /* Save for any further attempts */
04921       ast_copy_string(p->fromuser, l, sizeof(p->fromuser));
04922 
04923    /* Allow user to be overridden */
04924    if (!ast_strlen_zero(p->fromname))
04925       n = p->fromname;
04926    else /* Save for any further attempts */
04927       ast_copy_string(p->fromname, n, sizeof(p->fromname));
04928 
04929    if (pedanticsipchecking) {
04930       ast_uri_encode(n, tmp, sizeof(tmp), 0);
04931       n = tmp;
04932       ast_uri_encode(l, tmp2, sizeof(tmp2), 0);
04933       l = tmp2;
04934    }
04935 
04936    if ((ourport != 5060) && ast_strlen_zero(p->fromdomain)) /* Needs to be 5060 */
04937       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);
04938    else
04939       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);
04940 
04941    /* If we're calling a registered SIP peer, use the fullcontact to dial to the peer */
04942    if (!ast_strlen_zero(p->fullcontact)) {
04943       /* If we have full contact, trust it */
04944       ast_build_string(&invite, &invite_max, "%s", p->fullcontact);
04945    } else {
04946       /* Otherwise, use the username while waiting for registration */
04947       ast_build_string(&invite, &invite_max, "sip:");
04948       if (!ast_strlen_zero(p->username)) {
04949          n = p->username;
04950          if (pedanticsipchecking) {
04951             ast_uri_encode(n, tmp, sizeof(tmp), 0);
04952             n = tmp;
04953          }
04954          ast_build_string(&invite, &invite_max, "%s@", n);
04955       }
04956       ast_build_string(&invite, &invite_max, "%s", p->tohost);
04957       if (ntohs(p->sa.sin_port) != 5060)     /* Needs to be 5060 */
04958          ast_build_string(&invite, &invite_max, ":%d", ntohs(p->sa.sin_port));
04959       ast_build_string(&invite, &invite_max, "%s", urioptions);
04960    }
04961 
04962    /* If custom URI options have been provided, append them */
04963    if (p->options && p->options->uri_options)
04964       ast_build_string(&invite, &invite_max, ";%s", p->options->uri_options);
04965 
04966    ast_copy_string(p->uri, invite_buf, sizeof(p->uri));
04967 
04968    if (sipmethod == SIP_NOTIFY && !ast_strlen_zero(p->theirtag)) { 
04969       /* If this is a NOTIFY, use the From: tag in the subscribe (RFC 3265) */
04970       snprintf(to, sizeof(to), "<sip:%s>;tag=%s", p->uri, p->theirtag);
04971    } else if (p->options && p->options->vxml_url) {
04972       /* If there is a VXML URL append it to the SIP URL */
04973       snprintf(to, sizeof(to), "<%s>;%s", p->uri, p->options->vxml_url);
04974    } else {
04975       snprintf(to, sizeof(to), "<%s>", p->uri);
04976    }
04977    
04978    memset(req, 0, sizeof(struct sip_request));
04979    init_req(req, sipmethod, p->uri);
04980    snprintf(tmp, sizeof(tmp), "%d %s", ++p->ocseq, sip_methods[sipmethod].text);
04981 
04982    add_header(req, "Via", p->via);
04983    /* SLD: FIXME?: do Route: here too?  I think not cos this is the first request.
04984     * OTOH, then we won't have anything in p->route anyway */
04985    /* Build Remote Party-ID and From */
04986    if (ast_test_flag(p, SIP_SENDRPID) && (sipmethod == SIP_INVITE)) {
04987       build_rpid(p);
04988       add_header(req, "From", p->rpid_from);
04989    } else {
04990       add_header(req, "From", from);
04991    }
04992    add_header(req, "To", to);
04993    ast_copy_string(p->exten, l, sizeof(p->exten));
04994    build_contact(p);
04995    add_header(req, "Contact", p->our_contact);
04996    add_header(req, "Call-ID", p->callid);
04997    add_header(req, "CSeq", tmp);
04998    add_header(req, "User-Agent", default_useragent);
04999    add_header(req, "Max-Forwards", DEFAULT_MAX_FORWARDS);
05000    if (p->rpid)
05001       add_header(req, "Remote-Party-ID", p->rpid);
05002 }

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

insecure2str: Convert Insecure setting to printable string ---

Definition at line 7810 of file chan_sip.c.

Referenced by _sip_show_peer().

07811 {
07812    if (port && invite)
07813       return "port,invite";
07814    else if (port)
07815       return "port";
07816    else if (invite)
07817       return "invite";
07818    else
07819       return "no";
07820 }

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

References ASTERISK_GPL_KEY.

13577 {
13578    return ASTERISK_GPL_KEY;
13579 }

static void list_route struct sip_route route  )  [static]
 

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

Definition at line 6115 of file chan_sip.c.

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

06116 {
06117    if (!route) {
06118       ast_verbose("list_route: no route\n");
06119       return;
06120    }
06121    while (route) {
06122       ast_verbose("list_route: hop: <%s>\n", route->hop);
06123       route = route->next;
06124    }
06125 }

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 13424 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, io_context_create(), LOG_ERROR, LOG_WARNING, manager_sip_show_peer(), manager_sip_show_peers(), my_clis, 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.

13425 {
13426    ASTOBJ_CONTAINER_INIT(&userl);   /* User object list */
13427    ASTOBJ_CONTAINER_INIT(&peerl);   /* Peer object list */
13428    ASTOBJ_CONTAINER_INIT(&regl); /* Registry object list */
13429 
13430    sched = sched_context_create();
13431    if (!sched) {
13432       ast_log(LOG_WARNING, "Unable to create schedule context\n");
13433    }
13434 
13435    io = io_context_create();
13436    if (!io) {
13437       ast_log(LOG_WARNING, "Unable to create I/O context\n");
13438    }
13439 
13440    reload_config();  /* Load the configuration from sip.conf */
13441 
13442    /* Make sure we can register our sip channel type */
13443    if (ast_channel_register(&sip_tech)) {
13444       ast_log(LOG_ERROR, "Unable to register channel type %s\n", channeltype);
13445       return -1;
13446    }
13447 
13448    /* Register all CLI functions for SIP */
13449    ast_cli_register_multiple(my_clis, sizeof(my_clis)/ sizeof(my_clis[0]));
13450 
13451    /* Tell the RTP subdriver that we're here */
13452    ast_rtp_proto_register(&sip_rtp);
13453 
13454    /* Register dialplan applications */
13455    ast_register_application(app_dtmfmode, sip_dtmfmode, synopsis_dtmfmode, descrip_dtmfmode);
13456 
13457    /* These will be removed soon */
13458    ast_register_application(app_sipaddheader, sip_addheader, synopsis_sipaddheader, descrip_sipaddheader);
13459    ast_register_application(app_sipgetheader, sip_getheader, synopsis_sipgetheader, descrip_sipgetheader);
13460 
13461    /* Register dialplan functions */
13462    ast_custom_function_register(&sip_header_function);
13463    ast_custom_function_register(&sippeer_function);
13464    ast_custom_function_register(&sipchaninfo_function);
13465    ast_custom_function_register(&checksipdomain_function);
13466 
13467    /* Register manager commands */
13468    ast_manager_register2("SIPpeers", EVENT_FLAG_SYSTEM, manager_sip_show_peers,
13469          "List SIP peers (text format)", mandescr_show_peers);
13470    ast_manager_register2("SIPshowpeer", EVENT_FLAG_SYSTEM, manager_sip_show_peer,
13471          "Show SIP peer (text format)", mandescr_show_peer);
13472 
13473    sip_poke_all_peers();   
13474    sip_send_all_registers();
13475    
13476    /* And start the monitor for the first time */
13477    restart_monitor();
13478 
13479    return 0;
13480 }

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

lws2sws: Parse multiline SIP headers into one header

Definition at line 3331 of file chan_sip.c.

References t.

Referenced by sipsock_read().

03332 { 
03333    int h = 0, t = 0; 
03334    int lws = 0; 
03335 
03336    for (; h < len;) { 
03337       /* Eliminate all CRs */ 
03338       if (msgbuf[h] == '\r') { 
03339          h++; 
03340          continue; 
03341       } 
03342       /* Check for end-of-line */ 
03343       if (msgbuf[h] == '\n') { 
03344          /* Check for end-of-message */ 
03345          if (h + 1 == len) 
03346             break; 
03347          /* Check for a continuation line */ 
03348          if (msgbuf[h + 1] == ' ' || msgbuf[h + 1] == '\t') { 
03349             /* Merge continuation line */ 
03350             h++; 
03351             continue; 
03352          } 
03353          /* Propagate LF and start new line */ 
03354          msgbuf[t++] = msgbuf[h++]; 
03355          lws = 0;
03356          continue; 
03357       } 
03358       if (msgbuf[h] == ' ' || msgbuf[h] == '\t') { 
03359          if (lws) { 
03360             h++; 
03361             continue; 
03362          } 
03363          msgbuf[t++] = msgbuf[h++]; 
03364          lws = 1; 
03365          continue; 
03366       } 
03367       msgbuf[t++] = msgbuf[h++]; 
03368       if (lws) 
03369          lws = 0; 
03370    } 
03371    msgbuf[t] = '\0'; 
03372    return t; 
03373 }

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

Definition at line 3075 of file chan_sip.c.

References thread_safe_rand().

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

03076 {
03077    snprintf(tagbuf, len, "as%08x", thread_safe_rand());
03078 }

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

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

Referenced by load_module().

08031 {
08032    char *id = astman_get_header(m,"ActionID");
08033    char *a[4];
08034    char *peer;
08035    int ret;
08036 
08037    peer = astman_get_header(m,"Peer");
08038    if (ast_strlen_zero(peer)) {
08039       astman_send_error(s, m, "Peer: <name> missing.\n");
08040       return 0;
08041    }
08042    a[0] = "sip";
08043    a[1] = "show";
08044    a[2] = "peer";
08045    a[3] = peer;
08046 
08047    if (!ast_strlen_zero(id))
08048       ast_cli(s->fd, "ActionID: %s\r\n",id);
08049    ret = _sip_show_peer(1, s->fd, s, m, 4, a );
08050    ast_cli( s->fd, "\r\n\r\n" );
08051    return ret;
08052 }

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

References _sip_show_peers(), ast_cli(), ast_strlen_zero(), astman_get_header(), astman_send_ack(), s, and total.

Referenced by load_module().

07612 {
07613    char *id = astman_get_header(m,"ActionID");
07614    char *a[] = { "sip", "show", "peers" };
07615    char idtext[256] = "";
07616    int total = 0;
07617 
07618    if (!ast_strlen_zero(id))
07619       snprintf(idtext,256,"ActionID: %s\r\n",id);
07620 
07621    astman_send_ack(s, m, "Peer status list will follow");
07622    /* List the peers in separate manager events */
07623    _sip_show_peers(s->fd, &total, s, m, 3, a);
07624    /* Send final confirmation */
07625    ast_cli(s->fd,
07626    "Event: PeerlistComplete\r\n"
07627    "ListItems: %d\r\n"
07628    "%s"
07629    "\r\n", total, idtext);
07630    return 0;
07631 }

static char* nat2str int  nat  )  [static]
 

nat2str: Convert NAT setting to text string

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

07514 {
07515    switch(nat) {
07516    case SIP_NAT_NEVER:
07517       return "No";
07518    case SIP_NAT_ROUTE:
07519       return "Route";
07520    case SIP_NAT_ALWAYS:
07521       return "Always";
07522    case SIP_NAT_RFC3581:
07523       return "RFC3581";
07524    default:
07525       return "Unknown";
07526    }
07527 }

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

parse_copy: Copy SIP request, parse it

Definition at line 1474 of file chan_sip.c.

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

Referenced by send_request(), and send_response().

01475 {
01476    memset(dst, 0, sizeof(*dst));
01477    memcpy(dst->data, src->data, sizeof(dst->data));
01478    dst->len = src->len;
01479    parse_request(dst);
01480 }

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

References ast_log(), ast_test_flag, ast_channel::call_forward, get_header(), get_in_brackets(), LOG_DEBUG, sip_pvt::owner, s, and SIP_PROMISCREDIR.

Referenced by handle_response().

09579 {
09580    char tmp[256];
09581    char *s, *e;
09582    ast_copy_string(tmp, get_header(req, "Contact"), sizeof(tmp));
09583    s = get_in_brackets(tmp);
09584    e = strchr(s, ';');
09585    if (e)
09586       *e = '\0';
09587    if (ast_test_flag(p, SIP_PROMISCREDIR)) {
09588       if (!strncasecmp(s, "sip:", 4))
09589          s += 4;
09590       e = strchr(s, '/');
09591       if (e)
09592          *e = '\0';
09593       ast_log(LOG_DEBUG, "Found promiscuous redirection to 'SIP/%s'\n", s);
09594       if (p->owner)
09595          snprintf(p->owner->call_forward, sizeof(p->owner->call_forward), "SIP/%s", s);
09596    } else {
09597       e = strchr(tmp, '@');
09598       if (e)
09599          *e = '\0';
09600       e = strchr(tmp, '/');
09601       if (e)
09602          *e = '\0';
09603       if (!strncasecmp(s, "sip:", 4))
09604          s += 4;
09605       ast_log(LOG_DEBUG, "Found 302 Redirect to extension '%s'\n", s);
09606       if (p->owner)
09607          ast_copy_string(p->owner->call_forward, s, sizeof(p->owner->call_forward));
09608    }
09609 }

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

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

Referenced by handle_response_invite().

05877 {
05878    char contact[SIP_LEN_CONTACT]; 
05879    char *c, *n, *pt;
05880    int port;
05881    struct hostent *hp;
05882    struct ast_hostent ahp;
05883    struct sockaddr_in oldsin;
05884 
05885    /* Look for brackets */
05886    ast_copy_string(contact, get_header(req, "Contact"), sizeof(contact));
05887    c = get_in_brackets(contact);
05888 
05889    /* Save full contact to call pvt for later bye or re-invite */
05890    ast_copy_string(pvt->fullcontact, c, sizeof(pvt->fullcontact));   
05891 
05892    /* Save URI for later ACKs, BYE or RE-invites */
05893    ast_copy_string(pvt->okcontacturi, c, sizeof(pvt->okcontacturi));
05894    
05895    /* Make sure it's a SIP URL */
05896    if (strncasecmp(c, "sip:", 4)) {
05897       ast_log(LOG_NOTICE, "'%s' is not a valid SIP contact (missing sip:) trying to use anyway\n", c);
05898    } else
05899       c += 4;
05900 
05901    /* Ditch arguments */
05902    n = strchr(c, ';');
05903    if (n) 
05904       *n = '\0';
05905 
05906    /* Grab host */
05907    n = strchr(c, '@');
05908    if (!n) {
05909       n = c;
05910       c = NULL;
05911    } else {
05912       *n = '\0';
05913       n++;
05914    }
05915    pt = strchr(n, ':');
05916    if (pt) {
05917       *pt = '\0';
05918       pt++;
05919       port = atoi(pt);
05920    } else
05921       port = DEFAULT_SIP_PORT;
05922 
05923    memcpy(&oldsin, &pvt->sa, sizeof(oldsin));
05924 
05925    if (!(ast_test_flag(pvt, SIP_NAT) & SIP_NAT_ROUTE)) {
05926       /* XXX This could block for a long time XXX */
05927       /* We should only do this if it's a name, not an IP */
05928       hp = ast_gethostbyname(n, &ahp);
05929       if (!hp)  {
05930          ast_log(LOG_WARNING, "Invalid host '%s'\n", n);
05931          return -1;
05932       }
05933       pvt->sa.sin_family = AF_INET;
05934       memcpy(&pvt->sa.sin_addr, hp->h_addr, sizeof(pvt->sa.sin_addr));
05935       pvt->sa.sin_port = htons(port);
05936    } else {
05937       /* Don't trust the contact field.  Just use what they came to us
05938          with. */
05939       memcpy(&pvt->sa, &pvt->recv, sizeof(pvt->sa));
05940    }
05941    return 0;
05942 }

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

References sip_peer::addr, ahp, 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, 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().

05953 {
05954    char contact[BUFSIZ]; 
05955    char data[BUFSIZ];
05956    char iabuf[INET_ADDRSTRLEN];
05957    char *expires = get_header(req, "Expires");
05958    int expiry = atoi(expires);
05959    char *c, *n, *pt;
05960    int port;
05961    char *useragent;
05962    struct hostent *hp;
05963    struct ast_hostent ahp;
05964    struct sockaddr_in oldsin;
05965 
05966    if (ast_strlen_zero(expires)) {  /* No expires header */
05967       expires = strcasestr(get_header(req, "Contact"), ";expires=");
05968       if (expires) {
05969          char *ptr;
05970          if ((ptr = strchr(expires, ';')))
05971             *ptr = '\0';
05972          if (sscanf(expires + 9, "%d", &expiry) != 1)
05973             expiry = default_expiry;
05974       } else {
05975          /* Nothing has been specified */
05976          expiry = default_expiry;
05977       }
05978    }
05979    /* Look for brackets */
05980    ast_copy_string(contact, get_header(req, "Contact"), sizeof(contact));
05981    if (strchr(contact, '<') == NULL) { /* No <, check for ; and strip it */
05982       char *ptr = strchr(contact, ';');   /* This is Header options, not URI options */
05983       if (ptr)
05984          *ptr = '\0';
05985    }
05986    c = get_in_brackets(contact);
05987 
05988    /* if they did not specify Contact: or Expires:, they are querying
05989       what we currently have stored as their contact address, so return
05990       it
05991    */
05992    if (ast_strlen_zero(c) && ast_strlen_zero(expires)) {
05993       /* If we have an active registration, tell them when the registration is going to expire */
05994       if ((p->expire > -1) && !ast_strlen_zero(p->fullcontact)) {
05995          pvt->expiry = ast_sched_when(sched, p->expire);
05996       } 
05997       return PARSE_REGISTER_QUERY;
05998    } else if (!strcasecmp(c, "*") || !expiry) { /* Unregister this peer */
05999       /* This means remove all registrations and return OK */
06000       memset(&p->addr, 0, sizeof(p->addr));
06001       if (p->expire > -1)
06002          ast_sched_del(sched, p->expire);
06003       p->expire = -1;
06004 
06005       destroy_association(p);
06006       
06007       register_peer_exten(p, 0);
06008       p->fullcontact[0] = '\0';
06009       p->useragent[0] = '\0';
06010       p->sipoptions = 0;
06011       p->lastms = 0;
06012 
06013       if (option_verbose > 2)
06014          ast_verbose(VERBOSE_PREFIX_3 "Unregistered SIP '%s'\n", p->name);
06015          manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: SIP/%s\r\nPeerStatus: Unregistered\r\n", p->name);
06016       return PARSE_REGISTER_UPDATE;
06017    }
06018    ast_copy_string(p->fullcontact, c, sizeof(p->fullcontact));
06019    /* For the 200 OK, we should use the received contact */
06020    snprintf(pvt->our_contact, sizeof(pvt->our_contact) - 1, "<%s>", c);
06021    /* Make sure it's a SIP URL */
06022    if (strncasecmp(c, "sip:", 4)) {
06023       ast_log(LOG_NOTICE, "'%s' is not a valid SIP contact (missing sip:) trying to use anyway\n", c);
06024    } else
06025       c += 4;
06026    /* Ditch q */
06027    n = strchr(c, ';');
06028    if (n) {
06029       *n = '\0';
06030    }
06031    /* Grab host */
06032    n = strchr(c, '@');
06033    if (!n) {
06034       n = c;
06035       c = NULL;
06036    } else {
06037       *n = '\0';
06038       n++;
06039    }
06040    pt = strchr(n, ':');
06041    if (pt) {
06042       *pt = '\0';
06043       pt++;
06044       port = atoi(pt);
06045    } else
06046       port = DEFAULT_SIP_PORT;
06047    memcpy(&oldsin, &p->addr, sizeof(oldsin));
06048    if (!(ast_test_flag(p, SIP_NAT) & SIP_NAT_ROUTE)) {
06049       /* XXX This could block for a long time XXX */
06050       hp = ast_gethostbyname(n, &ahp);
06051       if (!hp)  {
06052          ast_log(LOG_WARNING, "Invalid host '%s'\n", n);
06053          return PARSE_REGISTER_FAILED;
06054       }
06055       p->addr.sin_family = AF_INET;
06056       memcpy(&p->addr.sin_addr, hp->h_addr, sizeof(p->addr.sin_addr));
06057       p->addr.sin_port = htons(port);
06058    } else {
06059       /* Don't trust the contact field.  Just use what they came to us
06060          with */
06061       memcpy(&p->addr, &pvt->recv, sizeof(p->addr));
06062    }
06063 
06064    if (c)   /* Overwrite the default username from config at registration */
06065       ast_copy_string(p->username, c, sizeof(p->username));
06066    else
06067       p->username[0] = '\0';
06068 
06069    if (p->expire > -1)
06070       ast_sched_del(sched, p->expire);
06071    if ((expiry < 1) || (expiry > max_expiry))
06072       expiry = max_expiry;
06073    if (!ast_test_flag(p, SIP_REALTIME))
06074       p->expire = ast_sched_add(sched, (expiry + 10) * 1000, expire_register, p);
06075    else
06076       p->expire = -1;
06077    pvt->expiry = expiry;
06078    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);
06079    if (!ast_test_flag((&p->flags_page2), SIP_PAGE2_RT_FROMCONTACT)) 
06080       ast_db_put("SIP/Registry", p->name, data);
06081    manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: SIP/%s\r\nPeerStatus: Registered\r\n", p->name);
06082    if (inaddrcmp(&p->addr, &oldsin)) {
06083       sip_poke_peer(p);
06084       if (option_verbose > 2)
06085          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);
06086       register_peer_exten(p, 1);
06087    }
06088    
06089    /* Save SIP options profile */
06090    p->sipoptions = pvt->sipoptions;
06091 
06092    /* Save User agent */
06093    useragent = get_header(req, "User-Agent");
06094    if (useragent && strcasecmp(useragent, p->useragent)) {
06095       ast_copy_string(p->useragent, useragent, sizeof(p->useragent));
06096       if (option_verbose > 3) {
06097          ast_verbose(VERBOSE_PREFIX_3 "Saved useragent \"%s\" for peer %s\n",p->useragent,p->name);  
06098       }
06099    }
06100    return PARSE_REGISTER_UPDATE;
06101 }

static void parse_request struct sip_request req  )  [static]
 

parse_request: Parse a SIP message ----

Definition at line 3376 of file chan_sip.c.

References ast_log(), ast_strlen_zero(), sip_request::data, determine_firstline_parts(), sip_request::header, sip_request::headers, sip_request::line, sip_request::lines, 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().

03377 {
03378    /* Divide fields by NULL's */
03379    char *c;
03380    int f = 0;
03381 
03382    c = req->data;
03383 
03384    /* First header starts immediately */
03385    req->header[f] = c;
03386    while(*c) {
03387       if (*c == '\n') {
03388          /* We've got a new header */
03389          *c = 0;
03390 
03391          if (sipdebug && option_debug > 3)
03392             ast_log(LOG_DEBUG, "Header %d: %s (%d)\n", f, req->header[f], (int) strlen(req->header[f]));
03393          if (ast_strlen_zero(req->header[f])) {
03394             /* Line by itself means we're now in content */
03395             c++;
03396             break;
03397          }
03398          if (f >= SIP_MAX_HEADERS - 1) {
03399             ast_log(LOG_WARNING, "Too many SIP headers. Ignoring.\n");
03400          } else
03401             f++;
03402          req->header[f] = c + 1;
03403       } else if (*c == '\r') {
03404          /* Ignore but eliminate \r's */
03405          *c = 0;
03406       }
03407       c++;
03408    }
03409    /* Check for last header */
03410    if (!ast_strlen_zero(req->header[f])) {
03411       if (sipdebug && option_debug > 3)
03412          ast_log(LOG_DEBUG, "Header %d: %s (%d)\n", f, req->header[f], (int) strlen(req->header[f]));
03413       f++;
03414    }
03415    req->headers = f;
03416    /* Now we process any mime content */
03417    f = 0;
03418    req->line[f] = c;
03419    while(*c) {
03420       if (*c == '\n') {
03421          /* We've got a new line */
03422          *c = 0;
03423          if (sipdebug && option_debug > 3)
03424             ast_log(LOG_DEBUG, "Line: %s (%d)\n", req->line[f], (int) strlen(req->line[f]));
03425          if (f >= SIP_MAX_LINES - 1) {
03426             ast_log(LOG_WARNING, "Too many SDP lines. Ignoring.\n");
03427          } else
03428             f++;
03429          req->line[f] = c + 1;
03430       } else if (*c == '\r') {
03431          /* Ignore and eliminate \r's */
03432          *c = 0;
03433       }
03434       c++;
03435    }
03436    /* Check for last line */
03437    if (!ast_strlen_zero(req->line[f])) 
03438       f++;
03439    req->lines = f;
03440    if (*c) 
03441       ast_log(LOG_WARNING, "Odd content, extra stuff left over ('%s')\n", c);
03442    /* Split up the first line parts */
03443    determine_firstline_parts(req);
03444 }

static unsigned int parse_sip_options struct sip_pvt pvt,
char *  supported
[static]
 

parse_sip_options: Parse supported header in incoming packet

Definition at line 1003 of file chan_sip.c.

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

Referenced by handle_request_invite().

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

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

peer_status: Report Peer status in character string

Definition at line 7531 of file chan_sip.c.

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

07532 {
07533    int res = 0;
07534    if (peer->maxms) {
07535       if (peer->lastms < 0) {
07536          ast_copy_string(status, "UNREACHABLE", statuslen);
07537       } else if (peer->lastms > peer->maxms) {
07538          snprintf(status, statuslen, "LAGGED (%d ms)", peer->lastms);
07539          res = 1;
07540       } else if (peer->lastms) {
07541          snprintf(status, statuslen, "OK (%d ms)", peer->lastms);
07542          res = 1;
07543       } else {
07544          ast_copy_string(status, "UNKNOWN", statuslen);
07545       }
07546    } else { 
07547       ast_copy_string(status, "Unmonitored", statuslen);
07548       /* Checking if port is 0 */
07549       res = -1;
07550    }
07551    return res;
07552 }

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

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

Referenced by _sip_show_peer(), and sip_show_settings().

07971 {
07972    int x, codec;
07973 
07974    for(x = 0; x < 32 ; x++) {
07975       codec = ast_codec_pref_index(pref, x);
07976       if (!codec)
07977          break;
07978       ast_cli(fd, "%s", ast_getformatname(codec));
07979       if (x < 31 && ast_codec_pref_index(pref, x + 1))
07980          ast_cli(fd, ",");
07981    }
07982    if (!x)
07983       ast_cli(fd, "none");
07984 }

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

print_group: Print call group and pickup group ---

Definition at line 7787 of file chan_sip.c.

References ast_cli(), and ast_print_group().

Referenced by _sip_show_peer(), and sip_show_user().

07788 {
07789    char buf[256];
07790    ast_cli(fd, crlf ? "%s\r\n" : "%s\n", ast_print_group(buf, sizeof(buf), group) );
07791 }

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

References ahp, 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_pvt::capability, sip_request::data, debug, EVENT_FLAG_CALL, get_sdp(), get_sdp_iterate(), host, hp, sip_pvt::jointcapability, sip_pvt::lastrtprx, sip_pvt::lastrtptx, LOG_DEBUG, LOG_ERROR, LOG_NOTICE, LOG_WARNING, manager_event(), ast_channel::name, ast_channel::nativeformats, noncodeccapability, sip_pvt::noncodeccapability, sip_pvt::owner, sip_pvt::peercapability, portno, sip_pvt::prefs, ast_channel::readformat, sip_pvt::rtp, sdpLineNum_iterator_init(), SIP_CALL_ONHOLD, sip_debug_test_pvt(), SIP_DTMF, SIP_DTMF_AUTO, SIP_DTMF_INBAND, SIP_DTMF_RFC2833, SIP_NOVIDEO, ast_channel::uniqueid, sip_pvt::vrtp, and ast_channel::writeformat.

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

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 1688 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_flags_page2, global_rtautoclear, LOG_WARNING, ast_variable::name, ast_variable::next, peerl, sched, SIP_PAGE2_RTAUTOCLEAR, SIP_PAGE2_RTCACHEFRIENDS, SIP_REALTIME, ast_variable::value, and var.

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

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

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

01611 {
01612    char port[10];
01613    char ipaddr[20];
01614    char regseconds[20];
01615    time_t nowtime;
01616    
01617    time(&nowtime);
01618    nowtime += expirey;
01619    snprintf(regseconds, sizeof(regseconds), "%d", (int)nowtime);  /* Expiration time */
01620    ast_inet_ntoa(ipaddr, sizeof(ipaddr), sin->sin_addr);
01621    snprintf(port, sizeof(port), "%d", ntohs(sin->sin_port));
01622    
01623    if (fullcontact)
01624       ast_update_realtime("sippeers", "name", peername, "ipaddr", ipaddr, "port", port, "regseconds", regseconds, "username", username, "fullcontact", fullcontact, NULL);
01625    else
01626       ast_update_realtime("sippeers", "name", peername, "ipaddr", ipaddr, "port", port, "regseconds", regseconds, "username", username, NULL);
01627 }

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

References ast_load_realtime(), ast_set_flag, ast_test_flag, ast_variables_destroy(), ASTOBJ_CONTAINER_LINK, build_user(), global_flags_page2, ast_variable::name, ast_variable::next, SIP_PAGE2_RTCACHEFRIENDS, SIP_REALTIME, user, userl, ast_variable::value, and var.

01803 {
01804    struct ast_variable *var;
01805    struct ast_variable *tmp;
01806    struct sip_user *user = NULL;
01807 
01808    var = ast_load_realtime("sipusers", "name", username, NULL);
01809 
01810    if (!var)
01811       return NULL;
01812 
01813    tmp = var;
01814    while (tmp) {
01815       if (!strcasecmp(tmp->name, "type") &&
01816          !strcasecmp(tmp->value, "peer")) {
01817          ast_variables_destroy(var);
01818          return NULL;
01819       }
01820       tmp = tmp->next;
01821    }
01822    
01823 
01824 
01825    user = build_user(username, var, !ast_test_flag((&global_flags_page2), SIP_PAGE2_RTCACHEFRIENDS));
01826    
01827    if (!user) {   /* No user found */
01828       ast_variables_destroy(var);
01829       return NULL;
01830    }
01831 
01832    if (ast_test_flag((&global_flags_page2), SIP_PAGE2_RTCACHEFRIENDS)) {
01833       ast_set_flag((&user->flags_page2), SIP_PAGE2_RTCACHEFRIENDS);
01834       suserobjs++;
01835       ASTOBJ_CONTAINER_LINK(&userl,user);
01836    } else {
01837       /* Move counter from s to r... */
01838       suserobjs--;
01839       ruserobjs++;
01840       ast_set_flag(user, SIP_REALTIME);
01841    }
01842    ast_variables_destroy(var);
01843    return user;
01844 }

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

receive_message: Receive SIP MESSAGE method messages ---

Definition at line 7426 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().

07427 {
07428    char buf[1024];
07429    struct ast_frame f;
07430    char *content_type;
07431 
07432    content_type = get_header(req, "Content-Type");
07433    if (strcmp(content_type, "text/plain")) { /* No text/plain attachment */
07434       transmit_response(p, "415 Unsupported Media Type", req); /* Good enough, or? */
07435       ast_set_flag(p, SIP_NEEDDESTROY);
07436       return;
07437    }
07438 
07439    if (get_msg_text(buf, sizeof(buf), req)) {
07440       ast_log(LOG_WARNING, "Unable to retrieve text from %s\n", p->callid);
07441       transmit_response(p, "202 Accepted", req);
07442       ast_set_flag(p, SIP_NEEDDESTROY);
07443       return;
07444    }
07445 
07446    if (p->owner) {
07447       if (sip_debug_test_pvt(p))
07448          ast_verbose("Message received: '%s'\n", buf);
07449       memset(&f, 0, sizeof(f));
07450       f.frametype = AST_FRAME_TEXT;
07451       f.subclass = 0;
07452       f.offset = 0;
07453       f.data = buf;
07454       f.datalen = strlen(buf);
07455       ast_queue_frame(p->owner, &f);
07456       transmit_response(p, "202 Accepted", req); /* We respond 202 accepted, since we relay the message */
07457    } else { /* Message outside of a call, we do not support that */
07458       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);
07459       transmit_response(p, "405 Method Not Allowed", req); /* Good enough, or? */
07460    }
07461    ast_set_flag(p, SIP_NEEDDESTROY);
07462    return;
07463 }

static void reg_source_db struct sip_peer peer  )  [static]
 

reg_source_db: Get registration details from Asterisk DB ---

Definition at line 5815 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.

05816 {
05817    char data[256];
05818    char iabuf[INET_ADDRSTRLEN];
05819    struct in_addr in;
05820    int expiry;
05821    int port;
05822    char *scan, *addr, *port_str, *expiry_str, *username, *contact;
05823 
05824    if (ast_test_flag(&(peer->flags_page2), SIP_PAGE2_RT_FROMCONTACT)) 
05825       return;
05826    if (ast_db_get("SIP/Registry", peer->name, data, sizeof(data)))
05827       return;
05828 
05829    scan = data;
05830    addr = strsep(&scan, ":");
05831    port_str = strsep(&scan, ":");
05832    expiry_str = strsep(&scan, ":");
05833    username = strsep(&scan, ":");
05834    contact = scan;   /* Contact include sip: and has to be the last part of the database entry as long as we use : as a separator */
05835 
05836    if (!inet_aton(addr, &in))
05837       return;
05838 
05839    if (port_str)
05840       port = atoi(port_str);
05841    else
05842       return;
05843 
05844    if (expiry_str)
05845       expiry = atoi(expiry_str);
05846    else
05847       return;
05848 
05849    if (username)
05850       ast_copy_string(peer->username, username, sizeof(peer->username));
05851    if (contact)
05852       ast_copy_string(peer->fullcontact, contact, sizeof(peer->fullcontact));
05853 
05854    if (option_verbose > 2)
05855       ast_verbose(VERBOSE_PREFIX_3 "SIP Seeding peer from astdb: '%s' at %s@%s:%d for %d\n",
05856              peer->name, peer->username, ast_inet_ntoa(iabuf, sizeof(iabuf), in), port, expiry);
05857 
05858    memset(&peer->addr, 0, sizeof(peer->addr));
05859    peer->addr.sin_family = AF_INET;
05860    peer->addr.sin_addr = in;
05861    peer->addr.sin_port = htons(port);
05862    if (sipsock < 0) {
05863       /* SIP isn't up yet, so schedule a poke only, pretty soon */
05864       if (peer->pokeexpire > -1)
05865          ast_sched_del(sched, peer->pokeexpire);
05866       peer->pokeexpire = ast_sched_add(sched, thread_safe_rand() % 5000 + 1, sip_poke_peer_s, peer);
05867    } else
05868       sip_poke_peer(peer);
05869    if (peer->expire > -1)
05870       ast_sched_del(sched, peer->expire);
05871    peer->expire = ast_sched_add(sched, (expiry + 10) * 1000, expire_register, peer);
05872    register_peer_exten(peer, 1);
05873 }

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

References ast_add_extension(), ast_context_remove_extension(), ast_strlen_zero(), FREE, sip_peer::regexten, strdup, and strsep().

01631 {
01632    char multi[256];
01633    char *stringp, *ext;
01634    if (!ast_strlen_zero(regcontext)) {
01635       ast_copy_string(multi, ast_strlen_zero(peer->regexten) ? peer->name : peer->regexten, sizeof(multi));
01636       stringp = multi;
01637       while((ext = strsep(&stringp, "&"))) {
01638          if (onoff)
01639             ast_add_extension(regcontext, 1, ext, 1, NULL, NULL, "Noop", strdup(peer->name), FREE, channeltype);
01640          else
01641             ast_context_remove_extension(regcontext, ext, 1, NULL);
01642       }
01643    }
01644 }

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 6507 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().

06508 {
06509    int res = -3;
06510    struct sip_peer *peer;
06511    char tmp[256];
06512    char iabuf[INET_ADDRSTRLEN];
06513    char *name, *c;
06514    char *t;
06515    char *domain;
06516 
06517    /* Terminate URI */
06518    t = uri;
06519    while(*t && (*t > 32) && (*t != ';'))
06520       t++;
06521    *t = '\0';
06522    
06523    ast_copy_string(tmp, get_header(req, "To"), sizeof(tmp));
06524    if (pedanticsipchecking)
06525       ast_uri_decode(tmp);
06526 
06527    c = get_in_brackets(tmp);
06528    /* Ditch ;user=phone */
06529    name = strchr(c, ';');
06530    if (name)
06531       *name = '\0';
06532 
06533    if (!strncmp(c, "sip:", 4)) {
06534       name = c + 4;
06535    } else {
06536       name = c;
06537       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));
06538    }
06539 
06540    /* Strip off the domain name */
06541    if ((c = strchr(name, '@'))) {
06542       *c++ = '\0';
06543       domain = c;
06544       if ((c = strchr(domain, ':')))   /* Remove :port */
06545          *c = '\0';
06546       if (!AST_LIST_EMPTY(&domain_list)) {
06547          if (!check_sip_domain(domain, NULL, 0)) {
06548             transmit_response(p, "404 Not found (unknown domain)", &p->initreq);
06549             return -3;
06550          }
06551       }
06552    }
06553 
06554    ast_copy_string(p->exten, name, sizeof(p->exten));
06555    build_contact(p);
06556    peer = find_peer(name, NULL, 1);
06557    if (!(peer && ast_apply_ha(peer->ha, sin))) {
06558       if (peer)
06559          ASTOBJ_UNREF(peer,sip_destroy_peer);
06560    }
06561    if (peer) {
06562       if (!ast_test_flag(&peer->flags_page2, SIP_PAGE2_DYNAMIC)) {
06563          ast_log(LOG_ERROR, "Peer '%s' is trying to register, but not configured as host=dynamic\n", peer->name);
06564       } else {
06565          ast_copy_flags(p, peer, SIP_NAT);
06566          transmit_response(p, "100 Trying", req);
06567          if (!(res = check_auth(p, req, p->randdata, sizeof(p->randdata), peer->name, peer->secret, peer->md5secret, SIP_REGISTER, uri, 0, ignore))) {
06568             sip_cancel_destroy(p);
06569             switch (parse_register_contact(p, peer, req)) {
06570             case PARSE_REGISTER_FAILED:
06571                ast_log(LOG_WARNING, "Failed to parse contact info\n");
06572                transmit_response_with_date(p, "400 Bad Request", req);
06573                peer->lastmsgssent = -1;
06574                res = 0;
06575                break;
06576             case PARSE_REGISTER_QUERY:
06577                transmit_response_with_date(p, "200 OK", req);
06578                peer->lastmsgssent = -1;
06579                res = 0;
06580                break;
06581             case PARSE_REGISTER_UPDATE:
06582                update_peer(peer, p->expiry);
06583                /* Say OK and ask subsystem to retransmit msg counter */
06584                transmit_response_with_date(p, "200 OK", req);
06585                peer->lastmsgssent = -1;
06586                res = 0;
06587                break;
06588             }
06589          } 
06590       }
06591    }
06592    if (!peer && autocreatepeer) {
06593       /* Create peer if we have autocreate mode enabled */
06594       peer = temp_peer(name);
06595       if (peer) {
06596          ASTOBJ_CONTAINER_LINK(&peerl, peer);
06597          sip_cancel_destroy(p);
06598          switch (parse_register_contact(p, peer, req)) {
06599          case PARSE_REGISTER_FAILED:
06600             ast_log(LOG_WARNING, "Failed to parse contact info\n");
06601             transmit_response_with_date(p, "400 Bad Request", req);
06602             peer->lastmsgssent = -1;
06603             res = 0;
06604             break;
06605          case PARSE_REGISTER_QUERY:
06606             transmit_response_with_date(p, "200 OK", req);
06607             peer->lastmsgssent = -1;
06608             res = 0;
06609             break;
06610          case PARSE_REGISTER_UPDATE:
06611             /* Say OK and ask subsystem to retransmit msg counter */
06612             transmit_response_with_date(p, "200 OK", req);
06613             manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: SIP/%s\r\nPeerStatus: Registered\r\n", peer->name);
06614             peer->lastmsgssent = -1;
06615             res = 0;
06616             break;
06617          }
06618       }
06619    }
06620    if (!res) {
06621       ast_device_state_changed("SIP/%s", peer->name);
06622    }
06623    if (res < 0) {
06624       switch (res) {
06625       case -1:
06626          /* Wrong password in authentication. Go away, don't try again until you fixed it */
06627          transmit_response(p, "403 Forbidden (Bad auth)", &p->initreq);
06628          break;
06629       case -2:
06630          /* Username and digest username does not match. 
06631             Asterisk uses the From: username for authentication. We need the
06632             users to use the same authentication user name until we support
06633             proper authentication by digest auth name */
06634          transmit_response(p, "403 Authentication user name does not match account name", &p->initreq);
06635          break;
06636       case -3:
06637          if (global_alwaysauthreject) {
06638             transmit_fake_auth_response(p, &p->initreq, p->randdata, sizeof(p->randdata), 1);
06639          } else {
06640             /* URI not found */
06641             transmit_response(p, "404 Not found", &p->initreq);
06642          }
06643          /* Set res back to -2 because we don't want to return an invalid domain message. That check already happened up above. */
06644          res = -2;
06645          break;
06646       }
06647       if (option_debug > 1) {
06648          ast_log(LOG_DEBUG, "SIP REGISTER attempt failed for %s : %s\n",
06649             peer->name,
06650             (res == -1) ? "Bad password" : ((res == -2 ) ? "Bad digest user" : "Peer not found"));
06651       }
06652    }
06653    if (peer)
06654       ASTOBJ_UNREF(peer,sip_destroy_peer);
06655 
06656    return res;
06657 }

static char* regstate2str int  regstate  )  [static]
 

Definition at line 5355 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.

05356 {
05357    switch(regstate) {
05358    case REG_STATE_FAILED:
05359       return "Failed";
05360    case REG_STATE_UNREGISTERED:
05361       return "Unregistered";
05362    case REG_STATE_REGSENT:
05363       return "Request Sent";
05364    case REG_STATE_AUTHSENT:
05365       return "Auth. Sent";
05366    case REG_STATE_REGISTERED:
05367       return "Registered";
05368    case REG_STATE_REJECTED:
05369       return "Rejected";
05370    case REG_STATE_TIMEOUT:
05371       return "Timeout";
05372    case REG_STATE_NOAUTH:
05373       return "No Authentication";
05374    default:
05375       return "Unknown";
05376    }
05377 }

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

References sip_reload().

13389 {
13390    return sip_reload(0, 0, NULL);
13391 }

static int reload_config void   )  [static]
 

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

Definition at line 12564 of file chan_sip.c.

References __ourip, add_realm_authentication(), add_sip_domain(), ahp, 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_enable_packet_fragmentation(), 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, global_allowguest, global_alwaysauthreject, global_capability, global_flags, global_flags_page2, 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, prefs, 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.

12565 {
12566    struct ast_config *cfg;
12567    struct ast_variable *v;
12568    struct sip_peer *peer;
12569    struct sip_user *user;
12570    struct ast_hostent ahp;
12571    char *cat;
12572    char *utype;
12573    struct hostent *hp;
12574    int format;
12575    char iabuf[INET_ADDRSTRLEN];
12576    struct ast_flags dummy;
12577    int auto_sip_domains = 0;
12578    struct sockaddr_in old_bindaddr = bindaddr;
12579 
12580    cfg = ast_config_load(config);
12581 
12582    /* We *must* have a config file otherwise stop immediately */
12583    if (!cfg) {
12584       ast_log(LOG_NOTICE, "Unable to load config %s\n", config);
12585       return -1;
12586    }
12587    
12588    /* Reset IP addresses  */
12589    memset(&bindaddr, 0, sizeof(bindaddr));
12590    memset(&localaddr, 0, sizeof(localaddr));
12591    memset(&externip, 0, sizeof(externip));
12592    memset(&prefs, 0 , sizeof(prefs));
12593    sipdebug &= ~SIP_DEBUG_CONFIG;
12594 
12595    /* Initialize some reasonable defaults at SIP reload */
12596    ast_copy_string(default_context, DEFAULT_CONTEXT, sizeof(default_context));
12597    default_subscribecontext[0] = '\0';
12598    default_language[0] = '\0';
12599    default_fromdomain[0] = '\0';
12600    default_qualify = 0;
12601    allow_external_domains = 1;   /* Allow external invites */
12602    externhost[0] = '\0';
12603    externexpire = 0;
12604    externrefresh = 10;
12605    ast_copy_string(default_useragent, DEFAULT_USERAGENT, sizeof(default_useragent));
12606    ast_copy_string(default_notifymime, DEFAULT_NOTIFYMIME, sizeof(default_notifymime));
12607    global_notifyringing = 1;
12608    global_alwaysauthreject = 0;
12609    ast_copy_string(global_realm, DEFAULT_REALM, sizeof(global_realm));
12610    ast_copy_string(global_musicclass, "default", sizeof(global_musicclass));
12611    ast_copy_string(default_callerid, DEFAULT_CALLERID, sizeof(default_callerid));
12612    memset(&outboundproxyip, 0, sizeof(outboundproxyip));
12613    outboundproxyip.sin_port = htons(DEFAULT_SIP_PORT);
12614    outboundproxyip.sin_family = AF_INET;  /* Type of address: IPv4 */
12615    videosupport = 0;
12616    compactheaders = 0;
12617    dumphistory = 0;
12618    recordhistory = 0;
12619    relaxdtmf = 0;
12620    callevents = 0;
12621    ourport = DEFAULT_SIP_PORT;
12622    global_rtptimeout = 0;
12623    global_rtpholdtimeout = 0;
12624    global_rtpkeepalive = 0;
12625    global_rtautoclear = 120;
12626    pedanticsipchecking = 0;
12627    global_reg_timeout = DEFAULT_REGISTRATION_TIMEOUT;
12628    global_regattempts_max = 0;
12629    ast_clear_flag(&global_flags, AST_FLAGS_ALL);
12630    ast_clear_flag(&global_flags_page2, AST_FLAGS_ALL);
12631    ast_set_flag(&global_flags, SIP_DTMF_RFC2833);
12632    ast_set_flag(&global_flags, SIP_NAT_RFC3581);
12633    ast_set_flag(&global_flags, SIP_CAN_REINVITE);
12634    ast_set_flag(&global_flags_page2, SIP_PAGE2_RTUPDATE);
12635    global_mwitime = DEFAULT_MWITIME;
12636    strcpy(global_vmexten, DEFAULT_VMEXTEN);
12637    srvlookup = 0;
12638    autocreatepeer = 0;
12639    regcontext[0] = '\0';
12640    tos = 0;
12641    expiry = DEFAULT_EXPIRY;
12642    global_allowguest = 1;
12643 
12644    /* Read the [general] config section of sip.conf (or from realtime config) */
12645    v = ast_variable_browse(cfg, "general");
12646    while(v) {
12647       if (handle_common_options(&global_flags, &dummy, v)) {
12648          v = v->next;
12649          continue;
12650       }
12651 
12652       /* Create the interface list */
12653       if (!strcasecmp(v->name, "context")) {
12654          ast_copy_string(default_context, v->value, sizeof(default_context));
12655       } else if (!strcasecmp(v->name, "realm")) {
12656          ast_copy_string(global_realm, v->value, sizeof(global_realm));
12657       } else if (!strcasecmp(v->name, "useragent")) {
12658          ast_copy_string(default_useragent, v->value, sizeof(default_useragent));
12659          ast_log(LOG_DEBUG, "Setting User Agent Name to %s\n",
12660             default_useragent);
12661       } else if (!strcasecmp(v->name, "rtcachefriends")) {
12662          ast_set2_flag((&global_flags_page2), ast_true(v->value), SIP_PAGE2_RTCACHEFRIENDS); 
12663       } else if (!strcasecmp(v->name, "rtupdate")) {
12664          ast_set2_flag((&global_flags_page2), ast_true(v->value), SIP_PAGE2_RTUPDATE); 
12665       } else if (!strcasecmp(v->name, "ignoreregexpire")) {
12666          ast_set2_flag((&global_flags_page2), ast_true(v->value), SIP_PAGE2_IGNOREREGEXPIRE);   
12667       } else if (!strcasecmp(v->name, "rtautoclear")) {
12668          int i = atoi(v->value);
12669          if (i > 0)
12670             global_rtautoclear = i;
12671          else
12672             i = 0;
12673          ast_set2_flag((&global_flags_page2), i || ast_true(v->value), SIP_PAGE2_RTAUTOCLEAR);
12674       } else if (!strcasecmp(v->name, "usereqphone")) {
12675          ast_set2_flag((&global_flags), ast_true(v->value), SIP_USEREQPHONE); 
12676       } else if (!strcasecmp(v->name, "relaxdtmf")) {
12677          relaxdtmf = ast_true(v->value);
12678       } else if (!strcasecmp(v->name, "checkmwi")) {
12679          if ((sscanf(v->value, "%d", &global_mwitime) != 1) || (global_mwitime < 0)) {
12680             ast_log(LOG_WARNING, "'%s' is not a valid MWI time setting at line %d.  Using default (10).\n", v->value, v->lineno);
12681             global_mwitime = DEFAULT_MWITIME;
12682          }
12683       } else if (!strcasecmp(v->name, "vmexten")) {
12684          ast_copy_string(global_vmexten, v->value, sizeof(global_vmexten));
12685       } else if (!strcasecmp(v->name, "rtptimeout")) {
12686          if ((sscanf(v->value, "%d", &global_rtptimeout) != 1) || (global_rtptimeout < 0)) {
12687             ast_log(LOG_WARNING, "'%s' is not a valid RTP hold time at line %d.  Using default.\n", v->value, v->lineno);
12688             global_rtptimeout = 0;
12689          }
12690       } else if (!strcasecmp(v->name, "rtpholdtimeout")) {
12691          if ((sscanf(v->value, "%d", &global_rtpholdtimeout) != 1) || (global_rtpholdtimeout < 0)) {
12692             ast_log(LOG_WARNING, "'%s' is not a valid RTP hold time at line %d.  Using default.\n", v->value, v->lineno);
12693             global_rtpholdtimeout = 0;
12694          }
12695       } else if (!strcasecmp(v->name, "rtpkeepalive")) {
12696          if ((sscanf(v->value, "%d", &global_rtpkeepalive) != 1) || (global_rtpkeepalive < 0)) {
12697             ast_log(LOG_WARNING, "'%s' is not a valid RTP keepalive time at line %d.  Using default.\n", v->value, v->lineno);
12698             global_rtpkeepalive = 0;
12699          }
12700       } else if (!strcasecmp(v->name, "videosupport")) {
12701          videosupport = ast_true(v->value);
12702       } else if (!strcasecmp(v->name, "compactheaders")) {
12703          compactheaders = ast_true(v->value);
12704       } else if (!strcasecmp(v->name, "notifymimetype")) {
12705          ast_copy_string(default_notifymime, v->value, sizeof(default_notifymime));
12706       } else if (!strcasecmp(v->name, "notifyringing")) {
12707          global_notifyringing = ast_true(v->value);
12708       } else if (!strcasecmp(v->name, "alwaysauthreject")) {
12709          global_alwaysauthreject = ast_true(v->value);
12710       } else if (!strcasecmp(v->name, "musicclass") || !strcasecmp(v->name, "musiconhold")) {
12711          ast_copy_string(global_musicclass, v->value, sizeof(global_musicclass));
12712       } else if (!strcasecmp(v->name, "language")) {
12713          ast_copy_string(default_language, v->value, sizeof(default_language));
12714       } else if (!strcasecmp(v->name, "regcontext")) {
12715          ast_copy_string(regcontext, v->value, sizeof(regcontext));
12716          /* Create context if it doesn't exist already */
12717          if (!ast_context_find(regcontext))
12718             ast_context_create(NULL, regcontext, channeltype);
12719       } else if (!strcasecmp(v->name, "callerid")) {
12720          ast_copy_string(default_callerid, v->value, sizeof(default_callerid));
12721       } else if (!strcasecmp(v->name, "fromdomain")) {
12722          ast_copy_string(default_fromdomain, v->value, sizeof(default_fromdomain));
12723       } else if (!strcasecmp(v->name, "outboundproxy")) {
12724          if (ast_get_ip_or_srv(&outboundproxyip, v->value, srvlookup ? "_sip._udp" : NULL) < 0)
12725             ast_log(LOG_WARNING, "Unable to locate host '%s'\n", v->value);
12726       } else if (!strcasecmp(v->name, "outboundproxyport")) {
12727          /* Port needs to be after IP */
12728          sscanf(v->value, "%d", &format);
12729          outboundproxyip.sin_port = htons(format);
12730       } else if (!strcasecmp(v->name, "autocreatepeer")) {
12731          autocreatepeer = ast_true(v->value);
12732       } else if (!strcasecmp(v->name, "srvlookup")) {
12733          srvlookup = ast_true(v->value);
12734       } else if (!strcasecmp(v->name, "pedantic")) {
12735          pedanticsipchecking = ast_true(v->value);
12736       } else if (!strcasecmp(v->name, "maxexpirey") || !strcasecmp(v->name, "maxexpiry")) {
12737          max_expiry = atoi(v->value);
12738          if (max_expiry < 1)
12739             max_expiry = DEFAULT_MAX_EXPIRY;
12740       } else if (!strcasecmp(v->name, "defaultexpiry") || !strcasecmp(v->name, "defaultexpirey")) {
12741          default_expiry = atoi(v->value);
12742          if (default_expiry < 1)
12743             default_expiry = DEFAULT_DEFAULT_EXPIRY;
12744       } else if (!strcasecmp(v->name, "sipdebug")) {
12745          if (ast_true(v->value))
12746             sipdebug |= SIP_DEBUG_CONFIG;
12747       } else if (!strcasecmp(v->name, "dumphistory")) {
12748          dumphistory = ast_true(v->value);
12749       } else if (!strcasecmp(v->name, "recordhistory")) {
12750          recordhistory = ast_true(v->value);
12751       } else if (!strcasecmp(v->name, "registertimeout")) {
12752          global_reg_timeout = atoi(v->value);
12753          if (global_reg_timeout < 1)
12754             global_reg_timeout = DEFAULT_REGISTRATION_TIMEOUT;
12755       } else if (!strcasecmp(v->name, "registerattempts")) {
12756          global_regattempts_max = atoi(v->value);
12757       } else if (!strcasecmp(v->name, "bindaddr")) {
12758          if (!(hp = ast_gethostbyname(v->value, &ahp))) {
12759             ast_log(LOG_WARNING, "Invalid address: %s\n", v->value);
12760          } else {
12761             memcpy(&bindaddr.sin_addr, hp->h_addr, sizeof(bindaddr.sin_addr));
12762          }
12763       } else if (!strcasecmp(v->name, "localnet")) {
12764          struct ast_ha *na;
12765          if (!(na = ast_append_ha("d", v->value, localaddr)))
12766             ast_log(LOG_WARNING, "Invalid localnet value: %s\n", v->value);
12767          else
12768             localaddr = na;
12769       } else if (!strcasecmp(v->name, "localmask")) {
12770          ast_log(LOG_WARNING, "Use of localmask is no long supported -- use localnet with mask syntax\n");
12771       } else if (!strcasecmp(v->name, "externip")) {
12772          if (!(hp = ast_gethostbyname(v->value, &ahp))) 
12773             ast_log(LOG_WARNING, "Invalid address for externip keyword: %s\n", v->value);
12774          else
12775             memcpy(&externip.sin_addr, hp->h_addr, sizeof(externip.sin_addr));
12776          externexpire = 0;
12777       } else if (!strcasecmp(v->name, "externhost")) {
12778          ast_copy_string(externhost, v->value, sizeof(externhost));
12779          if (!(hp = ast_gethostbyname(externhost, &ahp))) 
12780             ast_log(LOG_WARNING, "Invalid address for externhost keyword: %s\n", externhost);
12781          else
12782             memcpy(&externip.sin_addr, hp->h_addr, sizeof(externip.sin_addr));
12783          time(&externexpire);
12784       } else if (!strcasecmp(v->name, "externrefresh")) {
12785          if (sscanf(v->value, "%d", &externrefresh) != 1) {
12786             ast_log(LOG_WARNING, "Invalid externrefresh value '%s', must be an integer >0 at line %d\n", v->value, v->lineno);
12787             externrefresh = 10;
12788          }
12789       } else if (!strcasecmp(v->name, "allow")) {
12790          ast_parse_allow_disallow(&prefs, &global_capability, v->value, 1);
12791       } else if (!strcasecmp(v->name, "disallow")) {
12792          ast_parse_allow_disallow(&prefs, &global_capability, v->value, 0);
12793       } else if (!strcasecmp(v->name, "allowexternaldomains")) {
12794          allow_external_domains = ast_true(v->value);
12795       } else if (!strcasecmp(v->name, "autodomain")) {
12796          auto_sip_domains = ast_true(v->value);
12797       } else if (!strcasecmp(v->name, "domain")) {
12798          char *domain = ast_strdupa(v->value);
12799          char *context = strchr(domain, ',');
12800 
12801          if (context)
12802             *context++ = '\0';
12803 
12804          if (option_debug && ast_strlen_zero(context))
12805             ast_log(LOG_DEBUG, "No context specified at line %d for domain '%s'\n", v->lineno, domain);
12806          if (ast_strlen_zero(domain))
12807             ast_log(LOG_WARNING, "Empty domain specified at line %d\n", v->lineno);
12808          else
12809             add_sip_domain(ast_strip(domain), SIP_DOMAIN_CONFIG, context ? ast_strip(context) : "");
12810       } else if (!strcasecmp(v->name, "register")) {
12811          sip_register(v->value, v->lineno);
12812       } else if (!strcasecmp(v->name, "tos")) {
12813          if (ast_str2tos(v->value, &tos))
12814             ast_log(LOG_WARNING, "Invalid tos value at line %d, should be 'lowdelay', 'throughput', 'reliability', 'mincost', or 'none'\n", v->lineno);
12815       } else if (!strcasecmp(v->name, "bindport")) {
12816          if (sscanf(v->value, "%d", &ourport) == 1) {
12817             bindaddr.sin_port = htons(ourport);
12818          } else {
12819             ast_log(LOG_WARNING, "Invalid port number '%s' at line %d of %s\n", v->value, v->lineno, config);
12820          }
12821       } else if (!strcasecmp(v->name, "qualify")) {
12822          if (!strcasecmp(v->value, "no")) {
12823             default_qualify = 0;
12824          } else if (!strcasecmp(v->value, "yes")) {
12825             default_qualify = DEFAULT_MAXMS;
12826          } else if (sscanf(v->value, "%d", &default_qualify) != 1) {
12827             ast_log(LOG_WARNING, "Qualification default should be 'yes', 'no', or a number of milliseconds at line %d of sip.conf\n", v->lineno);
12828             default_qualify = 0;
12829          }
12830       } else if (!strcasecmp(v->name, "callevents")) {
12831          callevents = ast_true(v->value);
12832       }
12833       /* else if (strcasecmp(v->name,"type"))
12834        * ast_log(LOG_WARNING, "Ignoring %s\n", v->name);
12835        */
12836        v = v->next;
12837    }
12838 
12839    if (!allow_external_domains && AST_LIST_EMPTY(&domain_list)) {
12840       ast_log(LOG_WARNING, "To disallow external domains, you need to configure local SIP domains.\n");
12841       allow_external_domains = 1;
12842    }
12843    
12844    /* Build list of authentication to various SIP realms, i.e. service providers */
12845    v = ast_variable_browse(cfg, "authentication");
12846    while(v) {
12847       /* Format for authentication is auth = username:password@realm */
12848       if (!strcasecmp(v->name, "auth")) {
12849          authl = add_realm_authentication(authl, v->value, v->lineno);
12850       }
12851       v = v->next;
12852    }
12853    
12854    /* Load peers, users and friends */
12855    cat = ast_category_browse(cfg, NULL);
12856    while(cat) {
12857       if (strcasecmp(cat, "general") && strcasecmp(cat, "authentication")) {
12858          utype = ast_variable_retrieve(cfg, cat, "type");
12859          if (utype) {
12860             if (!strcasecmp(utype, "user") || !strcasecmp(utype, "friend")) {
12861                user = build_user(cat, ast_variable_browse(cfg, cat), 0);
12862                if (user) {
12863                   ASTOBJ_CONTAINER_LINK(&userl,user);
12864                   ASTOBJ_UNREF(user, sip_destroy_user);
12865                }
12866             }
12867             if (!strcasecmp(utype, "peer") || !strcasecmp(utype, "friend")) {
12868                peer = build_peer(cat, ast_variable_browse(cfg, cat), 0);
12869                if (peer) {
12870                   ASTOBJ_CONTAINER_LINK(&peerl,peer);
12871                   ASTOBJ_UNREF(peer, sip_destroy_peer);
12872                }
12873             } else if (strcasecmp(utype, "user")) {
12874                ast_log(LOG_WARNING, "Unknown type '%s' for '%s' in %s\n", utype, cat, "sip.conf");
12875             }
12876          } else
12877             ast_log(LOG_WARNING, "Section '%s' lacks type\n", cat);
12878       }
12879       cat = ast_category_browse(cfg, cat);
12880    }
12881    if (ast_find_ourip(&__ourip, bindaddr)) {
12882       ast_log(LOG_WARNING, "Unable to get own IP address, SIP disabled\n");
12883       return 0;
12884    }
12885    if (!ntohs(bindaddr.sin_port))
12886       bindaddr.sin_port = ntohs(DEFAULT_SIP_PORT);
12887    bindaddr.sin_family = AF_INET;
12888    ast_mutex_lock(&netlock);
12889    if ((sipsock > -1) && (memcmp(&old_bindaddr, &bindaddr, sizeof(struct sockaddr_in)))) {
12890       close(sipsock);
12891       sipsock = -1;
12892    }
12893    if (sipsock < 0) {
12894       sipsock = socket(AF_INET, SOCK_DGRAM, 0);
12895       if (sipsock < 0) {
12896          ast_log(LOG_WARNING, "Unable to create SIP socket: %s\n", strerror(errno));
12897       } else {
12898          /* Allow SIP clients on the same host to access us: */
12899          const int reuseFlag = 1;
12900 
12901          setsockopt(sipsock, SOL_SOCKET, SO_REUSEADDR,
12902                (const char*)&reuseFlag,
12903                sizeof reuseFlag);
12904 
12905          ast_enable_packet_fragmentation(sipsock);
12906 
12907          if (bind(sipsock, (struct sockaddr *)&bindaddr, sizeof(bindaddr)) < 0) {
12908             ast_log(LOG_WARNING, "Failed to bind to %s:%d: %s\n",
12909             ast_inet_ntoa(iabuf, sizeof(iabuf), bindaddr.sin_addr), ntohs(bindaddr.sin_port),
12910             strerror(errno));
12911             close(sipsock);
12912             sipsock = -1;
12913          } else {
12914             if (option_verbose > 1) { 
12915                ast_verbose(VERBOSE_PREFIX_2 "SIP Listening on %s:%d\n", 
12916                ast_inet_ntoa(iabuf, sizeof(iabuf), bindaddr.sin_addr), ntohs(bindaddr.sin_port));
12917                ast_verbose(VERBOSE_PREFIX_2 "Using TOS bits %d\n", tos);
12918             }
12919             if (setsockopt(sipsock, IPPROTO_IP, IP_TOS, &tos, sizeof(tos))) 
12920                ast_log(LOG_WARNING, "Unable to set TOS to %d\n", tos);
12921          }
12922       }
12923    }
12924    ast_mutex_unlock(&netlock);
12925 
12926    /* Add default domains - host name, IP address and IP:port */
12927    /* Only do this if user added any sip domain with "localdomains" */
12928    /* In order to *not* break backwards compatibility */
12929    /*    Some phones address us at IP only, some with additional port number */
12930    if (auto_sip_domains) {
12931       char temp[MAXHOSTNAMELEN];
12932 
12933       /* First our default IP address */
12934       if (bindaddr.sin_addr.s_addr) {
12935          ast_inet_ntoa(temp, sizeof(temp), bindaddr.sin_addr);
12936          add_sip_domain(temp, SIP_DOMAIN_AUTO, NULL);
12937       } else {
12938          ast_log(LOG_NOTICE, "Can't add wildcard IP address to domain list, please add IP address to domain manually.\n");
12939       }
12940 
12941       /* Our extern IP address, if configured */
12942       if (externip.sin_addr.s_addr) {
12943          ast_inet_ntoa(temp, sizeof(temp), externip.sin_addr);
12944          add_sip_domain(temp, SIP_DOMAIN_AUTO, NULL);
12945       }
12946 
12947       /* Extern host name (NAT traversal support) */
12948       if (!ast_strlen_zero(externhost))
12949          add_sip_domain(externhost, SIP_DOMAIN_AUTO, NULL);
12950       
12951       /* Our host name */
12952       if (!gethostname(temp, sizeof(temp)))
12953          add_sip_domain(temp, SIP_DOMAIN_AUTO, NULL);
12954    }
12955 
12956    /* Release configuration from memory */
12957    ast_config_destroy(cfg);
12958 
12959    /* Load the list of manual NOTIFY types to support */
12960    if (notify_types)
12961       ast_config_destroy(notify_types);
12962    notify_types = ast_config_load(notify_config);
12963 
12964    return 0;
12965 }

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

References ast_log(), ast_strlen_zero(), sip_pvt::domain, get_header(), key(), keys, LOG_WARNING, sip_pvt::nonce, sip_pvt::opaque, sip_pvt::qop, sip_pvt::realm, and strsep().

Referenced by do_proxy_auth(), and do_register_auth().

09099 {
09100    char tmp[512];
09101    char *c;
09102    char oldnonce[256];
09103 
09104    /* table of recognised keywords, and places where they should be copied */
09105    const struct x {
09106       const char *key;
09107       char *dst;
09108       int dstlen;
09109    } *i, keys[] = {
09110       { "realm=", p->realm, sizeof(p->realm) },
09111       { "nonce=", p->nonce, sizeof(p->nonce) },
09112       { "opaque=", p->opaque, sizeof(p->opaque) },
09113       { "qop=", p->qop, sizeof(p->qop) },
09114       { "domain=", p->domain, sizeof(p->domain) },
09115       { NULL, NULL, 0 },
09116    };
09117 
09118    ast_copy_string(tmp, get_header(req, header), sizeof(tmp));
09119    if (ast_strlen_zero(tmp)) 
09120       return -1;
09121    if (strncasecmp(tmp, "Digest ", strlen("Digest "))) {
09122       ast_log(LOG_WARNING, "missing Digest.\n");
09123       return -1;
09124    }
09125    c = tmp + strlen("Digest ");
09126    for (i = keys; i->key != NULL; i++)
09127       i->dst[0] = '\0'; /* init all to empty strings */
09128    ast_copy_string(oldnonce, p->nonce, sizeof(oldnonce));
09129    while (c && *(c = ast_skip_blanks(c))) {  /* lookup for keys */
09130       for (i = keys; i->key != NULL; i++) {
09131          char *src, *separator;
09132          if (strncasecmp(c, i->key, strlen(i->key)) != 0)
09133             continue;
09134          /* Found. Skip keyword, take text in quotes or up to the separator. */
09135          c += strlen(i->key);
09136          if (*c == '\"') {
09137             src = ++c;
09138             separator = "\"";
09139          } else {
09140             src = c;
09141             separator = ",";
09142          }
09143          strsep(&c, separator); /* clear separator and move ptr */
09144          ast_copy_string(i->dst, src, i->dstlen);
09145          break;
09146       }
09147       if (i->key == NULL) /* not found, try ',' */
09148          strsep(&c, ",");
09149    }
09150    /* Reset nonce count */
09151    if (strcmp(p->nonce, oldnonce)) 
09152       p->noncecount = 0;
09153 
09154    /* Save auth data for following registrations */
09155    if (p->registry) {
09156       struct sip_registry *r = p->registry;
09157 
09158       if (strcmp(r->nonce, p->nonce)) {
09159          ast_copy_string(r->realm, p->realm, sizeof(r->realm));
09160          ast_copy_string(r->nonce, p->nonce, sizeof(r->nonce));
09161          ast_copy_string(r->domain, p->domain, sizeof(r->domain));
09162          ast_copy_string(r->opaque, p->opaque, sizeof(r->opaque));
09163          ast_copy_string(r->qop, p->qop, sizeof(r->qop));
09164          r->noncecount = 0;
09165       }
09166    }
09167    return build_reply_digest(p, sipmethod, digest, digest_len); 
09168 }

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

04139 {
04140    struct sip_request *orig = &p->initreq;
04141    char stripped[80];
04142    char tmp[80];
04143    char newto[256];
04144    char *c, *n;
04145    char *ot, *of;
04146    int is_strict = 0;   /* Strict routing flag */
04147 
04148    memset(req, 0, sizeof(struct sip_request));
04149    
04150    snprintf(p->lastmsg, sizeof(p->lastmsg), "Tx: %s", sip_methods[sipmethod].text);
04151    
04152    if (!seqno) {
04153       p->ocseq++;
04154       seqno = p->ocseq;
04155    }
04156    
04157    if (newbranch) {
04158       p->branch ^= thread_safe_rand();
04159       build_via(p, p->via, sizeof(p->via));
04160    }
04161 
04162    /* Check for strict or loose router */
04163    if (p->route && !ast_strlen_zero(p->route->hop) && strstr(p->route->hop,";lr") == NULL)
04164       is_strict = 1;
04165 
04166    if (sipmethod == SIP_CANCEL) {
04167       c = p->initreq.rlPart2; /* Use original URI */
04168    } else if (sipmethod == SIP_ACK) {
04169       /* Use URI from Contact: in 200 OK (if INVITE) 
04170       (we only have the contacturi on INVITEs) */
04171       if (!ast_strlen_zero(p->okcontacturi))
04172          c = is_strict ? p->route->hop : p->okcontacturi;
04173       else
04174          c = p->initreq.rlPart2;
04175    } else if (!ast_strlen_zero(p->okcontacturi)) {
04176          c = is_strict ? p->route->hop : p->okcontacturi; /* Use for BYE or REINVITE */
04177    } else if (!ast_strlen_zero(p->uri)) {
04178       c = p->uri;
04179    } else {
04180       /* We have no URI, use To: or From:  header as URI (depending on direction) */
04181       c = get_header(orig, (ast_test_flag(p, SIP_OUTGOING)) ? "To" : "From");
04182       ast_copy_string(stripped, c, sizeof(stripped));
04183       c = get_in_brackets(stripped);
04184       n = strchr(c, ';');
04185       if (n)
04186          *n = '\0';
04187    }  
04188    init_req(req, sipmethod, c);
04189 
04190    snprintf(tmp, sizeof(tmp), "%d %s", seqno, sip_methods[sipmethod].text);
04191 
04192    add_header(req, "Via", p->via);
04193    if (p->route) {
04194       set_destination(p, p->route->hop);
04195       if (is_strict)
04196          add_route(req, p->route->next);
04197       else
04198          add_route(req, p->route);
04199    }
04200 
04201    ot = get_header(orig, "To");
04202    of = get_header(orig, "From");
04203 
04204    /* Add tag *unless* this is a CANCEL, in which case we need to send it exactly
04205       as our original request, including tag (or presumably lack thereof) */
04206    if (!strcasestr(ot, "tag=") && sipmethod != SIP_CANCEL) {
04207       /* Add the proper tag if we don't have it already.  If they have specified
04208          their tag, use it.  Otherwise, use our own tag */
04209       if (ast_test_flag(p, SIP_OUTGOING) && !ast_strlen_zero(p->theirtag))
04210          snprintf(newto, sizeof(newto), "%s;tag=%s", ot, p->theirtag);
04211       else if (!ast_test_flag(p, SIP_OUTGOING))
04212          snprintf(newto, sizeof(newto), "%s;tag=%s", ot, p->tag);
04213       else
04214          snprintf(newto, sizeof(newto), "%s", ot);
04215       ot = newto;
04216    }
04217 
04218    if (ast_test_flag(p, SIP_OUTGOING)) {
04219       add_header(req, "From", of);
04220       add_header(req, "To", ot);
04221    } else {
04222       add_header(req, "From", ot);
04223       add_header(req, "To", of);
04224    }
04225    add_header(req, "Contact", p->our_contact);
04226    copy_header(req, orig, "Call-ID");
04227    add_header(req, "CSeq", tmp);
04228 
04229    add_header(req, "User-Agent", default_useragent);
04230    add_header(req, "Max-Forwards", DEFAULT_MAX_FORWARDS);
04231 
04232    if (p->rpid)
04233       add_header(req, "Remote-Party-ID", p->rpid);
04234 
04235    return 0;
04236 }

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

04091 {
04092    char newto[256], *ot;
04093 
04094    memset(resp, 0, sizeof(*resp));
04095    init_resp(resp, msg, req);
04096    copy_via_headers(p, resp, req, "Via");
04097    if (msg[0] == '2')
04098       copy_all_header(resp, req, "Record-Route");
04099    copy_header(resp, req, "From");
04100    ot = get_header(req, "To");
04101    if (!strcasestr(ot, "tag=") && strncmp(msg, "100", 3)) {
04102       /* Add the proper tag if we don't have it already.  If they have specified
04103          their tag, use it.  Otherwise, use our own tag */
04104       if (!ast_strlen_zero(p->theirtag) && ast_test_flag(p, SIP_OUTGOING))
04105          snprintf(newto, sizeof(newto), "%s;tag=%s", ot, p->theirtag);
04106       else if (p->tag && !ast_test_flag(p, SIP_OUTGOING))
04107          snprintf(newto, sizeof(newto), "%s;tag=%s", ot, p->tag);
04108       else {
04109          ast_copy_string(newto, ot, sizeof(newto));
04110          newto[sizeof(newto) - 1] = '\0';
04111       }
04112       ot = newto;
04113    }
04114    add_header(resp, "To", ot);
04115    copy_header(resp, req, "Call-ID");
04116    copy_header(resp, req, "CSeq");
04117    add_header(resp, "User-Agent", default_useragent);
04118    add_header(resp, "Allow", ALLOWED_METHODS);
04119    if (msg[0] == '2' && (p->method == SIP_SUBSCRIBE || p->method == SIP_REGISTER)) {
04120       /* For registration responses, we also need expiry and
04121          contact info */
04122       char tmp[256];
04123 
04124       snprintf(tmp, sizeof(tmp), "%d", p->expiry);
04125       add_header(resp, "Expires", tmp);
04126       if (p->expiry) {  /* Only add contact if we have an expiry time */
04127          char contact[SIP_LEN_CONTACT];
04128          snprintf(contact, sizeof(contact), "%s;expires=%d", p->our_contact, p->expiry);
04129          add_header(resp, "Contact", contact);  /* Not when we unregister */
04130       }
04131    } else if (msg[0] != '4' && p->our_contact[0]) {
04132       add_header(resp, "Contact", p->our_contact);
04133    }
04134    return 0;
04135 }

static int restart_monitor void   )  [static]
 

restart_monitor: Start the channel monitor thread ---

Definition at line 11625 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.

11626 {
11627    /* If we're supposed to be stopped -- stay stopped */
11628    if (monitor_thread == AST_PTHREADT_STOP)
11629       return 0;
11630    if (ast_mutex_lock(&monlock)) {
11631       ast_log(LOG_WARNING, "Unable to lock monitor\n");
11632       return -1;
11633    }
11634    if (monitor_thread == pthread_self()) {
11635       ast_mutex_unlock(&monlock);
11636       ast_log(LOG_WARNING, "Cannot kill myself\n");
11637       return -1;
11638    }
11639    if (monitor_thread != AST_PTHREADT_NULL) {
11640       /* Wake up the thread */
11641       pthread_kill(monitor_thread, SIGURG);
11642    } else {
11643       /* Start a new monitor */
11644       if (ast_pthread_create(&monitor_thread, NULL, do_monitor, NULL) < 0) {
11645          ast_mutex_unlock(&monlock);
11646          ast_log(LOG_ERROR, "Unable to start monitor thread.\n");
11647          return -1;
11648       }
11649    }
11650    ast_mutex_unlock(&monlock);
11651    return 0;
11652 }

static int retrans_pkt void *  data  )  [static]
 

retrans_pkt: Retransmit SIP message if no answer ---

Definition at line 1175 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, sip_pkt::timer_a, and sip_pkt::timer_t1.

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

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

Definition at line 2908 of file chan_sip.c.

References sip_request::sdp_start.

02909 {
02910    *iterator = req->sdp_start;
02911 }

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 1517 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(), sip_debug_test_pvt(), SIP_NAT, and SIP_NAT_ROUTE.

01518 {
01519    int res;
01520    char iabuf[INET_ADDRSTRLEN];
01521    struct sip_request tmp;
01522    char tmpmsg[80];
01523 
01524    if (sip_debug_test_pvt(p)) {
01525       if (ast_test_flag(p, SIP_NAT) & SIP_NAT_ROUTE)
01526          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);
01527       else
01528          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);
01529    }
01530    if (reliable) {
01531       if (recordhistory) {
01532          parse_copy(&tmp, req);
01533          snprintf(tmpmsg, sizeof(tmpmsg), "%s / %s", tmp.data, get_header(&tmp, "CSeq"));
01534          append_history(p, "TxReqRel", tmpmsg);
01535       }
01536       res = __sip_reliable_xmit(p, seqno, 0, req->data, req->len, (reliable > 1), req->method);
01537    } else {
01538       if (recordhistory) {
01539          parse_copy(&tmp, req);
01540          snprintf(tmpmsg, sizeof(tmpmsg), "%s / %s", tmp.data, get_header(&tmp, "CSeq"));
01541          append_history(p, "TxReq", tmpmsg);
01542       }
01543       res = __sip_xmit(p, req->data, req->len);
01544    }
01545    return res;
01546 }

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 1483 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(), sip_debug_test_pvt(), SIP_NAT, and SIP_NAT_ROUTE.

01484 {
01485    int res;
01486    char iabuf[INET_ADDRSTRLEN];
01487    struct sip_request tmp;
01488    char tmpmsg[80];
01489 
01490    if (sip_debug_test_pvt(p)) {
01491       if (ast_test_flag(p, SIP_NAT) & SIP_NAT_ROUTE)
01492          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);
01493       else
01494          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);
01495    }
01496    if (reliable) {
01497       if (recordhistory) {
01498          parse_copy(&tmp, req);
01499          snprintf(tmpmsg, sizeof(tmpmsg), "%s / %s", tmp.data, get_header(&tmp, "CSeq"));
01500          append_history(p, "TxRespRel", tmpmsg);
01501       }
01502       res = __sip_reliable_xmit(p, seqno, 1, req->data, req->len, (reliable > 1), req->method);
01503    } else {
01504       if (recordhistory) {
01505          parse_copy(&tmp, req);
01506          snprintf(tmpmsg, sizeof(tmpmsg), "%s / %s", tmp.data, get_header(&tmp, "CSeq"));
01507          append_history(p, "TxResp", tmpmsg);
01508       }
01509       res = __sip_xmit(p, req->data, req->len);
01510    }
01511    if (res > 0)
01512       return 0;
01513    return res;
01514 }

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

set_destination: Set destination from SIP URI ---

Definition at line 3994 of file chan_sip.c.

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

03995 {
03996    char *h, *maddr, hostname[256];
03997    char iabuf[INET_ADDRSTRLEN];
03998    int port, hn;
03999    struct hostent *hp;
04000    struct ast_hostent ahp;
04001    int debug=sip_debug_test_pvt(p);
04002 
04003    /* Parse uri to h (host) and port - uri is already just the part inside the <> */
04004    /* general form we are expecting is sip[s]:username[:password]@host[:port][;...] */
04005 
04006    if (debug)
04007       ast_verbose("set_destination: Parsing <%s> for address/port to send to\n", uri);
04008 
04009    /* Find and parse hostname */
04010    h = strchr(uri, '@');
04011    if (h)
04012       ++h;
04013    else {
04014       h = uri;
04015       if (strncmp(h, "sip:", 4) == 0)
04016          h += 4;
04017       else if (strncmp(h, "sips:", 5) == 0)
04018          h += 5;
04019    }
04020    hn = strcspn(h, ":;>") + 1;
04021    if (hn > sizeof(hostname)) 
04022       hn = sizeof(hostname);
04023    ast_copy_string(hostname, h, hn);
04024    h += hn - 1;
04025 
04026    /* Is "port" present? if not default to DEFAULT_SIP_PORT */
04027    if (*h == ':') {
04028       /* Parse port */
04029       ++h;
04030       port = strtol(h, &h, 10);
04031    }
04032    else
04033       port = DEFAULT_SIP_PORT;
04034 
04035    /* Got the hostname:port - but maybe there's a "maddr=" to override address? */
04036    maddr = strstr(h, "maddr=");
04037    if (maddr) {
04038       maddr += 6;
04039       hn = strspn(maddr, "0123456789.") + 1;
04040       if (hn > sizeof(hostname)) hn = sizeof(hostname);
04041       ast_copy_string(hostname, maddr, hn);
04042    }
04043    
04044    hp = ast_gethostbyname(hostname, &ahp);
04045    if (hp == NULL)  {
04046       ast_log(LOG_WARNING, "Can't find address for host '%s'\n", hostname);
04047       return;
04048    }
04049    p->sa.sin_family = AF_INET;
04050    memcpy(&p->sa.sin_addr, hp->h_addr, sizeof(p->sa.sin_addr));
04051    p->sa.sin_port = htons(port);
04052    if (debug)
04053       ast_verbose("set_destination: set destination to %s, port %d\n", ast_inet_ntoa(iabuf, sizeof(iabuf), p->sa.sin_addr), port);
04054 }

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

sip_addheader: Add a SIP header ---

Definition at line 13126 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().

13127 {
13128    int no = 0;
13129    int ok = 0;
13130    char varbuf[128];
13131    
13132    if (ast_strlen_zero((char *)data)) {
13133       ast_log(LOG_WARNING, "This application requires the argument: Header\n");
13134       return 0;
13135    }
13136    ast_mutex_lock(&chan->lock);
13137 
13138    /* Check for headers */
13139    while (!ok && no <= 50) {
13140       no++;
13141       snprintf(varbuf, sizeof(varbuf), "_SIPADDHEADER%02d", no);
13142       if (ast_strlen_zero(pbx_builtin_getvar_helper(chan, varbuf + 1)))
13143          ok = 1;
13144    }
13145    if (ok) {
13146       pbx_builtin_setvar_helper (chan, varbuf, (char *)data);
13147       if (sipdebug)
13148          ast_log(LOG_DEBUG,"SIP Header added \"%s\" as %s\n", (char *) data, varbuf);
13149    } else {
13150       ast_log(LOG_WARNING, "Too many SIP headers added, max 50\n");
13151    }
13152    ast_mutex_unlock(&chan->lock);
13153    return 0;
13154 }

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

sip_addrcmp: Support routine for find_peer ---

Definition at line 1756 of file chan_sip.c.

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

Referenced by find_peer().

01757 {
01758    /* We know name is the first field, so we can cast */
01759    struct sip_peer *p = (struct sip_peer *)name;
01760    return   !(!inaddrcmp(&p->addr, sin) || 
01761                (ast_test_flag(p, SIP_INSECURE_PORT) &&
01762                (p->addr.sin_addr.s_addr == sin->sin_addr.s_addr)));
01763 }

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 3081 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(), bindaddr, build_callid(), build_via(), calloc, default_context, default_fromdomain, free, global_capability, global_flags, global_musicclass, global_rtpholdtimeout, global_rtpkeepalive, global_rtptimeout, iflist, io, LOG_DEBUG, LOG_WARNING, make_our_tag(), NONE, option_debug, prefs, 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().

03082 {
03083    struct sip_pvt *p;
03084 
03085    if (!(p = calloc(1, sizeof(*p))))
03086       return NULL;
03087 
03088    ast_mutex_init(&p->lock);
03089 
03090    p->method = intended_method;
03091    p->initid = -1;
03092    p->autokillid = -1;
03093    p->subscribed = NONE;
03094    p->stateid = -1;
03095    p->prefs = prefs;
03096    if (intended_method != SIP_OPTIONS) /* Peerpoke has it's own system */
03097       p->timer_t1 = 500;   /* Default SIP retransmission timer T1 (RFC 3261) */
03098 #ifdef OSP_SUPPORT
03099    p->osphandle = -1;
03100    p->osptimelimit = 0;
03101 #endif   
03102    if (sin) {
03103       memcpy(&p->sa, sin, sizeof(p->sa));
03104       if (ast_sip_ouraddrfor(&p->sa.sin_addr,&p->ourip))
03105          memcpy(&p->ourip, &__ourip, sizeof(p->ourip));
03106    } else {
03107       memcpy(&p->ourip, &__ourip, sizeof(p->ourip));
03108    }
03109 
03110    p->branch = thread_safe_rand();  
03111    make_our_tag(p->tag, sizeof(p->tag));
03112    /* Start with 101 instead of 1 */
03113    p->ocseq = 101;
03114 
03115    if (sip_methods[intended_method].need_rtp) {
03116       p->rtp = ast_rtp_new_with_bindaddr(sched, io, 1, 0, bindaddr.sin_addr);
03117       if (videosupport)
03118          p->vrtp = ast_rtp_new_with_bindaddr(sched, io, 1, 0, bindaddr.sin_addr);
03119       if (!p->rtp || (videosupport && !p->vrtp)) {
03120          ast_log(LOG_WARNING, "Unable to create RTP audio %s session: %s\n", videosupport ? "and video" : "", strerror(errno));
03121          ast_mutex_destroy(&p->lock);
03122          if (p->chanvars) {
03123             ast_variables_destroy(p->chanvars);
03124             p->chanvars = NULL;
03125          }
03126          free(p);
03127          return NULL;
03128       }
03129       ast_rtp_settos(p->rtp, tos);
03130       if (p->vrtp)
03131          ast_rtp_settos(p->vrtp, tos);
03132       p->rtptimeout = global_rtptimeout;
03133       p->rtpholdtimeout = global_rtpholdtimeout;
03134       p->rtpkeepalive = global_rtpkeepalive;
03135    }
03136 
03137    if (useglobal_nat && sin) {
03138       /* Setup NAT structure according to global settings if we have an address */
03139       ast_copy_flags(p, &global_flags, SIP_NAT);
03140       memcpy(&p->recv, sin, sizeof(p->recv));
03141       if (p->rtp)
03142          ast_rtp_setnat(p->rtp, (ast_test_flag(p, SIP_NAT) & SIP_NAT_ROUTE));
03143       if (p->vrtp)
03144          ast_rtp_setnat(p->vrtp, (ast_test_flag(p, SIP_NAT) & SIP_NAT_ROUTE));
03145    }
03146 
03147    if (p->method != SIP_REGISTER)
03148       ast_copy_string(p->fromdomain, default_fromdomain, sizeof(p->fromdomain));
03149    build_via(p, p->via, sizeof(p->via));
03150    if (!callid)
03151       build_callid(p->callid, sizeof(p->callid), p->ourip, p->fromdomain);
03152    else
03153       ast_copy_string(p->callid, callid, sizeof(p->callid));
03154    ast_copy_flags(p, &global_flags, SIP_FLAGS_TO_COPY);
03155    /* Assign default music on hold class */
03156    strcpy(p->musicclass, global_musicclass);
03157    p->capability = global_capability;
03158    if ((ast_test_flag(p, SIP_DTMF) == SIP_DTMF_RFC2833) || (ast_test_flag(p, SIP_DTMF) == SIP_DTMF_AUTO))
03159       p->noncodeccapability |= AST_RTP_DTMF;
03160    strcpy(p->context, default_context);
03161 
03162    /* Add to active dialog list */
03163    ast_mutex_lock(&iflock);
03164    p->next = iflist;
03165    iflist = p;
03166    ast_mutex_unlock(&iflock);
03167    if (option_debug)
03168       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");
03169    return p;
03170 }

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 2543 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().

02544 {
02545    int res = 0;
02546    struct sip_pvt *p = ast->tech_pvt;
02547 
02548    ast_mutex_lock(&p->lock);
02549    if (ast->_state != AST_STATE_UP) {
02550 #ifdef OSP_SUPPORT   
02551       time(&p->ospstart);
02552 #endif
02553       try_suggested_sip_codec(p);   
02554 
02555       ast_setstate(ast, AST_STATE_UP);
02556       if (option_debug)
02557          ast_log(LOG_DEBUG, "sip_answer(%s)\n", ast->name);
02558       res = transmit_response_with_sdp(p, "200 OK", &p->initreq, 1);
02559    }
02560    ast_mutex_unlock(&p->lock);
02561    return res;
02562 }

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 2022 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, sched, 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.

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

static int sip_cancel_destroy struct sip_pvt p  )  [static]
 

sip_cancel_destroy: Cancel destruction of SIP call ---

Definition at line 1363 of file chan_sip.c.

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

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

01364 {
01365    if (p->autokillid > -1)
01366       ast_sched_del(sched, p->autokillid);
01367    append_history(p, "CancelDestroy", "");
01368    p->autokillid = -1;
01369    return 0;
01370 }

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

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

01051 {
01052    if (sipdebug == 0)
01053       return 0;
01054    if (debugaddr.sin_addr.s_addr) {
01055       if (((ntohs(debugaddr.sin_port) != 0)
01056          && (debugaddr.sin_port != addr->sin_port))
01057          || (debugaddr.sin_addr.s_addr != addr->sin_addr.s_addr))
01058          return 0;
01059    }
01060    return 1;
01061 }

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

sip_debug_test_pvt: Test PVT for debugging output

Definition at line 1064 of file chan_sip.c.

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

Referenced by __sip_destroy(), add_sdp(), 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().

01065 {
01066    if (sipdebug == 0)
01067       return 0;
01068    return sip_debug_test_addr(((ast_test_flag(p, SIP_NAT) & SIP_NAT_ROUTE) ? &p->recv : &p->sa));
01069 }

static void sip_destroy struct sip_pvt p  )  [static]
 

sip_destroy: Destroy SIP call structure ---

Definition at line 2286 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().

02287 {
02288    ast_mutex_lock(&iflock);
02289    __sip_destroy(p, 1);
02290    ast_mutex_unlock(&iflock);
02291 }

static void sip_destroy_peer struct sip_peer peer  )  [static]
 

sip_destroy_peer: Destroy peer object from memory

Definition at line 1647 of file chan_sip.c.

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

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

01648 {
01649    /* Delete it, it needs to disappear */
01650    if (peer->call)
01651       sip_destroy(peer->call);
01652    if (peer->chanvars) {
01653       ast_variables_destroy(peer->chanvars);
01654       peer->chanvars = NULL;
01655    }
01656    if (peer->expire > -1)
01657       ast_sched_del(sched, peer->expire);
01658    if (peer->pokeexpire > -1)
01659       ast_sched_del(sched, peer->pokeexpire);
01660    register_peer_exten(peer, 0);
01661    ast_free_ha(peer->ha);
01662    if (ast_test_flag(peer, SIP_SELFDESTRUCT))
01663       apeerobjs--;
01664    else if (ast_test_flag(peer, SIP_REALTIME))
01665       rpeerobjs--;
01666    else
01667       speerobjs--;
01668    clear_realm_authentication(peer->auth);
01669    peer->auth = (struct sip_auth *) NULL;
01670    if (peer->dnsmgr)
01671       ast_dnsmgr_release(peer->dnsmgr);
01672    free(peer);
01673 }

static void sip_destroy_user struct sip_user user  )  [static]
 

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

Definition at line 1785 of file chan_sip.c.

References ast_free_ha(), ast_test_flag, ast_variables_destroy(), free, SIP_REALTIME, and user.

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

01786 {
01787    ast_free_ha(user->ha);
01788    if (user->chanvars) {
01789       ast_variables_destroy(user->chanvars);
01790       user->chanvars = NULL;
01791    }
01792    if (ast_test_flag(user, SIP_REALTIME))
01793       ruserobjs--;
01794    else
01795       suserobjs--;
01796    free(user);
01797 }

static int sip_devicestate void *  data  )  [static]
 

sip_devicestate: Part of PBX channel interface ---

Definition at line 11751 of file chan_sip.c.

References sip_peer::addr, ahp, 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().

11752 {
11753    char *host;
11754    char *tmp;
11755 
11756    struct hostent *hp;
11757    struct ast_hostent ahp;
11758    struct sip_peer *p;
11759 
11760    int res = AST_DEVICE_INVALID;
11761 
11762    host = ast_strdupa(data);
11763    if ((tmp = strchr(host, '@')))
11764       host = tmp + 1;
11765 
11766    if (option_debug > 2) 
11767       ast_log(LOG_DEBUG, "Checking device state for peer %s\n", host);
11768 
11769    if ((p = find_peer(host, NULL, 1))) {
11770       if (p->addr.sin_addr.s_addr || p->defaddr.sin_addr.s_addr) {
11771          /* we have an address for the peer */
11772          /* if qualify is turned on, check the status */
11773          if (p->maxms && (p->lastms > p->maxms)) {
11774             res = AST_DEVICE_UNAVAILABLE;
11775          } else {
11776             /* qualify is not on, or the peer is responding properly */
11777             /* check call limit */
11778             if (p->call_limit && (p->inUse == p->call_limit))
11779                res = AST_DEVICE_BUSY;
11780             else if (p->call_limit && p->inUse)
11781                res = AST_DEVICE_INUSE;
11782             else if (p->call_limit)
11783                res = AST_DEVICE_NOT_INUSE;
11784             else
11785                res = AST_DEVICE_UNKNOWN;
11786          }
11787       } else {
11788          /* there is no address, it's unavailable */
11789          res = AST_DEVICE_UNAVAILABLE;
11790       }
11791       ASTOBJ_UNREF(p,sip_destroy_peer);
11792    } else {
11793       hp = ast_gethostbyname(host, &ahp);
11794       if (hp)
11795          res = AST_DEVICE_UNKNOWN;
11796    }
11797 
11798    return res;
11799 }

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

sip_do_debug: Turn on SIP debugging (CLI command)

Definition at line 8929 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.

08930 {
08931    int oldsipdebug = sipdebug & SIP_DEBUG_CONSOLE;
08932    if (argc != 2) {
08933       if (argc != 4) 
08934          return RESULT_SHOWUSAGE;
08935       else if (strncmp(argv[2], "ip\0", 3) == 0)
08936          return sip_do_debug_ip(fd, argc, argv);
08937       else if (strncmp(argv[2], "peer\0", 5) == 0)
08938          return sip_do_debug_peer(fd, argc, argv);
08939       else return RESULT_SHOWUSAGE;
08940    }
08941    sipdebug |= SIP_DEBUG_CONSOLE;
08942    memset(&debugaddr, 0, sizeof(debugaddr));
08943    if (oldsipdebug)
08944       ast_cli(fd, "SIP Debugging re-enabled\n");
08945    else
08946       ast_cli(fd, "SIP Debugging enabled\n");
08947    return RESULT_SUCCESS;
08948 }

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

sip_do_debug: Enable SIP Debugging in CLI ---

Definition at line 8873 of file chan_sip.c.

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

Referenced by sip_do_debug().

08874 {
08875    struct hostent *hp;
08876    struct ast_hostent ahp;
08877    char iabuf[INET_ADDRSTRLEN];
08878    int port = 0;
08879    char *p, *arg;
08880 
08881    if (argc != 4)
08882       return RESULT_SHOWUSAGE;
08883    arg = argv[3];
08884    p = strstr(arg, ":");
08885    if (p) {
08886       *p = '\0';
08887       p++;
08888       port = atoi(p);
08889    }
08890    hp = ast_gethostbyname(arg, &ahp);
08891    if (hp == NULL)  {
08892       return RESULT_SHOWUSAGE;
08893    }
08894    debugaddr.sin_family = AF_INET;
08895    memcpy(&debugaddr.sin_addr, hp->h_addr, sizeof(debugaddr.sin_addr));
08896    debugaddr.sin_port = htons(port);
08897    if (port == 0)
08898       ast_cli(fd, "SIP Debugging Enabled for IP: %s\n", ast_inet_ntoa(iabuf, sizeof(iabuf), debugaddr.sin_addr));
08899    else
08900       ast_cli(fd, "SIP Debugging Enabled for IP: %s:%d\n", ast_inet_ntoa(iabuf, sizeof(iabuf), debugaddr.sin_addr), port);
08901    sipdebug |= SIP_DEBUG_CONSOLE;
08902    return RESULT_SUCCESS;
08903 }

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 8906 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().

08907 {
08908    struct sip_peer *peer;
08909    char iabuf[INET_ADDRSTRLEN];
08910    if (argc != 4)
08911       return RESULT_SHOWUSAGE;
08912    peer = find_peer(argv[3], NULL, 1);
08913    if (peer) {
08914       if (peer->addr.sin_addr.s_addr) {
08915          debugaddr.sin_family = AF_INET;
08916          memcpy(&debugaddr.sin_addr, &peer->addr.sin_addr, sizeof(debugaddr.sin_addr));
08917          debugaddr.sin_port = peer->addr.sin_port;
08918          ast_cli(fd, "SIP Debugging Enabled for IP: %s:%d\n", ast_inet_ntoa(iabuf, sizeof(iabuf), debugaddr.sin_addr), ntohs(debugaddr.sin_port));
08919          sipdebug |= SIP_DEBUG_CONSOLE;
08920       } else
08921          ast_cli(fd, "Unable to get IP address of peer '%s'\n", argv[3]);
08922       ASTOBJ_UNREF(peer,sip_destroy_peer);
08923    } else
08924       ast_cli(fd, "No such peer '%s'\n", argv[3]);
08925    return RESULT_SUCCESS;
08926 }

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

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

Definition at line 9008 of file chan_sip.c.

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

09009 {
09010    if (argc != 2) {
09011       return RESULT_SHOWUSAGE;
09012    }
09013    recordhistory = 1;
09014    ast_cli(fd, "SIP History Recording Enabled (use 'sip show history')\n");
09015    return RESULT_SUCCESS;
09016 }

static int sip_do_reload void   )  [static]
 

sip_do_reload: Reload module

Definition at line 13340 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().

13341 {
13342    clear_realm_authentication(authl);
13343    clear_sip_domains();
13344    authl = NULL;
13345 
13346    /* First, destroy all outstanding registry calls */
13347    /* This is needed, since otherwise active registry entries will not be destroyed */
13348    ASTOBJ_CONTAINER_TRAVERSE(&regl, 1, do {
13349       ASTOBJ_RDLOCK(iterator);
13350       if (iterator->call) {
13351          if (option_debug > 2)
13352             ast_log(LOG_DEBUG, "Destroying active SIP dialog for registry %s@%s\n", iterator->username, iterator->hostname);
13353          /* This will also remove references to the registry */
13354          sip_destroy(iterator->call);
13355       }
13356       ASTOBJ_UNLOCK(iterator);
13357    } while(0));
13358 
13359    ASTOBJ_CONTAINER_DESTROYALL(&userl, sip_destroy_user);
13360    ASTOBJ_CONTAINER_DESTROYALL(&regl, sip_registry_destroy);
13361    ASTOBJ_CONTAINER_MARKALL(&peerl);
13362    reload_config();
13363    /* Prune peers who still are supposed to be deleted */
13364    ASTOBJ_CONTAINER_PRUNE_MARKED(&peerl, sip_destroy_peer);
13365 
13366    sip_poke_all_peers();
13367    sip_send_all_registers();
13368 
13369    return 0;
13370 }

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

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

Definition at line 13076 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().

13077 {
13078    struct sip_pvt *p;
13079    char *mode;
13080    if (data)
13081       mode = (char *)data;
13082    else {
13083       ast_log(LOG_WARNING, "This application requires the argument: info, inband, rfc2833\n");
13084       return 0;
13085    }
13086    ast_mutex_lock(&chan->lock);
13087    if (chan->type != channeltype) {
13088       ast_log(LOG_WARNING, "Call this application only on SIP incoming calls\n");
13089       ast_mutex_unlock(&chan->lock);
13090       return 0;
13091    }
13092    p = chan->tech_pvt;
13093    if (!p) {
13094       ast_mutex_unlock(&chan->lock);
13095       return 0;
13096    }
13097    ast_mutex_lock(&p->lock);
13098    if (!strcasecmp(mode,"info")) {
13099       ast_clear_flag(p, SIP_DTMF);
13100       ast_set_flag(p, SIP_DTMF_INFO);
13101    } else if (!strcasecmp(mode,"rfc2833")) {
13102       ast_clear_flag(p, SIP_DTMF);
13103       ast_set_flag(p, SIP_DTMF_RFC2833);
13104    } else if (!strcasecmp(mode,"inband")) { 
13105       ast_clear_flag(p, SIP_DTMF);
13106       ast_set_flag(p, SIP_DTMF_INBAND);
13107    } else
13108       ast_log(LOG_WARNING, "I don't know about this dtmf mode: %s\n",mode);
13109    if (ast_test_flag(p, SIP_DTMF) == SIP_DTMF_INBAND) {
13110       if (!p->vad) {
13111          p->vad = ast_dsp_new();
13112          ast_dsp_set_features(p->vad, DSP_FEATURE_DTMF_DETECT);
13113       }
13114    } else {
13115       if (p->vad) {
13116          ast_dsp_free(p->vad);
13117          p->vad = NULL;
13118       }
13119    }
13120    ast_mutex_unlock(&p->lock);
13121    ast_mutex_unlock(&chan->lock);
13122    return 0;
13123 }

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 8754 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().

08755 {
08756    int x;
08757    struct sip_history *hist;
08758 
08759    if (!dialog)
08760       return;
08761 
08762    ast_log(LOG_DEBUG, "\n---------- SIP HISTORY for '%s' \n", dialog->callid);
08763    if (dialog->subscribed)
08764       ast_log(LOG_DEBUG, "  * Subscription\n");
08765    else
08766       ast_log(LOG_DEBUG, "  * SIP Call\n");
08767    x = 0;
08768    hist = dialog->history;
08769    while(hist) {
08770       x++;
08771       ast_log(LOG_DEBUG, "  %d. %s\n", x, hist->event);
08772       hist = hist->next;
08773    }
08774    if (!x)
08775       ast_log(LOG_DEBUG, "Call '%s' has no history\n", dialog->callid);
08776    ast_log(LOG_DEBUG, "\n---------- END SIP HISTORY for '%s' \n", dialog->callid);
08777    
08778 }

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

02619 {
02620    struct sip_pvt *p = newchan->tech_pvt;
02621    ast_mutex_lock(&p->lock);
02622    if (p->owner != oldchan) {
02623       ast_log(LOG_WARNING, "old channel wasn't %p but was %p\n", oldchan, p->owner);
02624       ast_mutex_unlock(&p->lock);
02625       return -1;
02626    }
02627    p->owner = newchan;
02628    ast_mutex_unlock(&p->lock);
02629    return 0;
02630 }

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

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

13292 {
13293    struct sip_pvt *p = chan->tech_pvt;
13294    return p->peercapability;  
13295 }

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

12969 {
12970    struct sip_pvt *p;
12971    struct ast_rtp *rtp = NULL;
12972    p = chan->tech_pvt;
12973    if (!p)
12974       return NULL;
12975    ast_mutex_lock(&p->lock);
12976    if (p->rtp && ast_test_flag(p, SIP_CAN_REINVITE))
12977       rtp =  p->rtp;
12978    ast_mutex_unlock(&p->lock);
12979    return rtp;
12980 }

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

12984 {
12985    struct sip_pvt *p;
12986    struct ast_rtp *rtp = NULL;
12987    p = chan->tech_pvt;
12988    if (!p)
12989       return NULL;
12990 
12991    ast_mutex_lock(&p->lock);
12992    if (p->vrtp && ast_test_flag(p, SIP_CAN_REINVITE))
12993       rtp = p->vrtp;
12994    ast_mutex_unlock(&p->lock);
12995    return rtp;
12996 }

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

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

Definition at line 13157 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().

13158 {
13159    char *argv, *varname = NULL, *header = NULL, *content, *options = NULL;
13160    static int dep_warning = 0;
13161    struct sip_pvt *p;
13162    int priority_jump = 0;
13163    
13164    if (!dep_warning) {
13165       ast_log(LOG_WARNING, "SIPGetHeader is deprecated, use the SIP_HEADER function instead.\n");
13166       dep_warning = 1;
13167    }
13168 
13169    argv = ast_strdupa(data);
13170    if (!argv) {
13171       ast_log(LOG_DEBUG, "Memory allocation failed\n");
13172       return 0;
13173    }
13174 
13175    if (strchr (argv, '=') ) { /* Pick out argument */
13176       varname = strsep (&argv, "=");
13177       if (strchr(argv, '|')) {
13178          header = strsep (&argv, "|");
13179          options = strsep (&argv, "\0");
13180       } else {
13181          header = strsep (&argv, "\0");
13182       }
13183 
13184    }
13185 
13186    if (!varname || !header) {
13187       ast_log(LOG_DEBUG, "SIPGetHeader: Ignoring command, Syntax error in argument\n");
13188       return 0;
13189    }
13190 
13191    if (options) {
13192       if (strchr(options, 'j'))
13193          priority_jump = 1;
13194    }
13195 
13196    ast_mutex_lock(&chan->lock);
13197    if (chan->type != channeltype) {
13198       ast_log(LOG_WARNING, "Call this application only on incoming SIP calls\n");
13199       ast_mutex_unlock(&chan->lock);
13200       return 0;
13201    }
13202 
13203    p = chan->tech_pvt;
13204    content = get_header(&p->initreq, header);   /* Get the header */
13205    if (!ast_strlen_zero(content)) {
13206       pbx_builtin_setvar_helper(chan, varname, content);
13207       if (option_verbose > 2)
13208          ast_verbose(VERBOSE_PREFIX_3 "SIPGetHeader: set variable %s to %s\n", varname, content);
13209       pbx_builtin_setvar_helper(chan, "SIPGETSTATUS", "FOUND");
13210    } else {
13211       ast_log(LOG_WARNING,"SIP Header %s not found for channel variable %s\n", header, varname);
13212       if (priority_jump || option_priority_jumping) {
13213          /* Goto priority n+101 if it exists, where n is the current priority number */
13214          ast_goto_if_exists(chan, chan->context, chan->exten, chan->priority + 101);
13215       }
13216       pbx_builtin_setvar_helper(chan, "SIPGETSTATUS", "NOTFOUND");
13217    }
13218    
13219    ast_mutex_unlock(&chan->lock);
13220    return 0;
13221 }

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

References __sip_pretend_ack(), ast_channel::_state, AST_CAUSE_NORMAL, ast_clear_flag, 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_lock, sip_pvt::username, and sip_pvt::vad.

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

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 2675 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, ast_channel::tech_pvt, transmit_info_with_vidupdate(), transmit_response(), transmit_response_with_sdp(), and sip_pvt::vrtp.

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

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 2763 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_setstate(), AST_STATE_DOWN, AST_STATE_RING, ast_strlen_zero(), ast_test_flag, ast_update_use_count(), ast_channel::callgroup, sip_pvt::capability, ast_channel::cid, ast_callerid::cid_dnid, ast_callerid::cid_name, ast_callerid::cid_num, 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, 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, ast_channel::rings, SIP_DTMF, SIP_DTMF_INBAND, sip_tech, strdup, ast_channel::tech, ast_channel::tech_pvt, ast_channel::type, usecnt_lock, ast_variable::value, and ast_channel::writeformat.

Referenced by handle_request_invite(), and sip_request_call().

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

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

sip_no_debug: Disable SIP Debugging in CLI ---

Definition at line 9030 of file chan_sip.c.

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

09032 {
09033    if (argc != 3)
09034       return RESULT_SHOWUSAGE;
09035    sipdebug &= ~SIP_DEBUG_CONSOLE;
09036    ast_cli(fd, "SIP Debugging Disabled\n");
09037    return RESULT_SUCCESS;
09038 }

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

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

Definition at line 9019 of file chan_sip.c.

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

09020 {
09021    if (argc != 3) {
09022       return RESULT_SHOWUSAGE;
09023    }
09024    recordhistory = 0;
09025    ast_cli(fd, "SIP History Recording Disabled\n");
09026    return RESULT_SUCCESS;
09027 }

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

sip_notify: Send SIP notify to peer

Definition at line 8951 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(), create_addr(), initreqprep(), LOG_WARNING, notify_config, notify_types, sip_pvt::ourip, RESULT_FAILURE, RESULT_SHOWUSAGE, sip_pvt::sa, sip_alloc(), sip_destroy(), SIP_NOTIFY, sip_scheddestroy(), transmit_sip_request(), var, and sip_pvt::via.

08952 {
08953    struct ast_variable *varlist;
08954    int i;
08955 
08956    if (argc < 4)
08957       return RESULT_SHOWUSAGE;
08958 
08959    if (!notify_types) {
08960       ast_cli(fd, "No %s file found, or no types listed there\n", notify_config);
08961       return RESULT_FAILURE;
08962    }
08963 
08964    varlist = ast_variable_browse(notify_types, argv[2]);
08965 
08966    if (!varlist) {
08967       ast_cli(fd, "Unable to find notify type '%s'\n", argv[2]);
08968       return RESULT_FAILURE;
08969    }
08970 
08971    for (i = 3; i < argc; i++) {
08972       struct sip_pvt *p;
08973       struct sip_request req;
08974       struct ast_variable *var;
08975 
08976       p = sip_alloc(NULL, NULL, 0, SIP_NOTIFY);
08977       if (!p) {
08978          ast_log(LOG_WARNING, "Unable to build sip pvt data for notify\n");
08979          return RESULT_FAILURE;
08980       }
08981 
08982       if (create_addr(p, argv[i])) {
08983          /* Maybe they're not registered, etc. */
08984          sip_destroy(p);
08985          ast_cli(fd, "Could not create address for '%s'\n", argv[i]);
08986          continue;
08987       }
08988 
08989       initreqprep(&req, p, SIP_NOTIFY);
08990 
08991       for (var = varlist; var; var = var->next)
08992          add_header(&req, var->name, var->value);
08993 
08994       add_blank_header(&req);
08995       /* Recalculate our side, and recalculate Call ID */
08996       if (ast_sip_ouraddrfor(&p->sa.sin_addr, &p->ourip))
08997          memcpy(&p->ourip, &__ourip, sizeof(p->ourip));
08998       build_via(p, p->via, sizeof(p->via));
08999       build_callid(p->callid, sizeof(p->callid), p->ourip, p->fromdomain);
09000       ast_cli(fd, "Sending NOTIFY of type '%s' to '%s'\n", argv[2], argv[i]);
09001       transmit_sip_request(p, &req);
09002       sip_scheddestroy(p, 15000);
09003    }
09004 
09005    return RESULT_SUCCESS;
09006 }

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 10281 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().

10282 {
10283    struct sip_dual *d;
10284    struct ast_channel *chan1m, *chan2m;
10285    pthread_t th;
10286    chan1m = ast_channel_alloc(0);
10287    chan2m = ast_channel_alloc(0);
10288    if ((!chan2m) || (!chan1m)) {
10289       if (chan1m)
10290          ast_hangup(chan1m);
10291       if (chan2m)
10292          ast_hangup(chan2m);
10293       return -1;
10294    }
10295    snprintf(chan1m->name, sizeof(chan1m->name), "Parking/%s", chan1->name);
10296    /* Make formats okay */
10297    chan1m->readformat = chan1->readformat;
10298    chan1m->writeformat = chan1->writeformat;
10299    ast_channel_masquerade(chan1m, chan1);
10300    /* Setup the extensions and such */
10301    ast_copy_string(chan1m->context, chan1->context, sizeof(chan1m->context));
10302    ast_copy_string(chan1m->exten, chan1->exten, sizeof(chan1m->exten));
10303    chan1m->priority = chan1->priority;
10304       
10305    /* We make a clone of the peer channel too, so we can play
10306       back the announcement */
10307    snprintf(chan2m->name, sizeof (chan2m->name), "SIPPeer/%s",chan2->name);
10308    /* Make formats okay */
10309    chan2m->readformat = chan2->readformat;
10310    chan2m->writeformat = chan2->writeformat;
10311    ast_channel_masquerade(chan2m, chan2);
10312    /* Setup the extensions and such */
10313    ast_copy_string(chan2m->context, chan2->context, sizeof(chan2m->context));
10314    ast_copy_string(chan2m->exten, chan2->exten, sizeof(chan2m->exten));
10315    chan2m->priority = chan2->priority;
10316    ast_mutex_lock(&chan2m->lock);
10317    if (ast_do_masquerade(chan2m)) {
10318       ast_log(LOG_WARNING, "Masquerade failed :(\n");
10319       ast_mutex_unlock(&chan2m->lock);
10320       ast_hangup(chan2m);
10321       return -1;
10322    }
10323    ast_mutex_unlock(&chan2m->lock);
10324    d = malloc(sizeof(struct sip_dual));
10325    if (d) {
10326       memset(d, 0, sizeof(*d));
10327       /* Save original request for followup */
10328       copy_request(&d->req, req);
10329       d->chan1 = chan1m;
10330       d->chan2 = chan2m;
10331       if (!ast_pthread_create(&th, NULL, sip_park_thread, d))
10332          return 0;
10333       free(d);
10334    }
10335    return -1;
10336 }

static void* sip_park_thread void *  stuff  )  [static]
 

sip_park_thread: Park SIP call support function

Definition at line 10258 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().

10259 {
10260    struct ast_channel *chan1, *chan2;
10261    struct sip_dual *d;
10262    struct sip_request req;
10263    int ext;
10264    int res;
10265    d = stuff;
10266    chan1 = d->chan1;
10267    chan2 = d->chan2;
10268    copy_request(&req, &d->req);
10269    free(d);
10270    ast_mutex_lock(&chan1->lock);
10271    ast_do_masquerade(chan1);
10272    ast_mutex_unlock(&chan1->lock);
10273    res = ast_park_call(chan1, chan2, 0, &ext);
10274    /* Then hangup */
10275    ast_hangup(chan2);
10276    ast_log(LOG_DEBUG, "Parked on extension '%d'\n", ext);
10277    return NULL;
10278 }

static void sip_poke_all_peers void   )  [static]
 

sip_poke_all_peers: Send a poke to all known peers

Definition at line 13307 of file chan_sip.c.

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

Referenced by load_module().

13308 {
13309    ASTOBJ_CONTAINER_TRAVERSE(&peerl, 1, do {
13310       ASTOBJ_WRLOCK(iterator);
13311       sip_poke_peer(iterator);
13312       ASTOBJ_UNLOCK(iterator);
13313    } while (0)
13314    );
13315 }

static int sip_poke_noanswer void *  data  )  [static]
 

sip_poke_noanswer: No answer to Qualify poke ---

Definition at line 11655 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().

11656 {
11657    struct sip_peer *peer = data;
11658    
11659    peer->pokeexpire = -1;
11660    if (peer->lastms > -1) {
11661       ast_log(LOG_NOTICE, "Peer '%s' is now UNREACHABLE!  Last qualify: %d\n", peer->name, peer->lastms);
11662       manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: SIP/%s\r\nPeerStatus: Unreachable\r\nTime: %d\r\n", peer->name, -1);
11663    }
11664    if (peer->call)
11665       sip_destroy(peer->call);
11666    peer->call = NULL;
11667    peer->lastms = -1;
11668    ast_device_state_changed("SIP/%s", peer->name);
11669    /* Try again quickly */
11670    peer->pokeexpire = ast_sched_add(sched, DEFAULT_FREQ_NOTOK, sip_poke_peer_s, peer);
11671    return 0;
11672 }

static int sip_poke_peer struct sip_peer peer  )  [static]
 

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

Definition at line 11677 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().

11678 {
11679    struct sip_pvt *p;
11680    if (!peer->maxms || !peer->addr.sin_addr.s_addr) {
11681       /* IF we have no IP, or this isn't to be monitored, return
11682         imeediately after clearing things out */
11683       if (peer->pokeexpire > -1)
11684          ast_sched_del(sched, peer->pokeexpire);
11685       peer->lastms = 0;
11686       peer->pokeexpire = -1;
11687       peer->call = NULL;
11688       return 0;
11689    }
11690    if (peer->call > 0) {
11691       if (sipdebug)
11692          ast_log(LOG_NOTICE, "Still have a QUALIFY dialog active, deleting\n");
11693       sip_destroy(peer->call);
11694    }
11695    p = peer->call = sip_alloc(NULL, NULL, 0, SIP_OPTIONS);
11696    if (!peer->call) {
11697       ast_log(LOG_WARNING, "Unable to allocate dialog for poking peer '%s'\n", peer->name);
11698       return -1;
11699    }
11700    memcpy(&p->sa, &peer->addr, sizeof(p->sa));
11701    memcpy(&p->recv, &peer->addr, sizeof(p->sa));
11702    ast_copy_flags(p, peer, SIP_FLAGS_TO_COPY);
11703 
11704    /* Send OPTIONs to peer's fullcontact */
11705    if (!ast_strlen_zero(peer->fullcontact)) {
11706       ast_copy_string (p->fullcontact, peer->fullcontact, sizeof(p->fullcontact));
11707    }
11708 
11709    if (!ast_strlen_zero(peer->tohost))
11710       ast_copy_string(p->tohost, peer->tohost, sizeof(p->tohost));
11711    else
11712       ast_inet_ntoa(p->tohost, sizeof(p->tohost), peer->addr.sin_addr);
11713 
11714    /* Recalculate our side, and recalculate Call ID */
11715    if (ast_sip_ouraddrfor(&p->sa.sin_addr,&p->ourip))
11716       memcpy(&p->ourip, &__ourip, sizeof(p->ourip));
11717    build_via(p, p->via, sizeof(p->via));
11718    build_callid(p->callid, sizeof(p->callid), p->ourip, p->fromdomain);
11719 
11720    if (peer->pokeexpire > -1)
11721       ast_sched_del(sched, peer->pokeexpire);
11722    p->peerpoke = peer;
11723    ast_set_flag(p, SIP_OUTGOING);
11724 #ifdef VOCAL_DATA_HACK
11725    ast_copy_string(p->username, "__VOCAL_DATA_SHOULD_READ_THE_SIP_SPEC__", sizeof(p->username));
11726    transmit_invite(p, SIP_INVITE, 0, 2);
11727 #else
11728    transmit_invite(p, SIP_OPTIONS, 0, 2);
11729 #endif
11730    gettimeofday(&peer->ps, NULL);
11731    peer->pokeexpire = ast_sched_add(sched, DEFAULT_MAXMS * 2, sip_poke_noanswer, peer);
11732 
11733    return 0;
11734 }

static int sip_poke_peer_s void *  data  )  [static]
 

Definition at line 5806 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().

05807 {
05808    struct sip_peer *peer = data;
05809    peer->pokeexpire = -1;
05810    sip_poke_peer(peer);
05811    return 0;
05812 }

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

References ast_test_flag, ASTOBJ_CONTAINER_TRAVERSE, ASTOBJ_CONTAINER_WRLOCK, ASTOBJ_MARK, ASTOBJ_RDLOCK, ASTOBJ_UNLOCK, name, peerl, RESULT_SHOWUSAGE, SIP_PAGE2_RTCACHEFRIENDS, and user.

07824 {
07825    struct sip_peer *peer;
07826    struct sip_user *user;
07827    int pruneuser = 0;
07828    int prunepeer = 0;
07829    int multi = 0;
07830    char *name = NULL;
07831    regex_t regexbuf;
07832 
07833    switch (argc) {
07834    case 4:
07835       if (!strcasecmp(argv[3], "user"))
07836          return RESULT_SHOWUSAGE;
07837       if (!strcasecmp(argv[3], "peer"))
07838          return RESULT_SHOWUSAGE;
07839       if (!strcasecmp(argv[3], "like"))
07840          return RESULT_SHOWUSAGE;
07841       if (!strcasecmp(argv[3], "all")) {
07842          multi = 1;
07843          pruneuser = prunepeer = 1;
07844       } else {
07845          pruneuser = prunepeer = 1;
07846          name = argv[3];
07847       }
07848       break;
07849    case 5:
07850       if (!strcasecmp(argv[4], "like"))
07851          return RESULT_SHOWUSAGE;
07852       if (!strcasecmp(argv[3], "all"))
07853          return RESULT_SHOWUSAGE;
07854       if (!strcasecmp(argv[3], "like")) {
07855          multi = 1;
07856          name = argv[4];
07857          pruneuser = prunepeer = 1;
07858       } else if (!strcasecmp(argv[3], "user")) {
07859          pruneuser = 1;
07860          if (!strcasecmp(argv[4], "all"))
07861             multi = 1;
07862          else
07863             name = argv[4];
07864       } else if (!strcasecmp(argv[3], "peer")) {
07865          prunepeer = 1;
07866          if (!strcasecmp(argv[4], "all"))
07867             multi = 1;
07868          else
07869             name = argv[4];
07870       } else
07871          return RESULT_SHOWUSAGE;
07872       break;
07873    case 6:
07874       if (strcasecmp(argv[4], "like"))
07875          return RESULT_SHOWUSAGE;
07876       if (!strcasecmp(argv[3], "user")) {
07877          pruneuser = 1;
07878          name = argv[5];
07879       } else if (!strcasecmp(argv[3], "peer")) {
07880          prunepeer = 1;
07881          name = argv[5];
07882       } else
07883          return RESULT_SHOWUSAGE;
07884       break;
07885    default:
07886       return RESULT_SHOWUSAGE;
07887    }
07888 
07889    if (multi && name) {
07890       if (regcomp(&regexbuf, name, REG_EXTENDED | REG_NOSUB))
07891          return RESULT_SHOWUSAGE;
07892    }
07893 
07894    if (multi) {
07895       if (prunepeer) {
07896          int pruned = 0;
07897 
07898          ASTOBJ_CONTAINER_WRLOCK(&peerl);
07899          ASTOBJ_CONTAINER_TRAVERSE(&peerl, 1, do {
07900             ASTOBJ_RDLOCK(iterator);
07901             if (name && regexec(&regexbuf, iterator->name, 0, NULL, 0)) {
07902                ASTOBJ_UNLOCK(iterator);
07903                continue;
07904             };
07905             if (ast_test_flag((&iterator->flags_page2), SIP_PAGE2_RTCACHEFRIENDS)) {
07906                ASTOBJ_MARK(iterator);
07907                pruned++;
07908             }
07909             ASTOBJ_UNLOCK(iterator);
07910          } while (0) );
07911          if (pruned) {
07912             ASTOBJ_CONTAINER_PRUNE_MARKED(&peerl, sip_destroy_peer);
07913             ast_cli(fd, "%d peers pruned.\n", pruned);
07914          } else
07915             ast_cli(fd, "No peers found to prune.\n");
07916          ASTOBJ_CONTAINER_UNLOCK(&peerl);
07917       }
07918       if (pruneuser) {
07919          int pruned = 0;
07920 
07921          ASTOBJ_CONTAINER_WRLOCK(&userl);
07922          ASTOBJ_CONTAINER_TRAVERSE(&userl, 1, do {
07923             ASTOBJ_RDLOCK(iterator);
07924             if (name && regexec(&regexbuf, iterator->name, 0, NULL, 0)) {
07925                ASTOBJ_UNLOCK(iterator);
07926                continue;
07927             };
07928             if (ast_test_flag((&iterator->flags_page2), SIP_PAGE2_RTCACHEFRIENDS)) {
07929                ASTOBJ_MARK(iterator);
07930                pruned++;
07931             }
07932             ASTOBJ_UNLOCK(iterator);
07933          } while (0) );
07934          if (pruned) {
07935             ASTOBJ_CONTAINER_PRUNE_MARKED(&userl, sip_destroy_user);
07936             ast_cli(fd, "%d users pruned.\n", pruned);
07937          } else
07938             ast_cli(fd, "No users found to prune.\n");
07939          ASTOBJ_CONTAINER_UNLOCK(&userl);
07940       }
07941    } else {
07942       if (prunepeer) {
07943          if ((peer = ASTOBJ_CONTAINER_FIND_UNLINK(&peerl, name))) {
07944             if (!ast_test_flag((&peer->flags_page2), SIP_PAGE2_RTCACHEFRIENDS)) {
07945                ast_cli(fd, "Peer '%s' is not a Realtime peer, cannot be pruned.\n", name);
07946                ASTOBJ_CONTAINER_LINK(&peerl, peer);
07947             } else
07948                ast_cli(fd, "Peer '%s' pruned.\n", name);
07949             ASTOBJ_UNREF(peer, sip_destroy_peer);
07950          } else
07951             ast_cli(fd, "Peer '%s' not found.\n", name);
07952       }
07953       if (pruneuser) {
07954          if ((user = ASTOBJ_CONTAINER_FIND_UNLINK(&userl, name))) {
07955             if (!ast_test_flag((&user->flags_page2), SIP_PAGE2_RTCACHEFRIENDS)) {
07956                ast_cli(fd, "User '%s' is not a Realtime user, cannot be pruned.\n", name);
07957                ASTOBJ_CONTAINER_LINK(&userl, user);
07958             } else
07959                ast_cli(fd, "User '%s' pruned.\n", name);
07960             ASTOBJ_UNREF(user, sip_destroy_user);
07961          } else
07962             ast_cli(fd, "User '%s' not found.\n", name);
07963       }
07964    }
07965 
07966    return RESULT_SUCCESS;
07967 }

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

sip_read: Read SIP RTP from channel

Definition at line 3044 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.

03045 {
03046    struct ast_frame *fr;
03047    struct sip_pvt *p = ast->tech_pvt;
03048    ast_mutex_lock(&p->lock);
03049    fr = sip_rtp_read(ast, p);
03050    time(&p->lastrtprx);
03051    ast_mutex_unlock(&p->lock);
03052    return fr;
03053 }

static int sip_reg_timeout void *  data  )  [static]
 

sip_reg_timeout: Registration timeout, register again

Definition at line 5417 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().

05418 {
05419 
05420    /* if we are here, our registration timed out, so we'll just do it over */
05421    struct sip_registry *r = ASTOBJ_REF((struct sip_registry *) data);
05422    struct sip_pvt *p;
05423    int res;
05424 
05425    /* if we couldn't get a reference to the registry object, punt */
05426    if (!r)
05427       return 0;
05428 
05429    ast_log(LOG_NOTICE, "   -- Registration for '%s@%s' timed out, trying again (Attempt #%d)\n", r->username, r->hostname, r->regattempts); 
05430    if (r->call) {
05431       /* Unlink us, destroy old call.  Locking is not relevant here because all this happens
05432          in the single SIP manager thread. */
05433       p = r->call;
05434       if (p->registry)
05435          ASTOBJ_UNREF(p->registry, sip_registry_destroy);
05436       r->call = NULL;
05437       ast_set_flag(p, SIP_NEEDDESTROY);   
05438       /* Pretend to ACK anything just in case */
05439       __sip_pretend_ack(p);
05440    }
05441    /* If we have a limit, stop registration and give up */
05442    if (global_regattempts_max && (r->regattempts > global_regattempts_max)) {
05443       /* Ok, enough is enough. Don't try any more */
05444       /* We could add an external notification here... 
05445          steal it from app_voicemail :-) */
05446       ast_log(LOG_NOTICE, "   -- Giving up forever trying to register '%s@%s'\n", r->username, r->hostname);
05447       r->regstate=REG_STATE_FAILED;
05448    } else {
05449       r->regstate=REG_STATE_UNREGISTERED;
05450       r->timeout = -1;
05451       res=transmit_register(r, SIP_REGISTER, NULL, NULL);
05452    }
05453    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));
05454    ASTOBJ_UNREF(r,sip_registry_destroy);
05455    return 0;
05456 }

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

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

Definition at line 3257 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().

03258 {
03259    struct sip_registry *reg;
03260    char copy[256];
03261    char *username=NULL, *hostname=NULL, *secret=NULL, *authuser=NULL;
03262    char *porta=NULL;
03263    char *contact=NULL;
03264    char *stringp=NULL;
03265    
03266    if (!value)
03267       return -1;
03268    ast_copy_string(copy, value, sizeof(copy));
03269    stringp=copy;
03270    username = stringp;
03271    hostname = strrchr(stringp, '@');
03272    if (hostname) {
03273       *hostname = '\0';
03274       hostname++;
03275    }
03276    if (ast_strlen_zero(username) || ast_strlen_zero(hostname)) {
03277       ast_log(LOG_WARNING, "Format for registration is user[:secret[:authuser]]@host[:port][/contact] at line %d\n", lineno);
03278       return -1;
03279    }
03280    stringp=username;
03281    username = strsep(&stringp, ":");
03282    if (username) {
03283       secret = strsep(&stringp, ":");
03284       if (secret) 
03285          authuser = strsep(&stringp, ":");
03286    }
03287    stringp = hostname;
03288    hostname = strsep(&stringp, "/");
03289    if (hostname) 
03290       contact = strsep(&stringp, "/");
03291    if (ast_strlen_zero(contact))
03292       contact = "s";
03293    stringp=hostname;
03294    hostname = strsep(&stringp, ":");
03295    porta = strsep(&stringp, ":");
03296    
03297    if (porta && !atoi(porta)) {
03298       ast_log(LOG_WARNING, "%s is not a valid port number at line %d\n", porta, lineno);
03299       return -1;
03300    }
03301    reg = malloc(sizeof(struct sip_registry));
03302    if (!reg) {
03303       ast_log(LOG_ERROR, "Out of memory. Can't allocate SIP registry entry\n");
03304       return -1;
03305    }
03306    memset(reg, 0, sizeof(struct sip_registry));
03307    regobjs++;
03308    ASTOBJ_INIT(reg);
03309    ast_copy_string(reg->contact, contact, sizeof(reg->contact));
03310    if (username)
03311       ast_copy_string(reg->username, username, sizeof(reg->username));
03312    if (hostname)
03313       ast_copy_string(reg->hostname, hostname, sizeof(reg->hostname));
03314    if (authuser)
03315       ast_copy_string(reg->authuser, authuser, sizeof(reg->authuser));
03316    if (secret)
03317       ast_copy_string(reg->secret, secret, sizeof(reg->secret));
03318    reg->expire = -1;
03319    reg->timeout =  -1;
03320    reg->refresh = default_expiry;
03321    reg->portno = porta ? atoi(porta) : 0;
03322    reg->callid_valid = 0;
03323    reg->ocseq = 101;
03324    ASTOBJ_CONTAINER_LINK(&regl, reg);
03325    ASTOBJ_UNREF(reg,sip_registry_destroy);
03326    return 0;
03327 }

static void sip_registry_destroy struct sip_registry reg  )  [static]
 

sip_registry_destroy: Destroy registry object ---

Definition at line 2095 of file chan_sip.c.

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

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

02096 {
02097    /* Really delete */
02098    if (reg->call) {
02099       /* Clear registry before destroying to ensure
02100          we don't get reentered trying to grab the registry lock */
02101       reg->call->registry = NULL;
02102       sip_destroy(reg->call);
02103    }
02104    if (reg->expire > -1)
02105       ast_sched_del(sched, reg->expire);
02106    if (reg->timeout > -1)
02107       ast_sched_del(sched, reg->timeout);
02108    regobjs--;
02109    free(reg);
02110    
02111 }

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

sip_reload: Force reload of module from cli ---

Definition at line 13373 of file chan_sip.c.

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

Referenced by reload().

13374 {
13375 
13376    ast_mutex_lock(&sip_reload_lock);
13377    if (sip_reloading) {
13378       ast_verbose("Previous SIP reload not yet done\n");
13379    } else
13380       sip_reloading = 1;
13381    ast_mutex_unlock(&sip_reload_lock);
13382    restart_monitor();
13383 
13384    return 0;
13385 }

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

References __ourip, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL, AST_CAUSE_SWITCH_CONGESTION, AST_CAUSE_UNREGISTERED, 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(), sip_pvt::callid, calloc, create_addr(), sip_pvt::fromdomain, sip_pvt::fullcontact, global_capability, host, sip_pvt::lock, LOG_ERROR, LOG_NOTICE, sip_pvt::options, sip_pvt::ourip, sip_pvt::peername, sip_pvt::prefcodec, restart_monitor(), sip_pvt::sa, sip_alloc(), sip_destroy(), SIP_INVITE, sip_new(), sip_pvt::username, and sip_pvt::via.

11804 {
11805    int oldformat;
11806    struct sip_pvt *p;
11807    struct ast_channel *tmpc = NULL;
11808    char *ext, *host;
11809    char tmp[256];
11810    char *dest = data;
11811 
11812    oldformat = format;
11813    format &= ((AST_FORMAT_MAX_AUDIO << 1) - 1);
11814    if (!format) {
11815       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));
11816       *cause = AST_CAUSE_BEARERCAPABILITY_NOTAVAIL;   /* Can't find codec to connect to host */
11817       return NULL;
11818    }
11819    p = sip_alloc(NULL, NULL, 0, SIP_INVITE);
11820    if (!p) {
11821       ast_log(LOG_ERROR, "Unable to build sip pvt data for '%s' (Out of memory)\n", (char *)data);
11822       *cause = AST_CAUSE_SWITCH_CONGESTION;
11823       return NULL;
11824    }
11825 
11826    p->options = calloc(1, sizeof(*p->options));
11827    if (!p->options) {
11828       sip_destroy(p);
11829       ast_log(LOG_ERROR, "Unable to build option SIP data structure - Out of memory\n");
11830       *cause = AST_CAUSE_SWITCH_CONGESTION;
11831       return NULL;
11832    }
11833 
11834    ast_copy_string(tmp, dest, sizeof(tmp));
11835    host = strchr(tmp, '@');
11836    if (host) {
11837       *host = '\0';
11838       host++;
11839       ext = tmp;
11840    } else {
11841       ext = strchr(tmp, '/');
11842       if (ext) {
11843          *ext++ = '\0';
11844          host = tmp;
11845       }
11846       else {
11847          host = tmp;
11848          ext = NULL;
11849       }
11850    }
11851 
11852    if (create_addr(p, host)) {
11853       *cause = AST_CAUSE_UNREGISTERED;
11854       sip_destroy(p);
11855       return NULL;
11856    }
11857    if (ast_strlen_zero(p->peername) && ext)
11858       ast_copy_string(p->peername, ext, sizeof(p->peername));
11859    /* Recalculate our side, and recalculate Call ID */
11860    if (ast_sip_ouraddrfor(&p->sa.sin_addr,&p->ourip))
11861       memcpy(&p->ourip, &__ourip, sizeof(p->ourip));
11862    build_via(p, p->via, sizeof(p->via));
11863    build_callid(p->callid, sizeof(p->callid), p->ourip, p->fromdomain);
11864    
11865    /* We have an extension to call, don't use the full contact here */
11866    /* This to enable dialling registered peers with extension dialling,
11867       like SIP/peername/extension   
11868       SIP/peername will still use the full contact */
11869    if (ext) {
11870       ast_copy_string(p->username, ext, sizeof(p->username));
11871       p->fullcontact[0] = 0;  
11872    }
11873 #if 0
11874    printf("Setting up to call extension '%s' at '%s'\n", ext ? ext : "<none>", host);
11875 #endif
11876    p->prefcodec = format;
11877    ast_mutex_lock(&p->lock);
11878    tmpc = sip_new(p, AST_STATE_DOWN, host);  /* Place the call */
11879    ast_mutex_unlock(&p->lock);
11880    if (!tmpc)
11881       sip_destroy(p);
11882    ast_update_use_count();
11883    restart_monitor();
11884    return tmpc;
11885 }

static int sip_reregister void *  data  )  [static]
 

sip_reregister: Update registration with SIP Proxy---

Definition at line 5382 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 sip_send_all_registers().

05383 {
05384    /* if we are here, we know that we need to reregister. */
05385    struct sip_registry *r= ASTOBJ_REF((struct sip_registry *) data);
05386 
05387    /* if we couldn't get a reference to the registry object, punt */
05388    if (!r)
05389       return 0;
05390 
05391    if (r->call && recordhistory) {
05392       char tmp[80];
05393       snprintf(tmp, sizeof(tmp), "Account: %s@%s", r->username, r->hostname);
05394       append_history(r->call, "RegistryRenew", tmp);
05395    }
05396    /* Since registry's are only added/removed by the the monitor thread, this
05397       may be overkill to reference/dereference at all here */
05398    if (sipdebug)
05399       ast_log(LOG_NOTICE, "   -- Re-registration for  %s@%s\n", r->username, r->hostname);
05400 
05401    r->expire = -1;
05402    __sip_do_register(r);
05403    ASTOBJ_UNREF(r, sip_registry_destroy);
05404    return 0;
05405 }

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 2994 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().

02995 {
02996    /* Retrieve audio/etc from channel.  Assumes p->lock is already held. */
02997    struct ast_frame *f;
02998    static struct ast_frame null_frame = { AST_FRAME_NULL, };
02999    
03000    if (!p->rtp) {
03001       /* We have no RTP allocated for this channel */
03002       return &null_frame;
03003    }
03004 
03005    switch(ast->fdno) {
03006    case 0:
03007       f = ast_rtp_read(p->rtp);  /* RTP Audio */
03008       break;
03009    case 1:
03010       f = ast_rtcp_read(p->rtp); /* RTCP Control Channel */
03011       break;
03012    case 2:
03013       f = ast_rtp_read(p->vrtp); /* RTP Video */
03014       break;
03015    case 3:
03016       f = ast_rtcp_read(p->vrtp);   /* RTCP Control Channel for video */
03017       break;
03018    default:
03019       f = &null_frame;
03020    }
03021    /* Don't forward RFC2833 if we're not supposed to */
03022    if (f && (f->frametype == AST_FRAME_DTMF) && (ast_test_flag(p, SIP_DTMF) != SIP_DTMF_RFC2833))
03023       return &null_frame;
03024    if (p->owner) {
03025       /* We already hold the channel lock */
03026       if (f->frametype == AST_FRAME_VOICE) {
03027          if (f->subclass != p->owner->nativeformats) {
03028             ast_log(LOG_DEBUG, "Oooh, format changed to %d\n", f->subclass);
03029             p->owner->nativeformats = f->subclass;
03030             ast_set_read_format(p->owner, p->owner->readformat);
03031             ast_set_write_format(p->owner, p->owner->writeformat);
03032          }
03033          if ((ast_test_flag(p, SIP_DTMF) == SIP_DTMF_INBAND) && p->vad) {
03034             f = ast_dsp_process(p->owner, p->vad, f);
03035             if (f && (f->frametype == AST_FRAME_DTMF)) 
03036                ast_log(LOG_DEBUG, "* Detected inband DTMF '%c'\n", f->subclass);
03037          }
03038       }
03039    }
03040    return f;
03041 }

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

sip_scheddestroy: Schedule destruction of SIP call ---

Definition at line 1346 of file chan_sip.c.

References __sip_autodestruct(), append_history(), ast_sched_add(), ast_sched_del(), ast_verbose(), sip_pvt::autokillid, sip_pvt::callid, sched, 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().

01347 {
01348    char tmp[80];
01349    if (sip_debug_test_pvt(p))
01350       ast_verbose("Scheduling destruction of call '%s' in %d ms\n", p->callid, ms);
01351    if (recordhistory) {
01352       snprintf(tmp, sizeof(tmp), "%d ms", ms);
01353       append_history(p, "SchedDestroy", tmp);
01354    }
01355 
01356    if (p->autokillid > -1)
01357       ast_sched_del(sched, p->autokillid);
01358    p->autokillid = ast_sched_add(sched, ms, __sip_autodestruct, p);
01359    return 0;
01360 }

static void sip_send_all_registers void   )  [static]
 

sip_send_all_registers: Send all known registrations

Definition at line 13318 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().

13319 {
13320    int ms;
13321    int regspacing;
13322    if (!regobjs)
13323       return;
13324    regspacing = default_expiry * 1000/regobjs;
13325    if (regspacing > 100)
13326       regspacing = 100;
13327    ms = regspacing;
13328    ASTOBJ_CONTAINER_TRAVERSE(&regl, 1, do {
13329       ASTOBJ_WRLOCK(iterator);
13330       if (iterator->expire > -1)
13331          ast_sched_del(sched, iterator->expire);
13332       ms += regspacing;
13333       iterator->expire = ast_sched_add(sched, ms, sip_reregister, iterator);
13334       ASTOBJ_UNLOCK(iterator);
13335    } while (0)
13336    );
13337 }

static int sip_send_mwi_to_peer struct sip_peer peer  )  [static]
 

sip_send_mwi_to_peer: Send message waiting indication ---

Definition at line 11438 of file chan_sip.c.

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

11439 {
11440    /* Called with peerl lock, but releases it */
11441    struct sip_pvt *p;
11442    int newmsgs, oldmsgs;
11443 
11444    /* Check for messages */
11445    ast_app_messagecount(peer->mailbox, &newmsgs, &oldmsgs);
11446    
11447    time(&peer->lastmsgcheck);
11448    
11449    /* Return now if it's the same thing we told them last time */
11450    if (((newmsgs << 8) | (oldmsgs)) == peer->lastmsgssent) {
11451       return 0;
11452    }
11453    
11454    p = sip_alloc(NULL, NULL, 0, SIP_NOTIFY);
11455    if (!p) {
11456       ast_log(LOG_WARNING, "Unable to build sip pvt data for MWI\n");
11457       return -1;
11458    }
11459    peer->lastmsgssent = ((newmsgs << 8) | (oldmsgs));
11460    if (create_addr_from_peer(p, peer)) {
11461       /* Maybe they're not registered, etc. */
11462       sip_destroy(p);
11463       return 0;
11464    }
11465    /* Recalculate our side, and recalculate Call ID */
11466    if (ast_sip_ouraddrfor(&p->sa.sin_addr,&p->ourip))
11467       memcpy(&p->ourip, &__ourip, sizeof(p->ourip));
11468    build_via(p, p->via, sizeof(p->via));
11469    build_callid(p->callid, sizeof(p->callid), p->ourip, p->fromdomain);
11470    /* Send MWI */
11471    ast_set_flag(p, SIP_OUTGOING);
11472    transmit_notify_with_mwi(p, newmsgs, oldmsgs, peer->vmexten);
11473    sip_scheddestroy(p, 15000);
11474    return 0;
11475 }

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

sip_senddigit: Send DTMF character on SIP channel

Definition at line 2634 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().

02635 {
02636    struct sip_pvt *p = ast->tech_pvt;
02637    int res = 0;
02638    ast_mutex_lock(&p->lock);
02639    switch (ast_test_flag(p, SIP_DTMF)) {
02640    case SIP_DTMF_INFO:
02641       transmit_info_with_digit(p, digit);
02642       break;
02643    case SIP_DTMF_RFC2833:
02644       if (p->rtp)
02645          ast_rtp_senddigit(p->rtp, digit);
02646       break;
02647    case SIP_DTMF_INBAND:
02648       res = -1;
02649       break;
02650    }
02651    ast_mutex_unlock(&p->lock);
02652    return res;
02653 }

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

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

Definition at line 1592 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().

01593 {
01594    struct sip_pvt *p = ast->tech_pvt;
01595    int debug=sip_debug_test_pvt(p);
01596 
01597    if (debug)
01598       ast_verbose("Sending text %s on %s\n", text, ast->name);
01599    if (!p)
01600       return -1;
01601    if (ast_strlen_zero(text))
01602       return 0;
01603    if (debug)
01604       ast_verbose("Really sending text %s on %s\n", text, ast->name);
01605    transmit_message_with_text(p, text);
01606    return 0;   
01607 }

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 12999 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_pvt::rtp, SIP_GOTREFER, SIP_NEEDREINVITE, SIP_PENDINGBYE, ast_channel::tech_pvt, transmit_reinvite_with_sdp(), sip_pvt::vredirip, and sip_pvt::vrtp.

13000 {
13001    struct sip_pvt *p;
13002    int changed = 0;
13003 
13004    p = chan->tech_pvt;
13005    if (!p) 
13006       return -1;
13007    ast_mutex_lock(&p->lock);
13008    if (rtp) {
13009       changed |= ast_rtp_get_peer(rtp, &p->redirip);
13010    } else if (p->redirip.sin_addr.s_addr || ntohs(p->redirip.sin_port) != 0) {
13011       memset(&p->redirip, 0, sizeof(p->redirip));
13012       changed = 1;
13013    }
13014    if (vrtp) {
13015       changed |= ast_rtp_get_peer(vrtp, &p->vredirip);
13016    } else if (p->vredirip.sin_addr.s_addr || ntohs(p->vredirip.sin_port) != 0) {
13017       memset(&p->vredirip, 0, sizeof(p->vredirip));
13018       changed = 1;
13019    }
13020    if (codecs && (p->redircodecs != codecs)) {
13021       p->redircodecs = codecs;
13022       changed = 1;
13023    }
13024    if (changed && !ast_test_flag(p, SIP_GOTREFER)) {
13025       if (!p->pendinginvite) {
13026          if (option_debug > 2) {
13027             char iabuf[INET_ADDRSTRLEN];
13028             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));
13029          }
13030          transmit_reinvite_with_sdp(p);
13031       } else if (!ast_test_flag(p, SIP_PENDINGBYE)) {
13032          if (option_debug > 2) {
13033             char iabuf[INET_ADDRSTRLEN];
13034             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));
13035          }
13036          ast_set_flag(p, SIP_NEEDREINVITE);  
13037       }
13038    }
13039    /* Reset lastrtprx timer */
13040    time(&p->lastrtprx);
13041    time(&p->lastrtptx);
13042    ast_mutex_unlock(&p->lock);
13043    return 0;
13044 }

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

sip_show_channel: Show details of one call ---

Definition at line 8644 of file chan_sip.c.

References ast_cli(), ast_getformatname(), ast_inet_ntoa(), ast_mutex_lock(), 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, 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.

08645 {
08646    struct sip_pvt *cur;
08647    char iabuf[INET_ADDRSTRLEN];
08648    size_t len;
08649    int found = 0;
08650 
08651    if (argc != 4)
08652       return RESULT_SHOWUSAGE;
08653    len = strlen(argv[3]);
08654    ast_mutex_lock(&iflock);
08655    cur = iflist;
08656    while(cur) {
08657       if (!strncasecmp(cur->callid, argv[3],len)) {
08658          ast_cli(fd,"\n");
08659          if (cur->subscribed != NONE)
08660             ast_cli(fd, "  * Subscription (type: %s)\n", subscription_type2str(cur->subscribed));
08661          else
08662             ast_cli(fd, "  * SIP Call\n");
08663          ast_cli(fd, "  Direction:              %s\n", ast_test_flag(cur, SIP_OUTGOING)?"Outgoing":"Incoming");
08664          ast_cli(fd, "  Call-ID:                %s\n", cur->callid);
08665          ast_cli(fd, "  Our Codec Capability:   %d\n", cur->capability);
08666          ast_cli(fd, "  Non-Codec Capability:   %d\n", cur->noncodeccapability);
08667          ast_cli(fd, "  Their Codec Capability:   %d\n", cur->peercapability);
08668          ast_cli(fd, "  Joint Codec Capability:   %d\n", cur->jointcapability);
08669          ast_cli(fd, "  Format                  %s\n", ast_getformatname(cur->owner ? cur->owner->nativeformats : 0) );
08670          ast_cli(fd, "  Theoretical Address:    %s:%d\n", ast_inet_ntoa(iabuf, sizeof(iabuf), cur->sa.sin_addr), ntohs(cur->sa.sin_port));
08671          ast_cli(fd, "  Received Address:       %s:%d\n", ast_inet_ntoa(iabuf, sizeof(iabuf), cur->recv.sin_addr), ntohs(cur->recv.sin_port));
08672          ast_cli(fd, "  NAT Support:            %s\n", nat2str(ast_test_flag(cur, SIP_NAT)));
08673          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)" );
08674          ast_cli(fd, "  Our Tag:                %s\n", cur->tag);
08675          ast_cli(fd, "  Their Tag:              %s\n", cur->theirtag);
08676          ast_cli(fd, "  SIP User agent:         %s\n", cur->useragent);
08677          if (!ast_strlen_zero(cur->username))
08678             ast_cli(fd, "  Username:               %s\n", cur->username);
08679          if (!ast_strlen_zero(cur->peername))
08680             ast_cli(fd, "  Peername:               %s\n", cur->peername);
08681          if (!ast_strlen_zero(cur->uri))
08682             ast_cli(fd, "  Original uri:           %s\n", cur->uri);
08683          if (!ast_strlen_zero(cur->cid_num))
08684             ast_cli(fd, "  Caller-ID:              %s\n", cur->cid_num);
08685          ast_cli(fd, "  Need Destroy:           %d\n", ast_test_flag(cur, SIP_NEEDDESTROY));
08686          ast_cli(fd, "  Last Message:           %s\n", cur->lastmsg);
08687          ast_cli(fd, "  Promiscuous Redir:      %s\n", ast_test_flag(cur, SIP_PROMISCREDIR) ? "Yes" : "No");
08688          ast_cli(fd, "  Route:                  %s\n", cur->route ? cur->route->hop : "N/A");
08689          ast_cli(fd, "  DTMF Mode:              %s\n", dtmfmode2str(ast_test_flag(cur, SIP_DTMF)));
08690          ast_cli(fd, "  SIP Options:            ");
08691          if (cur->sipoptions) {
08692             int x;
08693             for (x=0 ; (x < (sizeof(sip_options) / sizeof(sip_options[0]))); x++) {
08694                if (cur->sipoptions & sip_options[x].id)
08695                   ast_cli(fd, "%s ", sip_options[x].text);
08696             }
08697          } else
08698             ast_cli(fd, "(none)\n");
08699          ast_cli(fd, "\n\n");
08700          found++;
08701       }
08702       cur = cur->next;
08703    }
08704    ast_mutex_unlock(&iflock);
08705    if (!found) 
08706       ast_cli(fd, "No such SIP Call ID starting with '%s'\n", argv[3]);
08707    return RESULT_SUCCESS;
08708 }

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

sip_show_channels: Show active SIP channels ---

Definition at line 8445 of file chan_sip.c.

References __sip_show_channels().

08446 {
08447         return __sip_show_channels(fd, argc, argv, 0);
08448 }

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

Definition at line 8000 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.

08001 {
08002    struct domain *d;
08003 
08004    if (AST_LIST_EMPTY(&domain_list)) {
08005       ast_cli(fd, "SIP Domain support not enabled.\n\n");
08006       return RESULT_SUCCESS;
08007    } else {
08008       ast_cli(fd, FORMAT, "Our local SIP domains:", "Context", "Set by");
08009       AST_LIST_LOCK(&domain_list);
08010       AST_LIST_TRAVERSE(&domain_list, d, list)
08011          ast_cli(fd, FORMAT, d->domain, ast_strlen_zero(d->context) ? "(default)": d->context,
08012             domain_mode_to_text(d->mode));
08013       AST_LIST_UNLOCK(&domain_list);
08014       ast_cli(fd, "\n");
08015       return RESULT_SUCCESS;
08016    }
08017 }

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

sip_show_history: Show history details of one call ---

Definition at line 8711 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.

08712 {
08713    struct sip_pvt *cur;
08714    struct sip_history *hist;
08715    size_t len;
08716    int x;
08717    int found = 0;
08718 
08719    if (argc != 4)
08720       return RESULT_SHOWUSAGE;
08721    if (!recordhistory)
08722       ast_cli(fd, "\n***Note: History recording is currently DISABLED.  Use 'sip history' to ENABLE.\n");
08723    len = strlen(argv[3]);
08724    ast_mutex_lock(&iflock);
08725    cur = iflist;
08726    while(cur) {
08727       if (!strncasecmp(cur->callid, argv[3], len)) {
08728          ast_cli(fd,"\n");
08729          if (cur->subscribed != NONE)
08730             ast_cli(fd, "  * Subscription\n");
08731          else
08732             ast_cli(fd, "  * SIP Call\n");
08733          x = 0;
08734          hist = cur->history;
08735          while(hist) {
08736             x++;
08737             ast_cli(fd, "%d. %s\n", x, hist->event);
08738             hist = hist->next;
08739          }
08740          if (!x)
08741             ast_cli(fd, "Call '%s' has no history\n", cur->callid);
08742          found++;
08743       }
08744       cur = cur->next;
08745    }
08746    ast_mutex_unlock(&iflock);
08747    if (!found) 
08748       ast_cli(fd, "No such SIP Call ID starting with '%s'\n", argv[3]);
08749    return RESULT_SUCCESS;
08750 }

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

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

07467                                                           {
07468 #define FORMAT  "%-25.25s %-15.15s %-15.15s \n"
07469 #define FORMAT2 "%-25.25s %-15.15s %-15.15s \n"
07470    char ilimits[40];
07471    char iused[40];
07472    int showall = 0;
07473 
07474    if (argc < 3) 
07475       return RESULT_SHOWUSAGE;
07476 
07477    if (argc == 4 && !strcmp(argv[3],"all")) 
07478          showall = 1;
07479    
07480    ast_cli(fd, FORMAT, "* User name", "In use", "Limit");
07481    ASTOBJ_CONTAINER_TRAVERSE(&userl, 1, do {
07482       ASTOBJ_RDLOCK(iterator);
07483       if (iterator->call_limit)
07484          snprintf(ilimits, sizeof(ilimits), "%d", iterator->call_limit);
07485       else 
07486          ast_copy_string(ilimits, "N/A", sizeof(ilimits));
07487       snprintf(iused, sizeof(iused), "%d", iterator->inUse);
07488       if (showall || iterator->call_limit)
07489          ast_cli(fd, FORMAT2, iterator->name, iused, ilimits);
07490       ASTOBJ_UNLOCK(iterator);
07491    } while (0) );
07492 
07493    ast_cli(fd, FORMAT, "* Peer name", "In use", "Limit");
07494 
07495    ASTOBJ_CONTAINER_TRAVERSE(&peerl, 1, do {
07496       ASTOBJ_RDLOCK(iterator);
07497       if (iterator->call_limit)
07498          snprintf(ilimits, sizeof(ilimits), "%d", iterator->call_limit);
07499       else 
07500          ast_copy_string(ilimits, "N/A", sizeof(ilimits));
07501       snprintf(iused, sizeof(iused), "%d", iterator->inUse);
07502       if (showall || iterator->call_limit)
07503          ast_cli(fd, FORMAT2, iterator->name, iused, ilimits);
07504       ASTOBJ_UNLOCK(iterator);
07505    } while (0) );
07506 
07507    return RESULT_SUCCESS;
07508 #undef FORMAT
07509 #undef FORMAT2
07510 }

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

sip_show_objects: List all allocated SIP Objects ---

Definition at line 7773 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.

07774 {
07775    char tmp[256];
07776    if (argc != 3)
07777       return RESULT_SHOWUSAGE;
07778    ast_cli(fd, "-= User objects: %d static, %d realtime =-\n\n", suserobjs, ruserobjs);
07779    ASTOBJ_CONTAINER_DUMP(fd, tmp, sizeof(tmp), &userl);
07780    ast_cli(fd, "-= Peer objects: %d static, %d realtime, %d autocreate =-\n\n", speerobjs, rpeerobjs, apeerobjs);
07781    ASTOBJ_CONTAINER_DUMP(fd, tmp, sizeof(tmp), &peerl);
07782    ast_cli(fd, "-= Registry objects: %d =-\n\n", regobjs);
07783    ASTOBJ_CONTAINER_DUMP(fd, tmp, sizeof(tmp), &regl);
07784    return RESULT_SUCCESS;
07785 }

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

sip_show_peer: Show one peer in detail ---

Definition at line 8057 of file chan_sip.c.

References _sip_show_peer().

08058 {
08059    return _sip_show_peer(0, fd, NULL, NULL, argc, argv);
08060 }

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

sip_show_peers: CLI Show Peers command

Definition at line 7634 of file chan_sip.c.

References _sip_show_peers().

07635 {
07636    return _sip_show_peers(fd, NULL, NULL, NULL, argc, argv);
07637 }

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

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

08310 {
08311 #define FORMAT2 "%-30.30s  %-12.12s  %8.8s %-20.20s\n"
08312 #define FORMAT  "%-30.30s  %-12.12s  %8d %-20.20s\n"
08313    char host[80];
08314 
08315    if (argc != 3)
08316       return RESULT_SHOWUSAGE;
08317    ast_cli(fd, FORMAT2, "Host", "Username", "Refresh", "State");
08318    ASTOBJ_CONTAINER_TRAVERSE(&regl, 1, do {
08319       ASTOBJ_RDLOCK(iterator);
08320       snprintf(host, sizeof(host), "%s:%d", iterator->hostname, iterator->portno ? iterator->portno : DEFAULT_SIP_PORT);
08321       ast_cli(fd, FORMAT, host, iterator->username, iterator->refresh, regstate2str(iterator->regstate));
08322       ASTOBJ_UNLOCK(iterator);
08323    } while(0));
08324    return RESULT_SUCCESS;
08325 #undef FORMAT
08326 #undef FORMAT2
08327 }

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 8330 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_flags, global_flags_page2, 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, prefs, 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.

08331 {
08332    char tmp[BUFSIZ];
08333    int realtimepeers = 0;
08334    int realtimeusers = 0;
08335 
08336    realtimepeers = ast_check_realtime("sippeers");
08337    realtimeusers = ast_check_realtime("sipusers");
08338 
08339    if (argc != 3)
08340       return RESULT_SHOWUSAGE;
08341    ast_cli(fd, "\n\nGlobal Settings:\n");
08342    ast_cli(fd, "----------------\n");
08343    ast_cli(fd, "  SIP Port:               %d\n", ntohs(bindaddr.sin_port));
08344    ast_cli(fd, "  Bindaddress:            %s\n", ast_inet_ntoa(tmp, sizeof(tmp), bindaddr.sin_addr));
08345    ast_cli(fd, "  Videosupport:           %s\n", videosupport ? "Yes" : "No");
08346    ast_cli(fd, "  AutoCreatePeer:         %s\n", autocreatepeer ? "Yes" : "No");
08347    ast_cli(fd, "  Allow unknown access:   %s\n", global_allowguest ? "Yes" : "No");
08348    ast_cli(fd, "  Promsic. redir:         %s\n", ast_test_flag(&global_flags, SIP_PROMISCREDIR) ? "Yes" : "No");
08349    ast_cli(fd, "  SIP domain support:     %s\n", AST_LIST_EMPTY(&domain_list) ? "No" : "Yes");
08350    ast_cli(fd, "  Call to non-local dom.: %s\n", allow_external_domains ? "Yes" : "No");
08351    ast_cli(fd, "  URI user is phone no:   %s\n", ast_test_flag(&global_flags, SIP_USEREQPHONE) ? "Yes" : "No");
08352    ast_cli(fd, "  Our auth realm          %s\n", global_realm);
08353    ast_cli(fd, "  Realm. auth:            %s\n", authl ? "Yes": "No");
08354    ast_cli(fd, "  Always auth rejects:    %s\n", global_alwaysauthreject ? "Yes" : "No");
08355    ast_cli(fd, "  User Agent:             %s\n", default_useragent);
08356    ast_cli(fd, "  MWI checking interval:  %d secs\n", global_mwitime);
08357    ast_cli(fd, "  Reg. context:           %s\n", ast_strlen_zero(regcontext) ? "(not set)" : regcontext);
08358    ast_cli(fd, "  Caller ID:              %s\n", default_callerid);
08359    ast_cli(fd, "  From: Domain:           %s\n", default_fromdomain);
08360    ast_cli(fd, "  Record SIP history:     %s\n", recordhistory ? "On" : "Off");
08361    ast_cli(fd, "  Call Events:            %s\n", callevents ? "On" : "Off");
08362    ast_cli(fd, "  IP ToS:                 0x%x\n", tos);
08363 #ifdef OSP_SUPPORT
08364    ast_cli(fd, "  OSP Support:            Yes\n");
08365 #else
08366    ast_cli(fd, "  OSP Support:            No\n");
08367 #endif
08368    if (!realtimepeers && !realtimeusers)
08369       ast_cli(fd, "  SIP realtime:           Disabled\n" );
08370    else
08371       ast_cli(fd, "  SIP realtime:           Enabled\n" );
08372 
08373    ast_cli(fd, "\nGlobal Signalling Settings:\n");
08374    ast_cli(fd, "---------------------------\n");
08375    ast_cli(fd, "  Codecs:                 ");
08376    print_codec_to_cli(fd, &prefs);
08377    ast_cli(fd, "\n");
08378    ast_cli(fd, "  Relax DTMF:             %s\n", relaxdtmf ? "Yes" : "No");
08379    ast_cli(fd, "  Compact SIP headers:    %s\n", compactheaders ? "Yes" : "No");
08380    ast_cli(fd, "  RTP Timeout:            %d %s\n", global_rtptimeout, global_rtptimeout ? "" : "(Disabled)" );
08381    ast_cli(fd, "  RTP Hold Timeout:       %d %s\n", global_rtpholdtimeout, global_rtpholdtimeout ? "" : "(Disabled)");
08382    ast_cli(fd, "  MWI NOTIFY mime type:   %s\n", default_notifymime);
08383    ast_cli(fd, "  DNS SRV lookup:         %s\n", srvlookup ? "Yes" : "No");
08384    ast_cli(fd, "  Pedantic SIP support:   %s\n", pedanticsipchecking ? "Yes" : "No");
08385    ast_cli(fd, "  Reg. max duration:      %d secs\n", max_expiry);
08386    ast_cli(fd, "  Reg. default duration:  %d secs\n", default_expiry);
08387    ast_cli(fd, "  Outbound reg. timeout:  %d secs\n", global_reg_timeout);
08388    ast_cli(fd, "  Outbound reg. attempts: %d\n", global_regattempts_max);
08389    ast_cli(fd, "  Notify ringing state:   %s\n", global_notifyringing ? "Yes" : "No");
08390    ast_cli(fd, "\nDefault Settings:\n");
08391    ast_cli(fd, "-----------------\n");
08392    ast_cli(fd, "  Context:                %s\n", default_context);
08393    ast_cli(fd, "  Nat:                    %s\n", nat2str(ast_test_flag(&global_flags, SIP_NAT)));
08394    ast_cli(fd, "  DTMF:                   %s\n", dtmfmode2str(ast_test_flag(&global_flags, SIP_DTMF)));
08395    ast_cli(fd, "  Qualify:                %d\n", default_qualify);
08396    ast_cli(fd, "  Use ClientCode:         %s\n", ast_test_flag(&global_flags, SIP_USECLIENTCODE) ? "Yes" : "No");
08397    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" );
08398    ast_cli(fd, "  Language:               %s\n", ast_strlen_zero(default_language) ? "(Defaults to English)" : default_language);
08399    ast_cli(fd, "  Musicclass:             %s\n", global_musicclass);
08400    ast_cli(fd, "  Voice Mail Extension:   %s\n", global_vmexten);
08401 
08402    
08403    if (realtimepeers || realtimeusers) {
08404       ast_cli(fd, "\nRealtime SIP Settings:\n");
08405       ast_cli(fd, "----------------------\n");
08406       ast_cli(fd, "  Realtime Peers:         %s\n", realtimepeers ? "Yes" : "No");
08407       ast_cli(fd, "  Realtime Users:         %s\n", realtimeusers ? "Yes" : "No");
08408       ast_cli(fd, "  Cache Friends:          %s\n", ast_test_flag(&global_flags_page2, SIP_PAGE2_RTCACHEFRIENDS) ? "Yes" : "No");
08409       ast_cli(fd, "  Update:                 %s\n", ast_test_flag(&global_flags_page2, SIP_PAGE2_RTUPDATE) ? "Yes" : "No");
08410       ast_cli(fd, "  Ignore Reg. Expire:     %s\n", ast_test_flag(&global_flags_page2, SIP_PAGE2_IGNOREREGEXPIRE) ? "Yes" : "No");
08411       ast_cli(fd, "  Auto Clear:             %d\n", global_rtautoclear);
08412    }
08413    ast_cli(fd, "\n----\n");
08414    return RESULT_SUCCESS;
08415 }

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

sip_show_subscriptions: Show active SIP subscriptions ---

Definition at line 8451 of file chan_sip.c.

References __sip_show_channels().

08452 {
08453         return __sip_show_channels(fd, argc, argv, 1);
08454 }

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

sip_show_user: Show one user in detail ---

Definition at line 8245 of file chan_sip.c.

References ast_callerid_merge(), ast_cdr_flags2str(), ast_cli(), ast_codec_pref_index(), ast_describe_caller_presentation(), ast_getformatname(), ast_strlen_zero(), ASTOBJ_UNREF, find_user(), ast_variable::name, ast_variable::next, print_group(), RESULT_SHOWUSAGE, sip_destroy_user(), user, and ast_variable::value.

08246 {
08247    char cbuf[256];
08248    struct sip_user *user;
08249    struct ast_codec_pref *pref;
08250    struct ast_variable *v;
08251    int x = 0, codec = 0, load_realtime = 0;
08252 
08253    if (argc < 4)
08254       return RESULT_SHOWUSAGE;
08255 
08256    /* Load from realtime storage? */
08257    load_realtime = (argc == 5 && !strcmp(argv[4], "load")) ? 1 : 0;
08258 
08259    user = find_user(argv[3], load_realtime);
08260    if (user) {
08261       ast_cli(fd,"\n\n");
08262       ast_cli(fd, "  * Name       : %s\n", user->name);
08263       ast_cli(fd, "  Secret       : %s\n", ast_strlen_zero(user->secret)?"<Not set>":"<Set>");
08264       ast_cli(fd, "  MD5Secret    : %s\n", ast_strlen_zero(user->md5secret)?"<Not set>":"<Set>");
08265       ast_cli(fd, "  Context      : %s\n", user->context);
08266       ast_cli(fd, "  Language     : %s\n", user->language);
08267       if (!ast_strlen_zero(user->accountcode))
08268          ast_cli(fd, "  Accountcode  : %s\n", user->accountcode);
08269       ast_cli(fd, "  AMA flags    : %s\n", ast_cdr_flags2str(user->amaflags));
08270       ast_cli(fd, "  CallingPres  : %s\n", ast_describe_caller_presentation(user->callingpres));
08271       ast_cli(fd, "  Call limit   : %d\n", user->call_limit);
08272       ast_cli(fd, "  Callgroup    : ");
08273       print_group(fd, user->callgroup, 0);
08274       ast_cli(fd, "  Pickupgroup  : ");
08275       print_group(fd, user->pickupgroup, 0);
08276       ast_cli(fd, "  Callerid     : %s\n", ast_callerid_merge(cbuf, sizeof(cbuf), user->cid_name, user->cid_num, "<unspecified>"));
08277       ast_cli(fd, "  ACL          : %s\n", (user->ha?"Yes":"No"));
08278       ast_cli(fd, "  Codec Order  : (");
08279       pref = &user->prefs;
08280       for(x = 0; x < 32 ; x++) {
08281          codec = ast_codec_pref_index(pref,x);
08282          if (!codec)
08283             break;
08284          ast_cli(fd, "%s", ast_getformatname(codec));
08285          if (x < 31 && ast_codec_pref_index(pref,x+1))
08286             ast_cli(fd, "|");
08287       }
08288 
08289       if (!x)
08290          ast_cli(fd, "none");
08291       ast_cli(fd, ")\n");
08292 
08293       if (user->chanvars) {
08294          ast_cli(fd, "  Variables    :\n");
08295          for (v = user->chanvars ; v ; v = v->next)
08296             ast_cli(fd, "                 %s = %s\n", v->name, v->value);
08297       }
08298       ast_cli(fd,"\n");
08299       ASTOBJ_UNREF(user,sip_destroy_user);
08300    } else {
08301       ast_cli(fd,"User %s not found.\n", argv[3]);
08302       ast_cli(fd,"\n");
08303    }
08304 
08305    return RESULT_SUCCESS;
08306 }

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

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

Definition at line 7555 of file chan_sip.c.

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

07556 {
07557    regex_t regexbuf;
07558    int havepattern = 0;
07559 
07560 #define FORMAT  "%-25.25s  %-15.15s  %-15.15s  %-15.15s  %-5.5s%-10.10s\n"
07561 
07562    switch (argc) {
07563    case 5:
07564       if (!strcasecmp(argv[3], "like")) {
07565          if (regcomp(&regexbuf, argv[4], REG_EXTENDED | REG_NOSUB))
07566             return RESULT_SHOWUSAGE;
07567          havepattern = 1;
07568       } else
07569          return RESULT_SHOWUSAGE;
07570    case 3:
07571       break;
07572    default:
07573       return RESULT_SHOWUSAGE;
07574    }
07575 
07576    ast_cli(fd, FORMAT, "Username", "Secret", "Accountcode", "Def.Context", "ACL", "NAT");
07577    ASTOBJ_CONTAINER_TRAVERSE(&userl, 1, do {
07578       ASTOBJ_RDLOCK(iterator);
07579 
07580       if (havepattern && regexec(&regexbuf, iterator->name, 0, NULL, 0)) {
07581          ASTOBJ_UNLOCK(iterator);
07582          continue;
07583       }
07584 
07585       ast_cli(fd, FORMAT, iterator->name, 
07586          iterator->secret, 
07587          iterator->accountcode,
07588          iterator->context,
07589          iterator->ha ? "Yes" : "No",
07590          nat2str(ast_test_flag(iterator, SIP_NAT)));
07591       ASTOBJ_UNLOCK(iterator);
07592    } while (0)
07593    );
07594 
07595    if (havepattern)
07596       regfree(&regexbuf);
07597 
07598    return RESULT_SUCCESS;
07599 #undef FORMAT
07600 }

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 13227 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().

13228 {
13229    char *cdest;
13230    char *extension, *host, *port;
13231    char tmp[80];
13232    
13233    cdest = ast_strdupa(dest);
13234    if (!cdest) {
13235       ast_log(LOG_ERROR, "Problem allocating the memory\n");
13236       return 0;
13237    }
13238    extension = strsep(&cdest, "@");
13239    host = strsep(&cdest, ":");
13240    port = strsep(&cdest, ":");
13241    if (!extension) {
13242       ast_log(LOG_ERROR, "Missing mandatory argument: extension\n");
13243       return 0;
13244    }
13245 
13246    /* we'll issue the redirect message here */
13247    if (!host) {
13248       char *localtmp;
13249       ast_copy_string(tmp, get_header(&p->initreq, "To"), sizeof(tmp));
13250       if (!strlen(tmp)) {
13251          ast_log(LOG_ERROR, "Cannot retrieve the 'To' header from the original SIP request!\n");
13252          return 0;
13253       }
13254       if ((localtmp = strstr(tmp, "sip:")) && (localtmp = strchr(localtmp, '@'))) {
13255          char lhost[80], lport[80];
13256          memset(lhost, 0, sizeof(lhost));
13257          memset(lport, 0, sizeof(lport));
13258          localtmp++;
13259          /* This is okey because lhost and lport are as big as tmp */
13260          sscanf(localtmp, "%[^<>:; ]:%[^<>:; ]", lhost, lport);
13261          if (!strlen(lhost)) {
13262             ast_log(LOG_ERROR, "Can't find the host address\n");
13263             return 0;
13264          }
13265          host = ast_strdupa(lhost);
13266          if (!host) {
13267             ast_log(LOG_ERROR, "Problem allocating the memory\n");
13268             return 0;
13269          }
13270          if (!ast_strlen_zero(lport)) {
13271             port = ast_strdupa(lport);
13272             if (!port) {
13273                ast_log(LOG_ERROR, "Problem allocating the memory\n");
13274                return 0;
13275             }
13276          }
13277       }
13278    }
13279 
13280    snprintf(p->our_contact, sizeof(p->our_contact), "Transfer <sip:%s@%s%s%s>", extension, host, port ? ":" : "", port ? port : "");
13281    transmit_response_reliable(p, "302 Moved Temporarily", &p->initreq, 1);
13282 
13283    /* this is all that we want to send to that SIP device */
13284    ast_set_flag(p, SIP_ALREADYGONE);
13285 
13286    /* hangup here */
13287    return -1;
13288 }

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

sip_transfer: Transfer SIP call

Definition at line 2658 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().

02659 {
02660    struct sip_pvt *p = ast->tech_pvt;
02661    int res;
02662 
02663    ast_mutex_lock(&p->lock);
02664    if (ast->_state == AST_STATE_RING)
02665       res = sip_sipredirect(p, dest);
02666    else
02667       res = transmit_refer(p, dest);
02668    ast_mutex_unlock(&p->lock);
02669    return res;
02670 }

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

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

Definition at line 2565 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.

02566 {
02567    struct sip_pvt *p = ast->tech_pvt;
02568    int res = 0;
02569    switch (frame->frametype) {
02570    case AST_FRAME_VOICE:
02571       if (!(frame->subclass & ast->nativeformats)) {
02572          ast_log(LOG_WARNING, "Asked to transmit frame type %d, while native formats is %d (read/write = %d/%d)\n",
02573             frame->subclass, ast->nativeformats, ast->readformat, ast->writeformat);
02574          return 0;
02575       }
02576       if (p) {
02577          ast_mutex_lock(&p->lock);
02578          if (p->rtp) {
02579             /* If channel is not up, activate early media session */
02580             if ((ast->_state != AST_STATE_UP) && !ast_test_flag(p, SIP_PROGRESS_SENT) && !ast_test_flag(p, SIP_OUTGOING)) {
02581                transmit_response_with_sdp(p, "183 Session Progress", &p->initreq, 0);
02582                ast_set_flag(p, SIP_PROGRESS_SENT); 
02583             }
02584             time(&p->lastrtptx);
02585             res =  ast_rtp_write(p->rtp, frame);
02586          }
02587          ast_mutex_unlock(&p->lock);
02588       }
02589       break;
02590    case AST_FRAME_VIDEO:
02591       if (p) {
02592          ast_mutex_lock(&p->lock);
02593          if (p->vrtp) {
02594             /* Activate video early media */
02595             if ((ast->_state != AST_STATE_UP) && !ast_test_flag(p, SIP_PROGRESS_SENT) && !ast_test_flag(p, SIP_OUTGOING)) {
02596                transmit_response_with_sdp(p, "183 Session Progress", &p->initreq, 0);
02597                ast_set_flag(p, SIP_PROGRESS_SENT); 
02598             }
02599             time(&p->lastrtptx);
02600             res =  ast_rtp_write(p->vrtp, frame);
02601          }
02602          ast_mutex_unlock(&p->lock);
02603       }
02604       break;
02605    case AST_FRAME_IMAGE:
02606       return 0;
02607       break;
02608    default: 
02609       ast_log(LOG_WARNING, "Can't send %d type frames with SIP write\n", frame->frametype);
02610       return 0;
02611    }
02612 
02613    return res;
02614 }

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

sipsock_read: Read data from SIP socket ---

Definition at line 11342 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().

11343 {
11344    struct sip_request req;
11345    struct sockaddr_in sin = { 0, };
11346    struct sip_pvt *p;
11347    int res;
11348    socklen_t len;
11349    int nounlock;
11350    int recount = 0;
11351    char iabuf[INET_ADDRSTRLEN];
11352    unsigned int lockretry = 100;
11353 
11354    len = sizeof(sin);
11355    memset(&req, 0, sizeof(req));
11356    res = recvfrom(sipsock, req.data, sizeof(req.data) - 1, 0, (struct sockaddr *)&sin, &len);
11357    if (res < 0) {
11358 #if !defined(__FreeBSD__)
11359       if (errno == EAGAIN)
11360          ast_log(LOG_NOTICE, "SIP: Received packet with bad UDP checksum\n");
11361       else 
11362 #endif
11363       if (errno != ECONNREFUSED)
11364          ast_log(LOG_WARNING, "Recv error: %s\n", strerror(errno));
11365       return 1;
11366    }
11367    if (res == sizeof(req.data)) {
11368       ast_log(LOG_DEBUG, "Received packet exceeds buffer. Data is possibly lost\n");
11369       req.data[sizeof(req.data) - 1] = '\0';
11370    } else
11371       req.data[res] = '\0';
11372    req.len = res;
11373    if(sip_debug_test_addr(&sin))
11374       ast_set_flag(&req, SIP_PKT_DEBUG);
11375    if (pedanticsipchecking)
11376       req.len = lws2sws(req.data, req.len);  /* Fix multiline headers */
11377    if (ast_test_flag(&req, SIP_PKT_DEBUG)) {
11378       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);
11379    }
11380    parse_request(&req);
11381    req.method = find_sip_method(req.rlPart1);
11382    if (ast_test_flag(&req, SIP_PKT_DEBUG)) {
11383       ast_verbose("--- (%d headers %d lines)%s ---\n", req.headers, req.lines, (req.headers + req.lines == 0) ? " Nat keepalive" : "");
11384    }
11385 
11386    if (req.headers < 2) {
11387       /* Must have at least two headers */
11388       return 1;
11389    }
11390 
11391 
11392    /* Process request, with netlock held */
11393 retrylock:
11394    ast_mutex_lock(&netlock);
11395    p = find_call(&req, &sin, req.method);
11396    if (p) {
11397       /* Go ahead and lock the owner if it has one -- we may need it */
11398       if (p->owner && ast_mutex_trylock(&p->owner->lock)) {
11399          ast_log(LOG_DEBUG, "Failed to grab lock, trying again...\n");
11400          ast_mutex_unlock(&p->lock);
11401          ast_mutex_unlock(&netlock);
11402          /* Sleep for a very short amount of time */
11403          usleep(1);
11404          if (--lockretry)
11405             goto retrylock;
11406       }
11407       if (!lockretry) {
11408          ast_log(LOG_ERROR, "We could NOT get the channel lock for %s! \n", p->owner->name);
11409          ast_log(LOG_ERROR, "SIP MESSAGE JUST IGNORED: %s \n", req.data);
11410          ast_log(LOG_ERROR, "BAD! BAD! BAD!\n");
11411          return 1;
11412       }
11413       memcpy(&p->recv, &sin, sizeof(p->recv));
11414       if (recordhistory) {
11415          char tmp[80];
11416          /* This is a response, note what it was for */
11417          snprintf(tmp, sizeof(tmp), "%s / %s /%s", req.data, get_header(&req, "CSeq"), req.rlPart2);
11418          append_history(p, "Rx", tmp);
11419       }
11420       nounlock = 0;
11421       if (handle_request(p, &req, &sin, &recount, &nounlock) == -1) {
11422          /* Request failed */
11423          ast_log(LOG_DEBUG, "SIP message could not be handled, bad request: %-70.70s\n", p->callid[0] ? p->callid : "<no callid>");
11424       }
11425       
11426       if (p->owner && !nounlock)
11427          ast_mutex_unlock(&p->owner->lock);
11428       ast_mutex_unlock(&p->lock);
11429    }
11430    ast_mutex_unlock(&netlock);
11431    if (recount)
11432       ast_update_use_count();
11433 
11434    return 1;
11435 }

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

subscription_type2str: Show subscription type in string format

Definition at line 8418 of file chan_sip.c.

References subscription_types, and type.

Referenced by __sip_show_channels(), and sip_show_channel().

08418                                                                         {
08419    int i;
08420 
08421    for (i = 1; (i < (sizeof(subscription_types) / sizeof(subscription_types[0]))); i++) {
08422       if (subscription_types[i].type == subtype) {
08423          return subscription_types[i].text;
08424       }
08425    }
08426    return subscription_types[0].text;
08427 }

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

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

Definition at line 12259 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_flags, global_musicclass, global_rtpholdtimeout, global_rtpkeepalive, global_rtptimeout, malloc, prefs, reg_source_db(), SIP_FLAGS_TO_COPY, SIP_PAGE2_DYNAMIC, and SIP_SELFDESTRUCT.

Referenced by register_verify().

12260 {
12261    struct sip_peer *peer;
12262 
12263    peer = malloc(sizeof(*peer));
12264    if (!peer)
12265       return NULL;
12266 
12267    memset(peer, 0, sizeof(*peer));
12268    apeerobjs++;
12269    ASTOBJ_INIT(peer);
12270 
12271    peer->expire = -1;
12272    peer->pokeexpire = -1;
12273    ast_copy_string(peer->name, name, sizeof(peer->name));
12274    ast_copy_flags(peer, &global_flags, SIP_FLAGS_TO_COPY);
12275    strcpy(peer->context, default_context);
12276    strcpy(peer->subscribecontext, default_subscribecontext);
12277    strcpy(peer->language, default_language);
12278    strcpy(peer->musicclass, global_musicclass);
12279    peer->addr.sin_port = htons(DEFAULT_SIP_PORT);
12280    peer->addr.sin_family = AF_INET;
12281    peer->capability = global_capability;
12282    peer->rtptimeout = global_rtptimeout;
12283    peer->rtpholdtimeout = global_rtpholdtimeout;
12284    peer->rtpkeepalive = global_rtpkeepalive;
12285    ast_set_flag(peer, SIP_SELFDESTRUCT);
12286    ast_set_flag(&peer->flags_page2, SIP_PAGE2_DYNAMIC);
12287    peer->prefs = prefs;
12288    reg_source_db(peer);
12289 
12290    return peer;
12291 }

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 974 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(), transmit_register(), and transmit_response_using_temp().

00975 {
00976    int val;
00977 
00978    ast_mutex_lock(&rand_lock);
00979    val = rand();
00980    ast_mutex_unlock(&rand_lock);
00981    
00982    return val;
00983 }

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 6500 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().

06501 {
06502    snprintf(randdata, randlen, "%08x", thread_safe_rand());
06503    transmit_response_with_auth(p, "401 Unauthorized", req, randdata, reliable, "WWW-Authenticate", 0);
06504 }

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

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

Referenced by sip_senddigit().

05706 {
05707    struct sip_request req;
05708    reqprep(&req, p, SIP_INFO, 0, 1);
05709    add_digit(&req, digit);
05710    return send_request(p, &req, 1, p->ocseq);
05711 }

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

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

Referenced by sip_indicate().

05715 {
05716    struct sip_request req;
05717    reqprep(&req, p, SIP_INFO, 0, 1);
05718    add_vidupdate(&req);
05719    return send_request(p, &req, 1, p->ocseq);
05720 }

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 5005 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().

05006 {
05007    struct sip_request req;
05008    
05009    req.method = sipmethod;
05010    if (init) {
05011       /* Bump branch even on initial requests */
05012       p->branch ^= thread_safe_rand();
05013       build_via(p, p->via, sizeof(p->via));
05014       if (init > 1)
05015          initreqprep(&req, p, sipmethod);
05016       else
05017          reqprep(&req, p, sipmethod, 0, 1);
05018    } else
05019       reqprep(&req, p, sipmethod, 0, 1);
05020       
05021    if (p->options && p->options->auth)
05022       add_header(&req, p->options->authheader, p->options->auth);
05023    append_date(&req);
05024    if (sipmethod == SIP_REFER) { /* Call transfer */
05025       if (!ast_strlen_zero(p->refer_to))
05026          add_header(&req, "Refer-To", p->refer_to);
05027       if (!ast_strlen_zero(p->referred_by))
05028          add_header(&req, "Referred-By", p->referred_by);
05029    }
05030 #ifdef OSP_SUPPORT
05031    if ((req.method != SIP_OPTIONS) && p->options && !ast_strlen_zero(p->options->osptoken)) {
05032       ast_log(LOG_DEBUG,"Adding OSP Token: %s\n", p->options->osptoken);
05033       add_header(&req, "P-OSP-Auth-Token", p->options->osptoken);
05034    }
05035 #endif
05036    if (p->options && !ast_strlen_zero(p->options->distinctive_ring))
05037    {
05038       add_header(&req, "Alert-Info", p->options->distinctive_ring);
05039    }
05040    add_header(&req, "Allow", ALLOWED_METHODS);
05041    if (p->options && p->options->addsipheaders ) {
05042       struct ast_channel *ast;
05043       char *header = (char *) NULL;
05044       char *content = (char *) NULL;
05045       char *end = (char *) NULL;
05046       struct varshead *headp = (struct varshead *) NULL;
05047       struct ast_var_t *current;
05048 
05049       ast = p->owner;   /* The owner channel */
05050       if (ast) {
05051          char *headdup;
05052          headp = &ast->varshead;
05053          if (!headp)
05054             ast_log(LOG_WARNING,"No Headp for the channel...ooops!\n");
05055          else {
05056             AST_LIST_TRAVERSE(headp, current, entries) {  
05057                /* SIPADDHEADER: Add SIP header to outgoing call        */
05058                if (!strncasecmp(ast_var_name(current), "SIPADDHEADER", strlen("SIPADDHEADER"))) {
05059                   header = ast_var_value(current);
05060                   headdup = ast_strdupa(header);
05061                   /* Strip of the starting " (if it's there) */
05062                   if (*headdup == '"')
05063                      headdup++;
05064                   if ((content = strchr(headdup, ':'))) {
05065                      *content = '\0';
05066                      content++;  /* Move pointer ahead */
05067                      /* Skip white space */
05068                      while (*content == ' ')
05069                         content++;
05070                      /* Strip the ending " (if it's there) */
05071                      end = content + strlen(content) -1; 
05072                      if (*end == '"')
05073                         *end = '\0';
05074                   
05075                      add_header(&req, headdup, content);
05076                      if (sipdebug)
05077                         ast_log(LOG_DEBUG, "Adding SIP Header \"%s\" with content :%s: \n", headdup, content);
05078                   }
05079                }
05080             }
05081          }
05082       }
05083    }
05084    if (sdp && p->rtp) {
05085       ast_rtp_offered_from_local(p->rtp, 1);
05086       add_sdp(&req, p);
05087    } else {
05088       add_header_contentLength(&req, 0);
05089       add_blank_header(&req);
05090    }
05091 
05092    if (!p->initreq.headers) {
05093       /* Use this as the basis */
05094       copy_request(&p->initreq, &req);
05095       parse_request(&p->initreq);
05096       if (sip_debug_test_pvt(p))
05097          ast_verbose("%d headers, %d lines\n", p->initreq.headers, p->initreq.lines);
05098    }
05099    p->lastinvite = p->ocseq;
05100    return send_request(p, &req, init ? 2 : 1, p->ocseq);
05101 }

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

References add_text(), sip_pvt::ocseq, reqprep(), send_request(), and SIP_MESSAGE.

Referenced by sip_sendtext().

05652 {
05653    struct sip_request req;
05654    reqprep(&req, p, SIP_MESSAGE, 0, 1);
05655    add_text(&req, text);
05656    return send_request(p, &req, 1, p->ocseq);
05657 }

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 5276 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().

05277 {
05278    struct sip_request req;
05279    char tmp[500];
05280    char *t = tmp;
05281    size_t maxbytes = sizeof(tmp);
05282    char iabuf[INET_ADDRSTRLEN];
05283 
05284    initreqprep(&req, p, SIP_NOTIFY);
05285    add_header(&req, "Event", "message-summary");
05286    add_header(&req, "Content-Type", default_notifymime);
05287 
05288    ast_build_string(&t, &maxbytes, "Messages-Waiting: %s\r\n", newmsgs ? "yes" : "no");
05289    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);
05290    ast_build_string(&t, &maxbytes, "Voice-Message: %d/%d (0/0)\r\n", newmsgs, oldmsgs);
05291 
05292    if (t > tmp + sizeof(tmp))
05293       ast_log(LOG_WARNING, "Buffer overflow detected!!  (Please file a bug report)\n");
05294 
05295    add_header_contentLength(&req, strlen(tmp));
05296    add_line(&req, tmp);
05297 
05298    if (!p->initreq.headers) { /* Use this as the basis */
05299       copy_request(&p->initreq, &req);
05300       parse_request(&p->initreq);
05301       if (sip_debug_test_pvt(p))
05302          ast_verbose("%d headers, %d lines\n", p->initreq.headers, p->initreq.lines);
05303       determine_firstline_parts(&p->initreq);
05304    }
05305 
05306    return send_request(p, &req, 1, p->ocseq);
05307 }

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 5329 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().

05330 {
05331    struct sip_request req;
05332    char tmp[20];
05333    reqprep(&req, p, SIP_NOTIFY, 0, 1);
05334    snprintf(tmp, sizeof(tmp), "refer;id=%d", cseq);
05335    add_header(&req, "Event", tmp);
05336    add_header(&req, "Subscription-state", "terminated;reason=noresource");
05337    add_header(&req, "Content-Type", "message/sipfrag;version=2.0");
05338 
05339    strcpy(tmp, "SIP/2.0 200 OK");
05340    add_header_contentLength(&req, strlen(tmp));
05341    add_line(&req, tmp);
05342 
05343    if (!p->initreq.headers) {
05344       /* Use this as the basis */
05345       copy_request(&p->initreq, &req);
05346       parse_request(&p->initreq);
05347       if (sip_debug_test_pvt(p))
05348          ast_verbose("%d headers, %d lines\n", p->initreq.headers, p->initreq.lines);
05349       determine_firstline_parts(&p->initreq);
05350    }
05351 
05352    return send_request(p, &req, 1, p->ocseq);
05353 }

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

transmit_refer: Transmit SIP REFER message ---

Definition at line 5660 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().

05661 {
05662    struct sip_request req;
05663    char from[256];
05664    char *of, *c;
05665    char referto[256];
05666 
05667    if (ast_test_flag(p, SIP_OUTGOING)) 
05668       of = get_header(&p->initreq, "To");
05669    else
05670       of = get_header(&p->initreq, "From");
05671    ast_copy_string(from, of, sizeof(from));
05672    of = get_in_brackets(from);
05673    ast_copy_string(p->from,of,sizeof(p->from));
05674    if (strncmp(of, "sip:", 4)) {
05675       ast_log(LOG_NOTICE, "From address missing 'sip:', using it anyway\n");
05676    } else
05677       of += 4;
05678    /* Get just the username part */
05679    if ((c = strchr(dest, '@'))) {
05680       c = NULL;
05681    } else if ((c = strchr(of, '@'))) {
05682       *c = '\0';
05683       c++;
05684    }
05685    if (c) {
05686       snprintf(referto, sizeof(referto), "<sip:%s@%s>", dest, c);
05687    } else {
05688       snprintf(referto, sizeof(referto), "<sip:%s>", dest);
05689    }
05690 
05691    /* save in case we get 407 challenge */
05692    ast_copy_string(p->refer_to, referto, sizeof(p->refer_to));
05693    ast_copy_string(p->referred_by, p->our_contact, sizeof(p->referred_by));
05694 
05695    reqprep(&req, p, SIP_REFER, 0, 1);
05696    add_header(&req, "Refer-To", referto);
05697    if (!ast_strlen_zero(p->our_contact))
05698       add_header(&req, "Referred-By", p->our_contact);
05699    add_blank_header(&req);
05700    return send_request(p, &req, 1, p->ocseq);
05701 }

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 5459 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, bindaddr, 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().

05460 {
05461    struct sip_request req;
05462    char from[256];
05463    char to[256];
05464    char tmp[80];
05465    char via[80];
05466    char addr[80];
05467    struct sip_pvt *p;
05468 
05469    /* exit if we are already in process with this registrar ?*/
05470    if ( r == NULL || ((auth==NULL) && (r->regstate==REG_STATE_REGSENT || r->regstate==REG_STATE_AUTHSENT))) {
05471       ast_log(LOG_NOTICE, "Strange, trying to register %s@%s when registration already pending\n", r->username, r->hostname);
05472       return 0;
05473    }
05474 
05475    if (r->call) { /* We have a registration */
05476       if (!auth) {
05477          ast_log(LOG_WARNING, "Already have a REGISTER going on to %s@%s?? \n", r->username, r->hostname);
05478          return 0;
05479       } else {
05480          p = r->call;
05481          make_our_tag(p->tag, sizeof(p->tag));  /* create a new local tag for every register attempt */
05482          p->theirtag[0]='\0'; /* forget their old tag, so we don't match tags when getting response */
05483       }
05484    } else {
05485       /* Build callid for registration if we haven't registered before */
05486       if (!r->callid_valid) {
05487          build_callid(r->callid, sizeof(r->callid), __ourip, default_fromdomain);
05488          r->callid_valid = 1;
05489       }
05490       /* Allocate SIP packet for registration */
05491       p=sip_alloc( r->callid, NULL, 0, SIP_REGISTER);
05492       if (!p) {
05493          ast_log(LOG_WARNING, "Unable to allocate registration call\n");
05494          return 0;
05495       }
05496       if (recordhistory) {
05497          char tmp[80];
05498          snprintf(tmp, sizeof(tmp), "Account: %s@%s", r->username, r->hostname);
05499          append_history(p, "RegistryInit", tmp);
05500       }
05501       /* Find address to hostname */
05502       if (create_addr(p, r->hostname)) {
05503          /* we have what we hope is a temporary network error,
05504           * probably DNS.  We need to reschedule a registration try */
05505          sip_destroy(p);
05506          if (r->timeout > -1) {
05507             ast_sched_del(sched, r->timeout);
05508             r->timeout = ast_sched_add(sched, global_reg_timeout*1000, sip_reg_timeout, r);
05509             ast_log(LOG_WARNING, "Still have a registration timeout for %s@%s (create_addr() error), %d\n", r->username, r->hostname, r->timeout);
05510          } else {
05511             r->timeout = ast_sched_add(sched, global_reg_timeout*1000, sip_reg_timeout, r);
05512             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);
05513          }
05514          r->regattempts++;
05515          return 0;
05516       }
05517       /* Copy back Call-ID in case create_addr changed it */
05518       ast_copy_string(r->callid, p->callid, sizeof(r->callid));
05519       if (r->portno)
05520          p->sa.sin_port = htons(r->portno);
05521       else  /* Set registry port to the port set from the peer definition/srv or default */
05522          r->portno = ntohs(p->sa.sin_port);
05523       ast_set_flag(p, SIP_OUTGOING);   /* Registration is outgoing call */
05524       r->call=p;        /* Save pointer to SIP packet */
05525       p->registry=ASTOBJ_REF(r); /* Add pointer to registry in packet */
05526       if (!ast_strlen_zero(r->secret)) /* Secret (password) */
05527          ast_copy_string(p->peersecret, r->secret, sizeof(p->peersecret));
05528       if (!ast_strlen_zero(r->md5secret))
05529          ast_copy_string(p->peermd5secret, r->md5secret, sizeof(p->peermd5secret));
05530       /* User name in this realm  
05531       - if authuser is set, use that, otherwise use username */
05532       if (!ast_strlen_zero(r->authuser)) {   
05533          ast_copy_string(p->peername, r->authuser, sizeof(p->peername));
05534          ast_copy_string(p->authname, r->authuser, sizeof(p->authname));
05535       } else {
05536          if (!ast_strlen_zero(r->username)) {
05537             ast_copy_string(p->peername, r->username, sizeof(p->peername));
05538             ast_copy_string(p->authname, r->username, sizeof(p->authname));
05539             ast_copy_string(p->fromuser, r->username, sizeof(p->fromuser));
05540          }
05541       }
05542       if (!ast_strlen_zero(r->username))
05543          ast_copy_string(p->username, r->username, sizeof(p->username));
05544       /* Save extension in packet */
05545       ast_copy_string(p->exten, r->contact, sizeof(p->exten));
05546 
05547       /*
05548         check which address we should use in our contact header 
05549         based on whether the remote host is on the external or
05550         internal network so we can register through nat
05551        */
05552       if (ast_sip_ouraddrfor(&p->sa.sin_addr, &p->ourip))
05553          memcpy(&p->ourip, &bindaddr.sin_addr, sizeof(p->ourip));
05554       build_contact(p);
05555    }
05556 
05557    /* set up a timeout */
05558    if (auth == NULL)  {
05559       if (r->timeout > -1) {
05560          ast_log(LOG_WARNING, "Still have a registration timeout, #%d - deleting it\n", r->timeout);
05561          ast_sched_del(sched, r->timeout);
05562       }
05563       r->timeout = ast_sched_add(sched, global_reg_timeout * 1000, sip_reg_timeout, r);
05564       ast_log(LOG_DEBUG, "Scheduled a registration timeout for %s id  #%d \n", r->hostname, r->timeout);
05565    }
05566 
05567    if (strchr(r->username, '@')) {
05568       snprintf(from, sizeof(from), "<sip:%s>;tag=%s", r->username, p->tag);
05569       if (!ast_strlen_zero(p->theirtag))
05570          snprintf(to, sizeof(to), "<sip:%s>;tag=%s", r->username, p->theirtag);
05571       else
05572          snprintf(to, sizeof(to), "<sip:%s>", r->username);
05573    } else {
05574       snprintf(from, sizeof(from), "<sip:%s@%s>;tag=%s", r->username, p->tohost, p->tag);
05575       if (!ast_strlen_zero(p->theirtag))
05576          snprintf(to, sizeof(to), "<sip:%s@%s>;tag=%s", r->username, p->tohost, p->theirtag);
05577       else
05578          snprintf(to, sizeof(to), "<sip:%s@%s>", r->username, p->tohost);
05579    }
05580    
05581    /* Fromdomain is what we are registering to, regardless of actual
05582       host name from SRV */
05583    if (!ast_strlen_zero(p->fromdomain))
05584       snprintf(addr, sizeof(addr), "sip:%s", p->fromdomain);
05585    else
05586       snprintf(addr, sizeof(addr), "sip:%s", r->hostname);
05587    ast_copy_string(p->uri, addr, sizeof(p->uri));
05588 
05589    p->branch ^= thread_safe_rand();
05590 
05591    memset(&req, 0, sizeof(req));
05592    init_req(&req, sipmethod, addr);
05593 
05594    /* Add to CSEQ */
05595    snprintf(tmp, sizeof(tmp), "%u %s", ++r->ocseq, sip_methods[sipmethod].text);
05596    p->ocseq = r->ocseq;
05597 
05598    build_via(p, via, sizeof(via));
05599    add_header(&req, "Via", via);
05600    add_header(&req, "From", from);
05601    add_header(&req, "To", to);
05602    add_header(&req, "Call-ID", p->callid);
05603    add_header(&req, "CSeq", tmp);
05604    add_header(&req, "User-Agent", default_useragent);
05605    add_header(&req, "Max-Forwards", DEFAULT_MAX_FORWARDS);
05606 
05607    
05608    if (auth)   /* Add auth header */
05609       add_header(&req, authheader, auth);
05610    else if (!ast_strlen_zero(r->nonce)) {
05611       char digest[1024];
05612 
05613       /* We have auth data to reuse, build a digest header! */
05614       if (sipdebug)
05615          ast_log(LOG_DEBUG, "   >>> Re-using Auth data for %s@%s\n", r->username, r->hostname);
05616       ast_copy_string(p->realm, r->realm, sizeof(p->realm));
05617       ast_copy_string(p->nonce, r->nonce, sizeof(p->nonce));
05618       ast_copy_string(p->domain, r->domain, sizeof(p->domain));
05619       ast_copy_string(p->opaque, r->opaque, sizeof(p->opaque));
05620       ast_copy_string(p->qop, r->qop, sizeof(p->qop));
05621       p->noncecount = r->noncecount++;
05622 
05623       memset(digest,0,sizeof(digest));
05624       if(!build_reply_digest(p, sipmethod, digest, sizeof(digest)))
05625          add_header(&req, "Authorization", digest);
05626       else
05627          ast_log(LOG_NOTICE, "No authorization available for authentication of registration to %s@%s\n", r->username, r->hostname);
05628    
05629    }
05630 
05631    snprintf(tmp, sizeof(tmp), "%d", default_expiry);
05632    add_header(&req, "Expires", tmp);
05633    add_header(&req, "Contact", p->our_contact);
05634    add_header(&req, "Event", "registration");
05635    add_header_contentLength(&req, 0);
05636    add_blank_header(&req);
05637    copy_request(&p->initreq, &req);
05638    parse_request(&p->initreq);
05639    if (sip_debug_test_pvt(p)) {
05640       ast_verbose("REGISTER %d headers, %d lines\n", p->initreq.headers, p->initreq.lines);
05641    }
05642    determine_firstline_parts(&p->initreq);
05643    r->regstate=auth?REG_STATE_AUTHSENT:REG_STATE_REGSENT;
05644    r->regattempts++; /* Another attempt */
05645    if (option_debug > 3)
05646       ast_verbose("REGISTER attempt %d to %s@%s\n", r->regattempts, r->username, r->hostname);
05647    return send_request(p, &req, 2, p->ocseq);
05648 }

static int transmit_reinvite_with_sdp struct sip_pvt p  )  [static]
 

transmit_reinvite_with_sdp: Transmit reinvite with SDP :-) ---

Definition at line 4732 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().

04733 {
04734    struct sip_request req;
04735    if (ast_test_flag(p, SIP_REINVITE_UPDATE))
04736       reqprep(&req, p, SIP_UPDATE, 0, 1);
04737    else 
04738       reqprep(&req, p, SIP_INVITE, 0, 1);
04739    
04740    add_header(&req, "Allow", ALLOWED_METHODS);
04741    if (sipdebug)
04742       add_header(&req, "X-asterisk-info", "SIP re-invite (RTP bridge)");
04743    ast_rtp_offered_from_local(p->rtp, 1);
04744    add_sdp(&req, p);
04745    /* Use this as the basis */
04746    copy_request(&p->initreq, &req);
04747    parse_request(&p->initreq);
04748    if (sip_debug_test_pvt(p))
04749       ast_verbose("%d headers, %d lines\n", p->initreq.headers, p->initreq.lines);
04750    p->lastinvite = p->ocseq;
04751    ast_set_flag(p, SIP_OUTGOING);
04752    return send_request(p, &req, 1, p->ocseq);
04753 }

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 5723 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().

05724 {
05725    struct sip_request resp;
05726    reqprep(&resp, p, sipmethod, seqno, newbranch);
05727    add_header_contentLength(&resp, 0);
05728    add_blank_header(&resp);
05729    return send_request(p, &resp, reliable, seqno ? seqno : p->ocseq);
05730 }

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 5733 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().

05734 {
05735    struct sip_request resp;
05736 
05737    reqprep(&resp, p, sipmethod, seqno, newbranch);
05738    if (*p->realm) {
05739       char digest[1024];
05740 
05741       memset(digest, 0, sizeof(digest));
05742       if(!build_reply_digest(p, sipmethod, digest, sizeof(digest))) {
05743          if (p->options && p->options->auth_type == PROXY_AUTH)
05744             add_header(&resp, "Proxy-Authorization", digest);
05745          else if (p->options && p->options->auth_type == WWW_AUTH)
05746             add_header(&resp, "Authorization", digest);
05747          else  /* Default, to be backwards compatible (maybe being too careful, but leaving it for now) */
05748             add_header(&resp, "Proxy-Authorization", digest);
05749       } else
05750          ast_log(LOG_WARNING, "No authentication available for call %s\n", p->callid);
05751    }
05752    /* If we are hanging up and know a cause for that, send it in clear text to make
05753       debugging easier. */
05754    if (sipmethod == SIP_BYE) {
05755       if (p->owner && p->owner->hangupcause) {
05756          add_header(&resp, "X-Asterisk-HangupCause", ast_cause2str(p->owner->hangupcause));
05757       }
05758    }
05759 
05760    add_header_contentLength(&resp, 0);
05761    add_blank_header(&resp);
05762    return send_request(p, &resp, reliable, seqno ? seqno : p->ocseq);   
05763 }

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

transmit_response: Transmit response, no retransmits

Definition at line 4292 of file chan_sip.c.

References __transmit_response().

04293 {
04294    return __transmit_response(p, msg, req, 0);
04295 }

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 4308 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().

04309 {
04310    return __transmit_response(p, msg, req, fatal ? 2 : 1);
04311 }

static int transmit_response_using_temp char *  callid,
struct sockaddr_in *  sin,
int  useglobal_nat,
const int  intended_method,
struct sip_request req,
char *  msg
[static]
 

transmit_response_using_temp: Transmit response, no retransmits, using temporary pvt

Definition at line 4260 of file chan_sip.c.

References __ourip, __transmit_response(), ast_copy_flags, ast_sip_ouraddrfor(), build_via(), default_fromdomain, global_flags, make_our_tag(), SIP_NAT, and thread_safe_rand().

Referenced by find_call().

04261 {
04262    struct sip_pvt *p = alloca(sizeof(*p));
04263 
04264    memset(p, 0, sizeof(*p));
04265 
04266    p->method = intended_method;
04267    if (sin) {
04268       p->sa = *sin;
04269       if (ast_sip_ouraddrfor(&p->sa.sin_addr, &p->ourip))
04270          p->ourip = __ourip;
04271    } else
04272       p->ourip = __ourip;
04273    p->branch = thread_safe_rand();
04274    make_our_tag(p->tag, sizeof(p->tag));
04275    p->ocseq = 101;
04276 
04277    if (useglobal_nat && sin) {
04278       ast_copy_flags(p, &global_flags, SIP_NAT);
04279       memcpy(&p->recv, sin, sizeof(p->recv));
04280    }
04281 
04282    ast_copy_string(p->fromdomain, default_fromdomain, sizeof(p->fromdomain));
04283    build_via(p, p->via, sizeof(p->via));
04284    ast_copy_string(p->callid, callid, sizeof(p->callid));
04285 
04286    __transmit_response(p, msg, req, 0);
04287 
04288    return 0;
04289 }

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 4338 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().

04339 {
04340    struct sip_request resp;
04341    respprep(&resp, p, msg, req);
04342    add_header(&resp, "Accept", "application/sdp");
04343    add_header_contentLength(&resp, 0);
04344    add_blank_header(&resp);
04345    return send_response(p, &resp, reliable, 0);
04346 }

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 4349 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().

04350 {
04351    struct sip_request resp;
04352    char tmp[512];
04353    int seqno = 0;
04354 
04355    if (reliable && (sscanf(get_header(req, "CSeq"), "%d ", &seqno) != 1)) {
04356       ast_log(LOG_WARNING, "Unable to determine sequence number from '%s'\n", get_header(req, "CSeq"));
04357       return -1;
04358    }
04359    /* Stale means that they sent us correct authentication, but 
04360       based it on an old challenge (nonce) */
04361    snprintf(tmp, sizeof(tmp), "Digest algorithm=MD5, realm=\"%s\", nonce=\"%s\"%s", global_realm, randdata, stale ? ", stale=true" : "");
04362    respprep(&resp, p, msg, req);
04363    add_header(&resp, header, tmp);
04364    add_header_contentLength(&resp, 0);
04365    add_blank_header(&resp);
04366    return send_response(p, &resp, reliable, seqno);
04367 }

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

References add_blank_header(), add_header_contentLength(), append_date(), respprep(), and send_response().

Referenced by register_verify().

04328 {
04329    struct sip_request resp;
04330    respprep(&resp, p, msg, req);
04331    append_date(&resp);
04332    add_header_contentLength(&resp, 0);
04333    add_blank_header(&resp);
04334    return send_response(p, &resp, 0, 0);
04335 }

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 4658 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().

04659 {
04660    struct sip_request resp;
04661    int seqno;
04662    if (sscanf(get_header(req, "CSeq"), "%d ", &seqno) != 1) {
04663       ast_log(LOG_WARNING, "Unable to get seqno from '%s'\n", get_header(req, "CSeq"));
04664       return -1;
04665    }
04666    respprep(&resp, p, msg, req);
04667    if (p->rtp) {
04668       ast_rtp_offered_from_local(p->rtp, 0);
04669       try_suggested_sip_codec(p);   
04670       add_sdp(&resp, p);
04671    } else {
04672       ast_log(LOG_ERROR, "Can't add SDP to response, since we have no RTP session allocated. Call-ID %s\n", p->callid);
04673    }
04674    return send_response(p, &resp, retrans, seqno);
04675 }

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

References add_header(), append_date(), respprep(), and send_response().

Referenced by handle_request_invite().

04299 {
04300    struct sip_request resp;
04301    respprep(&resp, p, msg, req);
04302    append_date(&resp);
04303    add_header(&resp, "Unsupported", unsupported);
04304    return send_response(p, &resp, 0, 0);
04305 }

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

transmit_sip_request: Transmit SIP request

Definition at line 5310 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().

05311 {
05312    if (!p->initreq.headers) {
05313       /* Use this as the basis */
05314       copy_request(&p->initreq, req);
05315       parse_request(&p->initreq);
05316       if (sip_debug_test_pvt(p))
05317          ast_verbose("%d headers, %d lines\n", p->initreq.headers, p->initreq.lines);
05318       determine_firstline_parts(&p->initreq);
05319    }
05320 
05321    return send_request(p, req, 0, p->ocseq);
05322 }

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 5104 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, sip_pvt::expiry, sip_pvt::exten, find_subscription_type(), get_header(), get_in_brackets(), global_notifyringing, sip_pvt::initreq, LOG_WARNING, 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().

05105 {
05106    char tmp[4000], from[256], to[256];
05107    char *t = tmp, *c, *a, *mfrom, *mto;
05108    size_t maxbytes = sizeof(tmp);
05109    struct sip_request req;
05110    char hint[AST_MAX_EXTENSION];
05111    char *statestring = "terminated";
05112    const struct cfsubscription_types *subscriptiontype;
05113    enum state { NOTIFY_OPEN, NOTIFY_INUSE, NOTIFY_CLOSED } local_state = NOTIFY_OPEN;
05114    char *pidfstate = "--";
05115    char *pidfnote= "Ready";
05116 
05117    memset(from, 0, sizeof(from));
05118    memset(to, 0, sizeof(to));
05119    memset(tmp, 0, sizeof(tmp));
05120 
05121    switch (state) {
05122    case (AST_EXTENSION_RINGING | AST_EXTENSION_INUSE):
05123       if (global_notifyringing)
05124          statestring = "early";
05125       else
05126          statestring = "confirmed";
05127       local_state = NOTIFY_INUSE;
05128       pidfstate = "busy";
05129       pidfnote = "Ringing";
05130       break;
05131    case AST_EXTENSION_RINGING:
05132       statestring = "early";
05133       local_state = NOTIFY_INUSE;
05134       pidfstate = "busy";
05135       pidfnote = "Ringing";
05136       break;
05137    case AST_EXTENSION_INUSE:
05138       statestring = "confirmed";
05139       local_state = NOTIFY_INUSE;
05140       pidfstate = "busy";
05141       pidfnote = "On the phone";
05142       break;
05143    case AST_EXTENSION_BUSY:
05144       statestring = "confirmed";
05145       local_state = NOTIFY_CLOSED;
05146       pidfstate = "busy";
05147       pidfnote = "On the phone";
05148       break;
05149    case AST_EXTENSION_UNAVAILABLE:
05150       statestring = "confirmed";
05151       local_state = NOTIFY_CLOSED;
05152       pidfstate = "away";
05153       pidfnote = "Unavailable";
05154       break;
05155    case AST_EXTENSION_NOT_INUSE:
05156    default:
05157       /* Default setting */
05158       break;
05159    }
05160 
05161    subscriptiontype = find_subscription_type(p->subscribed);
05162    
05163    /* Check which device/devices we are watching  and if they are registered */
05164    if (ast_get_hint(hint, sizeof(hint), NULL, 0, NULL, p->context, p->exten)) {
05165       /* If they are not registered, we will override notification and show no availability */
05166       if (ast_device_state(hint) == AST_DEVICE_UNAVAILABLE) {
05167          local_state = NOTIFY_CLOSED;
05168          pidfstate = "away";
05169          pidfnote = "Not online";
05170       }
05171    }
05172 
05173    ast_copy_string(from, get_header(&p->initreq, "From"), sizeof(from));
05174    c = get_in_brackets(from);
05175    if (strncmp(c, "sip:", 4)) {
05176       ast_log(LOG_WARNING, "Huh?  Not a SIP header (%s)?\n", c);
05177       return -1;
05178    }
05179    if ((a = strchr(c, ';')))
05180       *a = '\0';
05181    mfrom = c;
05182 
05183    ast_copy_string(to, get_header(&p->initreq, "To"), sizeof(to));
05184    c = get_in_brackets(to);
05185    if (strncmp(c, "sip:", 4)) {
05186       ast_log(LOG_WARNING, "Huh?  Not a SIP header (%s)?\n", c);
05187       return -1;
05188    }
05189    if ((a = strchr(c, ';')))
05190       *a = '\0';
05191    mto = c;
05192 
05193    reqprep(&req, p, SIP_NOTIFY, 0, 1);
05194 
05195    
05196    add_header(&req, "Event", subscriptiontype->event);
05197    add_header(&req, "Content-Type", subscriptiontype->mediatype);
05198    switch(state) {
05199    case AST_EXTENSION_DEACTIVATED:
05200       if (p->subscribed == TIMEOUT)
05201          add_header(&req, "Subscription-State", "terminated;reason=timeout");
05202       else {
05203          add_header(&req, "Subscription-State", "terminated;reason=probation");
05204          add_header(&req, "Retry-After", "60");
05205       }
05206       break;
05207    case AST_EXTENSION_REMOVED:
05208       add_header(&req, "Subscription-State", "terminated;reason=noresource");
05209       break;
05210       break;
05211    default:
05212       if (p->expiry)
05213          add_header(&req, "Subscription-State", "active");
05214       else  /* Expired */
05215          add_header(&req, "Subscription-State", "terminated;reason=timeout");
05216    }
05217    switch (p->subscribed) {
05218    case XPIDF_XML:
05219    case CPIM_PIDF_XML:
05220       ast_build_string(&t, &maxbytes, "<?xml version=\"1.0\"?>\n");
05221       ast_build_string(&t, &maxbytes, "<!DOCTYPE presence PUBLIC \"-//IETF//DTD RFCxxxx XPIDF 1.0//EN\" \"xpidf.dtd\">\n");
05222       ast_build_string(&t, &maxbytes, "<presence>\n");
05223       ast_build_string(&t, &maxbytes, "<presentity uri=\"%s;method=SUBSCRIBE\" />\n", mfrom);
05224       ast_build_string(&t, &maxbytes, "<atom id=\"%s\">\n", p->exten);
05225       ast_build_string(&t, &maxbytes, "<address uri=\"%s;user=ip\" priority=\"0.800000\">\n", mto);
05226       ast_build_string(&t, &maxbytes, "<status status=\"%s\" />\n", (local_state ==  NOTIFY_OPEN) ? "open" : (local_state == NOTIFY_INUSE) ? "inuse" : "closed");
05227       ast_build_string(&t, &maxbytes, "<msnsubstatus substatus=\"%s\" />\n", (local_state == NOTIFY_OPEN) ? "online" : (local_state == NOTIFY_INUSE) ? "onthephone" : "offline");
05228       ast_build_string(&t, &maxbytes, "</address>\n</atom>\n</presence>\n");
05229       break;
05230    case PIDF_XML: /* Eyebeam supports this format */
05231       ast_build_string(&t, &maxbytes, "<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>\n");
05232       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);
05233       ast_build_string(&t, &maxbytes, "<pp:person><status>\n");
05234       if (pidfstate[0] != '-')
05235          ast_build_string(&t, &maxbytes, "<ep:activities><ep:%s/></ep:activities>\n", pidfstate);
05236       ast_build_string(&t, &maxbytes, "</status></pp:person>\n");
05237       ast_build_string(&t, &maxbytes, "<note>%s</note>\n", pidfnote); /* Note */
05238       ast_build_string(&t, &maxbytes, "<tuple id=\"%s\">\n", p->exten); /* Tuple start */
05239       ast_build_string(&t, &maxbytes, "<contact priority=\"1\">%s</contact>\n", mto);
05240       if (pidfstate[0] == 'b') /* Busy? Still open ... */
05241          ast_build_string(&t, &maxbytes, "<status><basic>open</basic></status>\n");
05242       else
05243          ast_build_string(&t, &maxbytes, "<status><basic>%s</basic></status>\n", (local_state != NOTIFY_CLOSED) ? "open" : "closed");
05244       ast_build_string(&t, &maxbytes, "</tuple>\n</presence>\n");
05245       break;
05246    case DIALOG_INFO_XML: /* SNOM subscribes in this format */
05247       ast_build_string(&t, &maxbytes, "<?xml version=\"1.0\"?>\n");
05248       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);
05249       if ((state & AST_EXTENSION_RINGING) && global_notifyringing)
05250          ast_build_string(&t, &maxbytes, "<dialog id=\"%s\" direction=\"recipient\">\n", p->exten);
05251       else
05252          ast_build_string(&t, &maxbytes, "<dialog id=\"%s\">\n", p->exten);
05253       ast_build_string(&t, &maxbytes, "<state>%s</state>\n", statestring);
05254       ast_build_string(&t, &maxbytes, "</dialog>\n</dialog-info>\n");
05255       break;
05256    case NONE:
05257    default:
05258       break;
05259    }
05260 
05261    if (t > tmp + sizeof(tmp))
05262       ast_log(LOG_WARNING, "Buffer overflow detected!!  (Please file a bug report)\n");
05263 
05264    add_header_contentLength(&req, strlen(tmp));
05265    add_line(&req, tmp);
05266 
05267    return send_request(p, &req, 1, p->ocseq);
05268 }

static void try_suggested_sip_codec struct sip_pvt p  )  [static]
 

Try setting codec suggested by the SIP_CODEC channel variable.

Definition at line 2519 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().

02520 {
02521    int fmt;
02522    char *codec;
02523 
02524    codec = pbx_builtin_getvar_helper(p->owner, "SIP_CODEC");
02525    if (!codec) 
02526       return;
02527 
02528    fmt = ast_getformatbyname(codec);
02529    if (fmt) {
02530       ast_log(LOG_NOTICE, "Changing codec to '%s' for this call because of ${SIP_CODEC) variable\n",codec);
02531       if (p->jointcapability & fmt) {
02532          p->jointcapability &= fmt;
02533          p->capability &= fmt;
02534       } else
02535          ast_log(LOG_NOTICE, "Ignoring ${SIP_CODEC} variable because it is not shared by both ends.\n");
02536    } else
02537       ast_log(LOG_NOTICE, "Ignoring ${SIP_CODEC} variable because of unrecognized/not configured codec (check allow/disallow in sip.conf): %s\n",codec);
02538    return;  
02539 }

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 13482 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, my_clis, sip_pvt::next, sip_pvt::owner, 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.

13483 {
13484    struct sip_pvt *p, *pl;
13485    
13486    /* First, take us out of the channel type list */
13487    ast_channel_unregister(&sip_tech);
13488 
13489    ast_custom_function_unregister(&sipchaninfo_function);
13490    ast_custom_function_unregister(&sippeer_function);
13491    ast_custom_function_unregister(&sip_header_function);
13492    ast_custom_function_unregister(&checksipdomain_function);
13493 
13494    ast_unregister_application(app_dtmfmode);
13495    ast_unregister_application(app_sipaddheader);
13496    ast_unregister_application(app_sipgetheader);
13497 
13498    ast_cli_unregister_multiple(my_clis, sizeof(my_clis) / sizeof(my_clis[0]));
13499 
13500    ast_rtp_proto_unregister(&sip_rtp);
13501 
13502    ast_manager_unregister("SIPpeers");
13503    ast_manager_unregister("SIPshowpeer");
13504 
13505    if (!ast_mutex_lock(&iflock)) {
13506       /* Hangup all interfaces if they have an owner */
13507       p = iflist;
13508       while (p) {
13509          if (p->owner)
13510             ast_softhangup(p->owner, AST_SOFTHANGUP_APPUNLOAD);
13511          p = p->next;
13512       }
13513       ast_mutex_unlock(&iflock);
13514    } else {
13515       ast_log(LOG_WARNING, "Unable to lock the interface list\n");
13516       return -1;
13517    }
13518 
13519    if (!ast_mutex_lock(&monlock)) {
13520       if (monitor_thread && (monitor_thread != AST_PTHREADT_STOP)) {
13521          pthread_cancel(monitor_thread);
13522          pthread_kill(monitor_thread, SIGURG);
13523          pthread_join(monitor_thread, NULL);
13524       }
13525       monitor_thread = AST_PTHREADT_STOP;
13526       ast_mutex_unlock(&monlock);
13527    } else {
13528       ast_log(LOG_WARNING, "Unable to lock the monitor\n");
13529       return -1;
13530    }
13531 
13532    if (!ast_mutex_lock(&iflock)) {
13533       /* Destroy all the interfaces and free their memory */
13534       p = iflist;
13535       while (p) {
13536          pl = p;
13537          p = p->next;
13538          /* Free associated memory */
13539          ast_mutex_destroy(&pl->lock);
13540          if (pl->chanvars) {
13541             ast_variables_destroy(pl->chanvars);
13542             pl->chanvars = NULL;
13543          }
13544          free(pl);
13545       }
13546       iflist = NULL;
13547       ast_mutex_unlock(&iflock);
13548    } else {
13549       ast_log(LOG_WARNING, "Unable to lock the interface list\n");
13550       return -1;
13551    }
13552 
13553    /* Free memory for local network address mask */
13554    ast_free_ha(localaddr);
13555 
13556    ASTOBJ_CONTAINER_DESTROYALL(&userl, sip_destroy_user);
13557    ASTOBJ_CONTAINER_DESTROY(&userl);
13558    ASTOBJ_CONTAINER_DESTROYALL(&peerl, sip_destroy_peer);
13559    ASTOBJ_CONTAINER_DESTROY(&peerl);
13560    ASTOBJ_CONTAINER_DESTROYALL(&regl, sip_registry_destroy);
13561    ASTOBJ_CONTAINER_DESTROY(&regl);
13562 
13563    clear_realm_authentication(authl);
13564    clear_sip_domains();
13565    close(sipsock);
13566    sched_context_destroy(sched);
13567       
13568    return 0;
13569 }

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 2208 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, and sip_pvt::username.

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

02209 {
02210    char name[256];
02211    int *inuse, *call_limit;
02212    int outgoing = ast_test_flag(fup, SIP_OUTGOING);
02213    struct sip_user *u = NULL;
02214    struct sip_peer *p = NULL;
02215 
02216    if (option_debug > 2)
02217       ast_log(LOG_DEBUG, "Updating call counter for %s call\n", outgoing ? "outgoing" : "incoming");
02218    /* Test if we need to check call limits, in order to avoid 
02219       realtime lookups if we do not need it */
02220    if (!ast_test_flag(fup, SIP_CALL_LIMIT))
02221       return 0;
02222 
02223    ast_copy_string(name, fup->username, sizeof(name));
02224 
02225    /* Check the list of users */
02226    u = find_user(name, 1);
02227    if (u) {
02228       inuse = &u->inUse;
02229       call_limit = &u->call_limit;
02230       p = NULL;
02231    } else {
02232       /* Try to find peer */
02233       if (!p)
02234          p = find_peer(fup->peername, NULL, 1);
02235       if (p) {
02236          inuse = &p->inUse;
02237          call_limit = &p->call_limit;
02238          ast_copy_string(name, fup->peername, sizeof(name));
02239       } else {
02240          if (option_debug > 1)
02241             ast_log(LOG_DEBUG, "%s is not a local user, no call limit\n", name);
02242          return 0;
02243       }
02244    }
02245    switch(event) {
02246       /* incoming and outgoing affects the inUse counter */
02247       case DEC_CALL_LIMIT:
02248          if ( *inuse > 0 ) {
02249                   if (ast_test_flag(fup,SIP_INC_COUNT))
02250                      (*inuse)--;
02251          } else {
02252             *inuse = 0;
02253          }
02254          if (option_debug > 1 || sipdebug) {
02255             ast_log(LOG_DEBUG, "Call %s %s '%s' removed from call limit %d\n", outgoing ? "to" : "from", u ? "user":"peer", name, *call_limit);
02256          }
02257          break;
02258       case INC_CALL_LIMIT:
02259          if (*call_limit > 0 ) {
02260             if (*inuse >= *call_limit) {
02261                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);
02262                if (u)
02263                   ASTOBJ_UNREF(u,sip_destroy_user);
02264                else
02265                   ASTOBJ_UNREF(p,sip_destroy_peer);
02266                return -1; 
02267             }
02268          }
02269          (*inuse)++;
02270                    ast_set_flag(fup,SIP_INC_COUNT);
02271          if (option_debug > 1 || sipdebug) {
02272             ast_log(LOG_DEBUG, "Call %s %s '%s' is %d out of %d\n", outgoing ? "to" : "from", u ? "user":"peer", name, *inuse, *call_limit);
02273          }
02274          break;
02275       default:
02276          ast_log(LOG_ERROR, "update_call_counter(%s, %d) called with no event!\n", name, event);
02277    }
02278    if (u)
02279       ASTOBJ_UNREF(u,sip_destroy_user);
02280    else
02281       ASTOBJ_UNREF(p,sip_destroy_peer);
02282    return 0;
02283 }

static void update_peer struct sip_peer p,
int  expiry
[static]
 

update_peer: Update peer data in database (if used) ---

Definition at line 1676 of file chan_sip.c.

References sip_peer::addr, ast_test_flag, sip_peer::flags_page2, sip_peer::fullcontact, global_flags_page2, realtime_update_peer(), SIP_PAGE2_RTCACHEFRIENDS, SIP_PAGE2_RTUPDATE, SIP_REALTIME, and sip_peer::username.

Referenced by register_verify().

01677 {
01678    int rtcachefriends = ast_test_flag(&(p->flags_page2), SIP_PAGE2_RTCACHEFRIENDS);
01679    if (ast_test_flag((&global_flags_page2), SIP_PAGE2_RTUPDATE) &&
01680       (ast_test_flag(p, SIP_REALTIME) || rtcachefriends)) {
01681       realtime_update_peer(p->name, &p->addr, p->username, rtcachefriends ? p->fullcontact : NULL, expiry);
01682    }
01683 }

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

References usecnt.

13572 {
13573    return usecnt;
13574 }


Variable Documentation

struct in_addr __ourip [static]
 

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

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

int apeerobjs = 0 [static]
 

Definition at line 382 of file chan_sip.c.

Referenced by sip_show_objects(), and temp_peer().

char* app_dtmfmode = "SIPDtmfMode" [static]
 

Definition at line 13048 of file chan_sip.c.

Referenced by load_module(), and unload_module().

char* app_sipaddheader = "SIPAddHeader" [static]
 

Definition at line 13050 of file chan_sip.c.

Referenced by load_module(), and unload_module().

char* app_sipgetheader = "SIPGetHeader" [static]
 

Definition at line 13062 of file chan_sip.c.

Referenced by load_module(), and unload_module().

struct sip_auth* authl [static]
 

Authentication list

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

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

struct sockaddr_in bindaddr = { 0, } [static]
 

Definition at line 876 of file chan_sip.c.

int callevents = 0 [static]
 

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

Referenced by load_module(), and unload_module().

int compactheaders = 0 [static]
 

send compact sip headers

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

struct sockaddr_in debugaddr [static]
 

Definition at line 421 of file chan_sip.c.

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

char default_callerid[AST_MAX_EXTENSION] = DEFAULT_CALLERID [static]
 

Definition at line 344 of file chan_sip.c.

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

char default_context[AST_MAX_CONTEXT] = DEFAULT_CONTEXT [static]
 

Definition at line 335 of file chan_sip.c.

int default_expiry = DEFAULT_DEFAULT_EXPIRY [static]
 

Definition at line 121 of file chan_sip.c.

Referenced by 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 346 of file chan_sip.c.

Referenced by reload_config(), sip_alloc(), sip_show_settings(), transmit_register(), and transmit_response_using_temp().

char default_language[MAX_LANGUAGE] = "" [static]
 

Definition at line 341 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 349 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 355 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 336 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 332 of file chan_sip.c.

Referenced by 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 13047 of file chan_sip.c.

Referenced by load_module().

char* descrip_sipaddheader [static]
 

Definition at line 13054 of file chan_sip.c.

Referenced by load_module().

char* descrip_sipgetheader [static]
 

Definition at line 13065 of file chan_sip.c.

Referenced by load_module().

int dumphistory = 0 [static]
 

Dump history to verbose before destroying SIP dialog

Definition at line 430 of file chan_sip.c.

Referenced by reload_config().

int expiry = DEFAULT_EXPIRY [static]
 

Definition at line 438 of file chan_sip.c.

Referenced by complete_dpreply(), parse_register_contact(), reg_source_db(), and reload_config().

time_t externexpire = 0 [static]
 

Definition at line 879 of file chan_sip.c.

Referenced by ast_sip_ouraddrfor(), and reload_config().

char externhost[MAXHOSTNAMELEN] = "" [static]
 

Definition at line 878 of file chan_sip.c.

Referenced by ast_sip_ouraddrfor(), and reload_config().

struct sockaddr_in externip [static]
 

Definition at line 877 of file chan_sip.c.

Referenced by ast_sip_ouraddrfor(), and reload_config().

int externrefresh = 10 [static]
 

Definition at line 880 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 385 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 353 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 411 of file chan_sip.c.

Referenced by build_peer(), build_user(), reload_config(), sip_alloc(), sip_request_call(), and temp_peer().

struct ast_flags global_flags = {0} [static]
 

global SIP_ flags

Definition at line 357 of file chan_sip.c.

Referenced by build_peer(), build_user(), check_user_full(), reload_config(), sip_alloc(), sip_show_settings(), temp_peer(), and transmit_response_using_temp().

struct ast_flags global_flags_page2 = {0} [static]
 

more global SIP_ flags

Definition at line 358 of file chan_sip.c.

Referenced by build_peer(), destroy_association(), realtime_peer(), realtime_user(), reload_config(), sip_show_settings(), and update_peer().

char global_musicclass[MAX_MUSICCLASS] = "" [static]
 

Global music on hold class

Definition at line 432 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 388 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 351 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 434 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 374 of file chan_sip.c.

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

int global_regattempts_max = 0 [static]
 

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

int global_rtpholdtimeout = 0 [static]
 

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

Referenced by build_peer(), reload_config(), sip_alloc(), and temp_peer().

int global_rtptimeout = 0 [static]
 

Definition at line 368 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 339 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 9313 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 441 of file chan_sip.c.

struct ast_ha* localaddr [static]
 

Definition at line 881 of file chan_sip.c.

Referenced by ast_sip_ouraddrfor(), reload_config(), and unload_module().

char mandescr_show_peer[] [static]
 

Definition at line 8020 of file chan_sip.c.

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

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

struct ast_cli_entry my_clis[] [static]
 

Definition at line 13393 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 9305 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 9309 of file chan_sip.c.

int noncodeccapability = AST_RTP_DTMF [static]
 

Definition at line 412 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 884 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 9245 of file chan_sip.c.

int ourport [static]
 

Definition at line 416 of file chan_sip.c.

struct sockaddr_in outboundproxyip [static]
 

Definition at line 415 of file chan_sip.c.

Referenced by reload_config().

int pedanticsipchecking = 0 [static]
 

Extra checking ? Default off

Definition at line 362 of file chan_sip.c.

Referenced by __get_header(), check_user_full(), find_call(), get_destination(), get_refer_info(), handle_request(), 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 450 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 9287 of file chan_sip.c.

int recordhistory = 0 [static]
 

Record SIP history. Off by default

Definition at line 429 of file chan_sip.c.

Referenced by do_register_auth(), reload_config(), sip_do_history(), sip_no_history(), sip_reregister(), sip_show_history(), sip_show_settings(), sipsock_read(), and transmit_register().

char regcontext[AST_MAX_CONTEXT] = "" [static]
 

Context for auto-extensions

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

Referenced by sip_register(), sip_send_all_registers(), and sip_show_objects().

int relaxdtmf = 0 [static]
 

Definition at line 366 of file chan_sip.c.

Referenced by reload_config(), and sip_show_settings().

int rpeerobjs = 0 [static]
 

Definition at line 381 of file chan_sip.c.

Referenced by build_peer(), and sip_show_objects().

int ruserobjs = 0 [static]
 

Definition at line 379 of file chan_sip.c.

Referenced by sip_show_objects().

struct sched_context* sched [static]
 

Definition at line 440 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 9269 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 9265 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 9240 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 9273 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 9260 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 9326 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 9282 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 9277 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 9292 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 9330 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 9322 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 9255 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 9250 of file chan_sip.c.

struct ast_custom_function sip_header_function [static]
 

Definition at line 9376 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(), 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 9318 of file chan_sip.c.

int sip_reloading = 0 [static]
 

Definition at line 808 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 13298 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 937 of file chan_sip.c.

Referenced by load_module(), sip_new(), and unload_module().

struct ast_custom_function sipchaninfo_function [static]
 

Definition at line 9561 of file chan_sip.c.

Referenced by load_module(), and unload_module().

int sipdebug = 0 [static]
 

Definition at line 420 of file chan_sip.c.

Referenced by add_sip_domain(), build_reply_digest(), check_auth(), handle_request_info(), handle_request_invite(), handle_request_subscribe(), parse_request(), reload_config(), sip_addheader(), sip_do_debug(), sip_do_debug_ip(), sip_do_debug_peer(), sip_no_debug(), sip_poke_peer(), sip_reregister(), transmit_invite(), transmit_register(), and transmit_reinvite_with_sdp().

struct ast_custom_function sippeer_function
 

Definition at line 9484 of file chan_sip.c.

Referenced by load_module(), and unload_module().

int sipsock = -1 [static]
 

Definition at line 873 of file chan_sip.c.

Referenced by __sip_xmit(), do_monitor(), reg_source_db(), reload_config(), sipsock_read(), and unload_module().

int* sipsock_read_id [static]
 

Definition at line 442 of file chan_sip.c.

Referenced by do_monitor().

int speerobjs = 0 [static]
 

Definition at line 380 of file chan_sip.c.

Referenced by build_peer(), and sip_show_objects().

int srvlookup = 0 [static]
 

SRV Lookup on or off. Default is off, RFC behavior is on

Definition at line 360 of file chan_sip.c.

Referenced by build_peer(), 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 378 of file chan_sip.c.

Referenced by build_user(), and sip_show_objects().

char* synopsis_dtmfmode = "Change the dtmfmode for a SIP call" [static]
 

Definition at line 13046 of file chan_sip.c.

Referenced by load_module().

char* synopsis_sipaddheader = "Add a SIP header to the outbound call" [static]
 

Definition at line 13051 of file chan_sip.c.

Referenced by load_module().

char* synopsis_sipgetheader = "Get a SIP header from an incoming call" [static]
 

Definition at line 13063 of file chan_sip.c.

Referenced by load_module().

int tos = 0 [static]
 

Definition at line 423 of file chan_sip.c.

int usecnt = 0 [static]
 

Definition at line 390 of file chan_sip.c.

struct ast_user_list userl [static]
 

The user list: Users and friends ---.

int videosupport = 0 [static]
 

Definition at line 425 of file chan_sip.c.

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


Generated on Sat Nov 25 00:45:59 2006 for Asterisk - the Open Source PBX by  doxygen 1.4.6