Thu May 24 14:21:57 2007

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"

Include dependency graph for chan_sip.c:

Go to the source code of this file.

Data Structures

struct  ast_peer_list
 The peer list: Peers and Friends ---. More...
struct  ast_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.
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 struct cfsubscription_typesfind_subscription_type (enum subscriptiontype subtype)
 find_subscription_type: Find subscription type in array
static struct sip_userfind_user (const char *name, int realtime)
 find_user: Locate user by name Locates user by name (From: sip uri user name part) first from in-memory list (static configuration) then from realtime storage (defined in extconfig.conf)
static void free_old_route (struct sip_route *route)
 free_old_route: Remove route from route list ---
static char * func_check_sipdomain (struct ast_channel *chan, char *cmd, char *data, char *buf, size_t len)
 function_check_sipdomain: Dial plan function to check if domain is local
static char * func_header_read (struct ast_channel *chan, char *cmd, char *data, char *buf, size_t len)
 func_header_read: Read SIP header (dialplan function)
static char * function_sipchaninfo_read (struct ast_channel *chan, char *cmd, char *data, char *buf, size_t len)
 function_sipchaninfo_read: ${SIPCHANINFO()} Dialplan function - reads sip channel data
static char * function_sippeer (struct ast_channel *chan, char *cmd, char *data, char *buf, size_t len)
 function_sippeer: ${SIPPEER()} Dialplan function - reads peer data
static int get_also_info (struct sip_pvt *p, struct sip_request *oreq)
 get_also_info: Call transfer support (old way, depreciated)--
static char * get_body (struct sip_request *req, char *name)
 get_body: get a specific line from the message body
static char * get_body_by_line (char *line, char *name, int nameLen)
 get_body_by_line: Reads one line of message body
static char * get_calleridname (char *input, char *output, size_t outputsize)
 get_calleridname: Get caller id name from SIP headers ---
static int get_destination (struct sip_pvt *p, struct sip_request *oreq)
 get_destination: Find out who the call is for --
static char * get_header (struct sip_request *req, char *name)
 get_header: Get header from SIP request ---
static char * get_in_brackets (char *tmp)
 get_in_brackets: Pick out text in brackets from character string ---
static int get_msg_text (char *buf, int len, struct sip_request *req)
 get_msg_text: Get text out of a SIP MESSAGE packet ---
static int get_rdnis (struct sip_pvt *p, struct sip_request *oreq)
 get_rdnis: get referring dnis ---
static int get_refer_info (struct sip_pvt *sip_pvt, struct sip_request *outgoing_req)
 get_refer_info: Call transfer support (the REFER method) ---
static int get_rpid_num (char *input, char *output, int maxlen)
 get_rpid_num: Get caller id number from Remote-Party-ID header field Returns true if number should be restricted (privacy setting found) output is set to NULL if no number found
static char * get_sdp (struct sip_request *req, char *name)
 get_sdp: get a specific line from the SDP
static char * get_sdp_iterate (int *iterator, struct sip_request *req, char *name)
static struct sip_pvtget_sip_pvt_byid_locked (char *callid)
 get_sip_pvt_byid_locked: Lock interface lock and find matching pvt lock ---
static char * gettag (struct sip_request *req, char *header, char *tagbuf, int tagbufsize)
 gettag: Get tag from packet
static int handle_common_options (struct ast_flags *flags, struct ast_flags *mask, struct ast_variable *v)
 handle_common_options: Handle flag-type options common to users and peers ---
static int handle_request (struct sip_pvt *p, struct sip_request *req, struct sockaddr_in *sin, int *recount, int *nounlock)
 handle_request: Handle SIP requests (methods) ---
static int handle_request_bye (struct sip_pvt *p, struct sip_request *req, int debug, int ignore)
 handle_request_bye: Handle incoming BYE request ---
static int handle_request_cancel (struct sip_pvt *p, struct sip_request *req, int debug, int ignore)
 handle_request_cancel: Handle incoming CANCEL request ---
static void handle_request_info (struct sip_pvt *p, struct sip_request *req)
 handle_request_info: Receive SIP INFO Message ---
static int handle_request_invite (struct sip_pvt *p, struct sip_request *req, int debug, int ignore, int seqno, struct sockaddr_in *sin, int *recount, char *e)
 handle_request_invite: Handle incoming INVITE request
static int handle_request_message (struct sip_pvt *p, struct sip_request *req, int debug, int ignore)
 handle_request_message: Handle incoming MESSAGE request ---
static int handle_request_options (struct sip_pvt *p, struct sip_request *req, int debug)
 handle_request_options: Handle incoming OPTIONS request
static int handle_request_refer (struct sip_pvt *p, struct sip_request *req, int debug, int ignore, int seqno, int *nounlock)
 handle_request_refer: Handle incoming REFER request ---
static int handle_request_register (struct sip_pvt *p, struct sip_request *req, int debug, int ignore, struct sockaddr_in *sin, char *e)
 handle_request_register: Handle incoming REGISTER request ---
static int handle_request_subscribe (struct sip_pvt *p, struct sip_request *req, int debug, int ignore, struct sockaddr_in *sin, int seqno, char *e)
 handle_request_subscribe: Handle incoming SUBSCRIBE request ---
static void handle_response (struct sip_pvt *p, int resp, char *rest, struct sip_request *req, int ignore, int seqno)
 handle_response: Handle SIP response in dialogue ---
static void handle_response_invite (struct sip_pvt *p, int resp, char *rest, struct sip_request *req, int ignore, int seqno)
 handle_response_invite: Handle SIP response in dialogue ---
static int handle_response_peerpoke (struct sip_pvt *p, int resp, char *rest, struct sip_request *req, int ignore, int seqno, int sipmethod)
 handle_response_peerpoke: Handle qualification responses (OPTIONS)
static int handle_response_register (struct sip_pvt *p, int resp, char *rest, struct sip_request *req, int ignore, int seqno)
 handle_response_register: Handle responses on REGISTER to services ---
static char * hangup_cause2sip (int cause)
 hangup_cause2sip: Convert Asterisk hangup causes to SIP codes
static int hangup_sip2cause (int cause)
 hangup_sip2cause: Convert SIP hangup causes to Asterisk hangup causes ---
static int init_req (struct sip_request *req, int sipmethod, char *recip)
 init_req: Initialize SIP request ---
static int init_resp (struct sip_request *req, char *resp, struct sip_request *orig)
 init_resp: Initialize SIP response, based on SIP request ---
static void initreqprep (struct sip_request *req, struct sip_pvt *p, int sipmethod)
 initreqprep: Initiate new SIP request to peer/user ---
static const char * insecure2str (int port, int invite)
 insecure2str: Convert Insecure setting to printable string ---
char * key ()
 Returns the ASTERISK_GPL_KEY.
static void list_route (struct sip_route *route)
 list_route: List all routes - mostly for debugging ---
int load_module ()
 Initialize the module.
static int lws2sws (char *msgbuf, int len)
 lws2sws: Parse multiline SIP headers into one header
static void make_our_tag (char *tagbuf, size_t len)
static int manager_sip_show_peer (struct mansession *s, struct message *m)
 manager_sip_show_peer: Show SIP peers in the manager API ---
static int manager_sip_show_peers (struct mansession *s, struct message *m)
 manager_sip_show_peers: Show SIP peers in the manager API ---
static char * nat2str (int nat)
 nat2str: Convert NAT setting to text string
static void parse_copy (struct sip_request *dst, struct sip_request *src)
 parse_copy: Copy SIP request, parse it
static void parse_moved_contact (struct sip_pvt *p, struct sip_request *req)
 parse_moved_contact: Parse 302 Moved temporalily response
static int parse_ok_contact (struct sip_pvt *pvt, struct sip_request *req)
 parse_ok_contact: Parse contact header for 200 OK on INVITE ---
static enum parse_register_result parse_register_contact (struct sip_pvt *pvt, struct sip_peer *p, struct sip_request *req)
 parse_register_contact: Parse contact header and save registration ---
static void parse_request (struct sip_request *req)
 parse_request: Parse a SIP message ----
unsigned int parse_sip_options (struct sip_pvt *pvt, char *supported)
 parse_sip_options: Parse supported header in incoming packet
static int peer_status (struct sip_peer *peer, char *status, int statuslen)
 peer_status: Report Peer status in character string
static void print_codec_to_cli (int fd, struct ast_codec_pref *pref)
 print_codec_to_cli: Print codec list from preference to CLI/manager
static void print_group (int fd, unsigned int group, int crlf)
 print_group: Print call group and pickup group ---
static int process_sdp (struct sip_pvt *p, struct sip_request *req)
 process_sdp: Process SIP SDP and activate RTP channels---
static struct sip_peerrealtime_peer (const char *peername, struct sockaddr_in *sin)
 realtime_peer: Get peer from realtime storage Checks the "sippeers" realtime family from extconfig.conf
static void realtime_update_peer (const char *peername, struct sockaddr_in *sin, const char *username, const char *fullcontact, int expirey)
 realtime_update_peer: Update peer object in realtime storage ---
static struct sip_userrealtime_user (const char *username)
 realtime_user: Load user from realtime storage Loads user from "sipusers" category in realtime (extconfig.conf) Users are matched on From: user name (the domain in skipped)
static void receive_message (struct sip_pvt *p, struct sip_request *req)
 receive_message: Receive SIP MESSAGE method messages ---
static void reg_source_db (struct sip_peer *peer)
 reg_source_db: Get registration details from Asterisk DB ---
static void register_peer_exten (struct sip_peer *peer, int onoff)
 register_peer_exten: Automatically add peer extension to dial plan ---
static int register_verify (struct sip_pvt *p, struct sockaddr_in *sin, struct sip_request *req, char *uri, int ignore)
 register_verify: Verify registration of user
static char * regstate2str (int regstate)
int reload (void)
 Reload stuff.
static int reload_config (void)
 reload_config: Re-read SIP.conf config file ---
static int reply_digest (struct sip_pvt *p, struct sip_request *req, char *header, int sipmethod, char *digest, int digest_len)
 reply_digest: reply to authentication for outbound registrations ---
static int reqprep (struct sip_request *req, struct sip_pvt *p, int sipmethod, int seqno, int newbranch)
 reqprep: Initialize a SIP request response packet ---
static int respprep (struct sip_request *resp, struct sip_pvt *p, char *msg, struct sip_request *req)
 respprep: Prepare SIP response packet ---
static int restart_monitor (void)
 restart_monitor: Start the channel monitor thread ---
static int retrans_pkt (void *data)
 retrans_pkt: Retransmit SIP message if no answer ---
static void sdpLineNum_iterator_init (int *iterator, struct sip_request *req)
static int send_request (struct sip_pvt *p, struct sip_request *req, int reliable, int seqno)
 send_request: Send SIP Request to the other part of the dialogue ---
static int send_response (struct sip_pvt *p, struct sip_request *req, int reliable, int seqno)
 send_response: Transmit response on SIP request---
static void set_destination (struct sip_pvt *p, char *uri)
 set_destination: Set destination from SIP URI ---
static int sip_addheader (struct ast_channel *chan, void *data)
 sip_addheader: Add a SIP header ---
static int sip_addrcmp (char *name, struct sockaddr_in *sin)
 sip_addrcmp: Support routine for find_peer ---
static struct sip_pvtsip_alloc (char *callid, struct sockaddr_in *sin, int useglobal_nat, const int intended_method)
 sip_alloc: Allocate SIP_PVT structure and set defaults ---
static int sip_answer (struct ast_channel *ast)
 sip_answer: Answer SIP call , send 200 OK on Invite Part of PBX interface
static int sip_call (struct ast_channel *ast, char *dest, int timeout)
 sip_call: Initiate SIP call from PBX used from the dial() application
static int sip_cancel_destroy (struct sip_pvt *p)
 sip_cancel_destroy: Cancel destruction of SIP call ---
static int sip_debug_test_addr (struct sockaddr_in *addr)
 sip_debug_test_addr: See if we pass debug IP filter
static int sip_debug_test_pvt (struct sip_pvt *p)
 sip_debug_test_pvt: Test PVT for debugging output
static void sip_destroy (struct sip_pvt *p)
 sip_destroy: Destroy SIP call structure ---
static void sip_destroy_peer (struct sip_peer *peer)
 sip_destroy_peer: Destroy peer object from memory
static void sip_destroy_user (struct sip_user *user)
 sip_destroy_user: Remove user object from in-memory storage ---
static int sip_devicestate (void *data)
 sip_devicestate: Part of PBX channel interface ---
static int sip_do_debug (int fd, int argc, char *argv[])
 sip_do_debug: Turn on SIP debugging (CLI command)
static int sip_do_debug_ip (int fd, int argc, char *argv[])
 sip_do_debug: Enable SIP Debugging in CLI ---
static int sip_do_debug_peer (int fd, int argc, char *argv[])
 sip_do_debug_peer: Turn on SIP debugging with peer mask
static int sip_do_history (int fd, int argc, char *argv[])
 sip_do_history: Enable SIP History logging (CLI) ---
static int sip_do_reload (void)
 sip_do_reload: Reload module
static int sip_dtmfmode (struct ast_channel *chan, void *data)
 sip_dtmfmode: change the DTMFmode for a SIP call (application) ---
static void sip_dump_history (struct sip_pvt *dialog)
 dump_history: Dump SIP history to debug log file at end of lifespan for SIP dialog
static int sip_fixup (struct ast_channel *oldchan, struct ast_channel *newchan)
 sip_fixup: Fix up a channel: If a channel is consumed, this is called. Basically update any ->owner links ----
static int sip_get_codec (struct ast_channel *chan)
 sip_get_codec: Return SIP UA's codec (part of the RTP interface) ---
static struct ast_rtpsip_get_rtp_peer (struct ast_channel *chan)
 sip_get_rtp_peer: Returns null if we can't reinvite (part of RTP interface)
static struct ast_rtpsip_get_vrtp_peer (struct ast_channel *chan)
 sip_get_vrtp_peer: Returns null if we can't reinvite video (part of RTP interface)
static int sip_getheader (struct ast_channel *chan, void *data)
 sip_getheader: Get a SIP header (dialplan app) ---
static int sip_hangup (struct ast_channel *ast)
 sip_hangup: Hangup SIP call Part of PBX interface, called from ast_hangup
static int sip_indicate (struct ast_channel *ast, int condition)
 sip_indicate: Play indication to user With SIP a lot of indications is sent as messages, letting the device play the indication - busy signal, congestion etc
static struct ast_channelsip_new (struct sip_pvt *i, int state, char *title)
 sip_new: Initiate a call in the SIP channel
static int sip_no_debug (int fd, int argc, char *argv[])
 sip_no_debug: Disable SIP Debugging in CLI ---
static int sip_no_history (int fd, int argc, char *argv[])
 sip_no_history: Disable SIP History logging (CLI) ---
static int sip_notify (int fd, int argc, char *argv[])
 sip_notify: Send SIP notify to peer
static int sip_park (struct ast_channel *chan1, struct ast_channel *chan2, struct sip_request *req)
 sip_park: Park a call ---
static void * sip_park_thread (void *stuff)
 sip_park_thread: Park SIP call support function
static void sip_poke_all_peers (void)
 sip_poke_all_peers: Send a poke to all known peers
static int sip_poke_noanswer (void *data)
 sip_poke_noanswer: No answer to Qualify poke ---
static int sip_poke_peer (struct sip_peer *peer)
 sip_poke_peer: Check availability of peer, also keep NAT open ---
static int sip_poke_peer_s (void *data)
static int sip_prune_realtime (int fd, int argc, char *argv[])
 sip_prune_realtime: Remove temporary realtime objects from memory (CLI) ---
static struct ast_framesip_read (struct ast_channel *ast)
 sip_read: Read SIP RTP from channel
static int sip_reg_timeout (void *data)
 sip_reg_timeout: Registration timeout, register again
static int sip_register (char *value, int lineno)
 sip_register: Parse register=> line in sip.conf and add to registry
static void sip_registry_destroy (struct sip_registry *reg)
 sip_registry_destroy: Destroy registry object ---
static int sip_reload (int fd, int argc, char *argv[])
 sip_reload: Force reload of module from cli ---
static struct ast_channelsip_request_call (const char *type, int format, void *data, int *cause)
 sip_request: PBX interface function -build SIP pvt structure ---
static int sip_reregister (void *data)
 sip_reregister: Update registration with SIP Proxy---
static struct ast_framesip_rtp_read (struct ast_channel *ast, struct sip_pvt *p)
 sip_rtp_read: Read RTP from network ---
static int sip_scheddestroy (struct sip_pvt *p, int ms)
 sip_scheddestroy: Schedule destruction of SIP call ---
static void sip_send_all_registers (void)
 sip_send_all_registers: Send all known registrations
static int sip_send_mwi_to_peer (struct sip_peer *peer)
 sip_send_mwi_to_peer: Send message waiting indication ---
static int sip_senddigit (struct ast_channel *ast, char digit)
 sip_senddigit: Send DTMF character on SIP channel
static int sip_sendtext (struct ast_channel *ast, const char *text)
 sip_sendtext: Send SIP MESSAGE text within a call ---
static int sip_set_rtp_peer (struct ast_channel *chan, struct ast_rtp *rtp, struct ast_rtp *vrtp, int codecs, int nat_active)
 sip_set_rtp_peer: Set the RTP peer for this call ---
static int sip_show_channel (int fd, int argc, char *argv[])
 sip_show_channel: Show details of one call ---
static int sip_show_channels (int fd, int argc, char *argv[])
 sip_show_channels: Show active SIP channels ---
static int sip_show_domains (int fd, int argc, char *argv[])
static int sip_show_history (int fd, int argc, char *argv[])
 sip_show_history: Show history details of one call ---
static int sip_show_inuse (int fd, int argc, char *argv[])
 sip_show_inuse: CLI Command to show calls within limits set by call_limit ---
static int sip_show_objects (int fd, int argc, char *argv[])
 sip_show_objects: List all allocated SIP Objects ---
static int sip_show_peer (int fd, int argc, char *argv[])
 sip_show_peer: Show one peer in detail ---
static int sip_show_peers (int fd, int argc, char *argv[])
 sip_show_peers: CLI Show Peers command
static int sip_show_registry (int fd, int argc, char *argv[])
 sip_show_registry: Show SIP Registry (registrations with other SIP proxies ---
static int sip_show_settings (int fd, int argc, char *argv[])
 sip_show_settings: List global settings for the SIP channel ---
static int sip_show_subscriptions (int fd, int argc, char *argv[])
 sip_show_subscriptions: Show active SIP subscriptions ---
static int sip_show_user (int fd, int argc, char *argv[])
 sip_show_user: Show one user in detail ---
static int sip_show_users (int fd, int argc, char *argv[])
 sip_show_users: CLI Command 'SIP Show Users' ---
static int sip_sipredirect (struct sip_pvt *p, const char *dest)
 sip_sipredirect: Transfer call before connect with a 302 redirect ---
static int sip_transfer (struct ast_channel *ast, const char *dest)
 sip_transfer: Transfer SIP call
static int sip_write (struct ast_channel *ast, struct ast_frame *frame)
 sip_write: Send frame to media channel (rtp) ---
static int sipsock_read (int *id, int fd, short events, void *ignore)
 sipsock_read: Read data from SIP socket ---
static const char * subscription_type2str (enum subscriptiontype subtype)
 subscription_type2str: Show subscription type in string format
static struct sip_peertemp_peer (const char *name)
 temp_peer: Create temporary peer (used in autocreatepeer mode) ---
static force_inline int thread_safe_rand (void)
 Thread-safe random number generator.
static void transmit_fake_auth_response (struct sip_pvt *p, struct sip_request *req, char *randdata, int randlen, int reliable)
 Send a fake 401 Unauthorized response when the administrator wants to hide the names of local users/peers from fishers.
static int transmit_info_with_digit (struct sip_pvt *p, char digit)
 transmit_info_with_digit: Send SIP INFO dtmf message, see Cisco documentation on cisco.co m ---
static int transmit_info_with_vidupdate (struct sip_pvt *p)
 transmit_info_with_vidupdate: Send SIP INFO with video update request ---
static int transmit_invite (struct sip_pvt *p, int sipmethod, int 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_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 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 struct cfsip_methods sip_methods []
static struct cfsip_options sip_options []
 List of well-known SIP options. If we get this in a require, we should check the list and answer accordingly.
static 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 struct ast_channel_tech sip_tech
 Definition of this channel for PBX channel registration.
static struct ast_custom_function sipchaninfo_function
static int sipdebug = 0
ast_custom_function sippeer_function
static int sipsock = -1
static int speerobjs = 0
static int srvlookup = 0
static struct cfsubscription_types subscription_types []
static int suserobjs = 0
static char * synopsis_dtmfmode = "Change the dtmfmode for a SIP call"
static char * synopsis_sipaddheader = "Add a SIP header to the outbound call"
static char * synopsis_sipgetheader = "Get a SIP header from an incoming call"
static int tos = 0
static int usecnt = 0
static struct ast_user_list userl
 The user list: Users and friends ---.
static int videosupport = 0


Detailed Description

Implementation of Session Initiation Protocol.

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

Todo:
SIP over TCP

SIP over TLS

Better support of forking

Definition in file chan_sip.c.


Define Documentation

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

SIP Methods we support.

Definition at line 323 of file chan_sip.c.

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

#define CALLERID_UNKNOWN   "Unknown"

Definition at line 127 of file chan_sip.c.

Referenced by initreqprep().

#define DEBUG_READ   0

Definition at line 141 of file chan_sip.c.

Referenced by ael_debug_read(), and ast_ael_compile().

#define DEBUG_SEND   1

Definition at line 142 of file chan_sip.c.

#define DEC_CALL_LIMIT   0

Definition at line 445 of file chan_sip.c.

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

#define DEFAULT_CALLERID   "asterisk"

Definition at line 342 of file chan_sip.c.

Referenced by reload_config().

#define DEFAULT_CONTEXT   "default"

Definition at line 333 of file chan_sip.c.

Referenced by reload_config().

#define DEFAULT_DEFAULT_EXPIRY   120

Definition at line 101 of file chan_sip.c.

Referenced by reload_config().

#define DEFAULT_EXPIRY   900

Expire slowly

Definition at line 436 of file chan_sip.c.

#define DEFAULT_FREQ_NOTOK   10 * 1000

Definition at line 133 of file chan_sip.c.

#define DEFAULT_FREQ_OK   60 * 1000

Definition at line 132 of file chan_sip.c.

#define DEFAULT_MAX_EXPIRY   3600

Definition at line 102 of file chan_sip.c.

Referenced by reload_config().

#define DEFAULT_MAX_FORWARDS   "70"

Definition at line 104 of file chan_sip.c.

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

#define DEFAULT_MAXMS   2000

Definition at line 131 of file chan_sip.c.

#define DEFAULT_MWITIME   10

Definition at line 386 of file chan_sip.c.

Referenced by reload_config().

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

Definition at line 347 of file chan_sip.c.

Referenced by reload_config().

#define DEFAULT_REALM   "asterisk"

Definition at line 432 of file chan_sip.c.

Referenced by reload_config().

#define DEFAULT_REGISTRATION_TIMEOUT   20

Definition at line 103 of file chan_sip.c.

Referenced by reload_config().

#define DEFAULT_RETRANS   1000

Definition at line 135 of file chan_sip.c.

#define DEFAULT_SIP_PORT   5060

From RFC 3261 (former 2543)

Definition at line 328 of file chan_sip.c.

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

#define DEFAULT_USERAGENT   "Asterisk PBX"

Definition at line 90 of file chan_sip.c.

Referenced by reload_config().

#define DEFAULT_VMEXTEN   "asterisk"

Definition at line 337 of file chan_sip.c.

Referenced by reload_config().

#define EXPIRY_GUARD_LIMIT   30

Definition at line 109 of file chan_sip.c.

Referenced by handle_response_register().

#define EXPIRY_GUARD_MIN   500

Definition at line 111 of file chan_sip.c.

Referenced by handle_response_register().

#define EXPIRY_GUARD_PCT   0.20

Definition at line 115 of file chan_sip.c.

Referenced by handle_response_register().

#define EXPIRY_GUARD_SECS   15

Definition at line 108 of file chan_sip.c.

Referenced by handle_response_register().

#define FLAG_FATAL   (1 << 1)

Definition at line 703 of file chan_sip.c.

Referenced by __sip_reliable_xmit(), and retrans_pkt().

#define FLAG_RESPONSE   (1 << 0)

Definition at line 702 of file chan_sip.c.

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

#define 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 7960 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 7960 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 7960 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 7960 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 7960 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 7960 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 962 of file chan_sip.c.

#define INC_CALL_LIMIT   1

Definition at line 446 of file chan_sip.c.

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

#define IPTOS_MINCOST   0x02

Definition at line 95 of file chan_sip.c.

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

Definition at line 124 of file chan_sip.c.

#define MAX_AUTHTRIES   3

Definition at line 138 of file chan_sip.c.

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

#define MAX_RETRANS   6

Definition at line 137 of file chan_sip.c.

#define NO_RTP   0

Definition at line 150 of file chan_sip.c.

#define NOT_SUPPORTED   0

Definition at line 267 of file chan_sip.c.

#define REG_STATE_AUTHSENT   2

Definition at line 811 of file chan_sip.c.

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

#define REG_STATE_FAILED   7

Definition at line 816 of file chan_sip.c.

Referenced by regstate2str(), and sip_reg_timeout().

#define REG_STATE_NOAUTH   6

Definition at line 815 of file chan_sip.c.

Referenced by registry_rerequest(), and regstate2str().

#define REG_STATE_REGISTERED   3

Definition at line 812 of file chan_sip.c.

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

#define REG_STATE_REGSENT   1

Definition at line 810 of file chan_sip.c.

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

#define REG_STATE_REJECTED   4

Definition at line 813 of file chan_sip.c.

Referenced by regstate2str(), and socket_read().

#define REG_STATE_TIMEOUT   5

Definition at line 814 of file chan_sip.c.

Referenced by attempt_transmit(), and regstate2str().

#define REG_STATE_UNREGISTERED   0

Definition at line 809 of file chan_sip.c.

Referenced by regstate2str(), and sip_reg_timeout().

#define RTP   1

Definition at line 149 of file chan_sip.c.

#define SIP_ALREADYGONE   (1 << 0)

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

Definition at line 518 of file chan_sip.c.

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

#define SIP_CALL_LIMIT   (1 << 29)

Definition at line 566 of file chan_sip.c.

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

#define SIP_CALL_ONHOLD   (1 << 28)

Definition at line 565 of file chan_sip.c.

Referenced by __sip_show_channels(), and process_sdp().

#define SIP_CAN_BYE   (1 << 15)

Can we send BYE for this dialog?

Definition at line 533 of file chan_sip.c.

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

#define SIP_CAN_REINVITE   (1 << 20)

allow peers to be reinvited to send media directly p2p

Definition at line 548 of file chan_sip.c.

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

#define SIP_DEBUG_CONFIG   1 << 0

Definition at line 417 of file chan_sip.c.

Referenced by reload_config().

#define SIP_DEBUG_CONSOLE   1 << 1

Definition at line 418 of file chan_sip.c.

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

#define SIP_DTMF   (3 << 16)

three settings, uses two bits

Definition at line 535 of file chan_sip.c.

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

#define SIP_DTMF_AUTO   (3 << 16)

AUTO switch between rfc2833 and in-band DTMF

Definition at line 539 of file chan_sip.c.

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

#define SIP_DTMF_INBAND   (1 << 16)

Inband audio, only for ULAW/ALAW

Definition at line 537 of file chan_sip.c.

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

#define SIP_DTMF_INFO   (2 << 16)

SIP Info messages

Definition at line 538 of file chan_sip.c.

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

#define SIP_DTMF_RFC2833   (0 << 16)

RTP DTMF

Definition at line 536 of file chan_sip.c.

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

#define SIP_FLAGS_TO_COPY

Value:

Definition at line 572 of file chan_sip.c.

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

#define SIP_GOTREFER   (1 << 7)

Got a refer?

Definition at line 525 of file chan_sip.c.

Referenced by handle_request_refer(), and sip_set_rtp_peer().

#define SIP_INC_COUNT   (1 << 31)

Definition at line 570 of file chan_sip.c.

Referenced by update_call_counter().

#define SIP_INSECURE_INVITE   (1 << 23)

don't require authentication for incoming INVITEs

Definition at line 552 of file chan_sip.c.

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

#define SIP_INSECURE_PORT   (1 << 22)

don't require matching port for incoming requests

Definition at line 551 of file chan_sip.c.

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

#define SIP_LEN_CONTACT   256

Definition at line 118 of file chan_sip.c.

Referenced by parse_ok_contact(), and respprep().

#define SIP_MAX_HEADERS   64

Max amount of SIP headers to read

Definition at line 442 of file chan_sip.c.

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

#define SIP_MAX_LINES   64

Max amount of lines in SIP attachment (like SDP)

Definition at line 443 of file chan_sip.c.

Referenced by add_line(), and parse_request().

#define SIP_MAX_PACKET   4096

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

Definition at line 329 of file chan_sip.c.

#define SIP_NAT   (3 << 18)

four settings, uses two bits

Definition at line 541 of file chan_sip.c.

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

#define SIP_NAT_ALWAYS   (3 << 18)

Definition at line 545 of file chan_sip.c.

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

#define SIP_NAT_NEVER   (0 << 18)

No nat support

Definition at line 542 of file chan_sip.c.

Referenced by handle_common_options(), and nat2str().

#define SIP_NAT_RFC3581   (1 << 18)

Definition at line 543 of file chan_sip.c.

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

#define SIP_NAT_ROUTE   (2 << 18)

Definition at line 544 of file chan_sip.c.

Referenced by __sip_xmit(), _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 519 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 523 of file chan_sip.c.

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

#define SIP_NOVIDEO   (1 << 2)

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

Definition at line 520 of file chan_sip.c.

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

#define SIP_OPT_100REL   (1 << 1)

Definition at line 270 of file chan_sip.c.

#define SIP_OPT_EARLY_SESSION   (1 << 3)

Definition at line 272 of file chan_sip.c.

#define SIP_OPT_EVENTLIST   (1 << 11)

Definition at line 280 of file chan_sip.c.

#define SIP_OPT_GRUU   (1 << 12)

Definition at line 281 of file chan_sip.c.

#define SIP_OPT_JOIN   (1 << 4)

Definition at line 273 of file chan_sip.c.

#define SIP_OPT_PATH   (1 << 5)

Definition at line 274 of file chan_sip.c.

#define SIP_OPT_PRECONDITION   (1 << 7)

Definition at line 276 of file chan_sip.c.

#define SIP_OPT_PREF   (1 << 6)

Definition at line 275 of file chan_sip.c.

#define SIP_OPT_PRIVACY   (1 << 8)

Definition at line 277 of file chan_sip.c.

#define SIP_OPT_REPLACES   (1 << 0)

Definition at line 269 of file chan_sip.c.

#define SIP_OPT_SDP_ANAT   (1 << 9)

Definition at line 278 of file chan_sip.c.

#define SIP_OPT_SEC_AGREE   (1 << 10)

Definition at line 279 of file chan_sip.c.

#define SIP_OPT_TARGET_DIALOG   (1 << 13)

Definition at line 282 of file chan_sip.c.

#define SIP_OPT_TIMER   (1 << 2)

Definition at line 271 of file chan_sip.c.

#define SIP_OSPAUTH   (3 << 26)

four settings, uses two bits

Definition at line 559 of file chan_sip.c.

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

#define SIP_OSPAUTH_EXCLUSIVE   (3 << 26)

Definition at line 563 of file chan_sip.c.

Referenced by check_auth(), and handle_common_options().

#define SIP_OSPAUTH_GATEWAY   (1 << 26)

Definition at line 561 of file chan_sip.c.

Referenced by check_auth(), and handle_common_options().

#define SIP_OSPAUTH_NO   (0 << 26)

Definition at line 560 of file chan_sip.c.

Referenced by check_auth().

#define SIP_OSPAUTH_PROXY   (2 << 26)

Definition at line 562 of file chan_sip.c.

Referenced by check_auth(), and handle_common_options().

#define SIP_OUTGOING   (1 << 13)

Is this an outgoing call?

Definition at line 531 of file chan_sip.c.

Referenced by handle_request_bye(), handle_request_invite(), handle_request_subscribe(), handle_response(), handle_response_invite(), reqprep(), respprep(), sip_call(), sip_hangup(), sip_indicate(), sip_poke_peer(), sip_send_mwi_to_peer(), sip_show_channel(), sip_write(), transmit_refer(), transmit_register(), transmit_reinvite_with_sdp(), and update_call_counter().

#define SIP_PAGE2_DYNAMIC   (1 << 5)

Is this a dynamic peer?

Definition at line 583 of file chan_sip.c.

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

#define SIP_PAGE2_IGNOREREGEXPIRE   (1 << 3)

Definition at line 581 of file chan_sip.c.

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

#define SIP_PAGE2_RT_FROMCONTACT   (1 << 4)

Definition at line 582 of file chan_sip.c.

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

#define SIP_PAGE2_RTAUTOCLEAR   (1 << 2)

Definition at line 580 of file chan_sip.c.

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

#define SIP_PAGE2_RTCACHEFRIENDS   (1 << 0)

Definition at line 578 of file chan_sip.c.

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

#define SIP_PAGE2_RTUPDATE   (1 << 1)

Definition at line 579 of file chan_sip.c.

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

#define SIP_PENDINGBYE   (1 << 6)

Need to send bye after we ack?

Definition at line 524 of file chan_sip.c.

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

#define SIP_PKT_DEBUG   (1 << 0)

Debug this packet

Definition at line 586 of file chan_sip.c.

Referenced by sipsock_read().

#define SIP_PKT_WITH_TOTAG   (1 << 1)

This packet has a to-tag

Definition at line 587 of file chan_sip.c.

Referenced by find_call(), and handle_request().

#define SIP_PROG_INBAND   (3 << 24)

three settings, uses two bits

Definition at line 554 of file chan_sip.c.

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

#define SIP_PROG_INBAND_NEVER   (0 << 24)

Definition at line 555 of file chan_sip.c.

Referenced by sip_indicate(), and sip_show_settings().

#define SIP_PROG_INBAND_NO   (1 << 24)

Definition at line 556 of file chan_sip.c.

Referenced by handle_common_options(), and sip_show_settings().

#define SIP_PROG_INBAND_YES   (2 << 24)

Definition at line 557 of file chan_sip.c.

Referenced by handle_common_options(), and sip_indicate().

#define SIP_PROGRESS_SENT   (1 << 4)

Have sent 183 message progress

Definition at line 522 of file chan_sip.c.

Referenced by sip_indicate(), and sip_write().

#define SIP_PROMISCREDIR   (1 << 8)

Promiscuous redirection

Definition at line 526 of file chan_sip.c.

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

#define SIP_REALTIME   (1 << 11)

Flag for realtime users

Definition at line 529 of file chan_sip.c.

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

#define SIP_REINVITE   (3 << 20)

two bits used

Definition at line 547 of file chan_sip.c.

Referenced by handle_common_options().

#define SIP_REINVITE_UPDATE   (2 << 20)

use UPDATE (RFC3311) when reinviting this peer

Definition at line 549 of file chan_sip.c.

Referenced by handle_common_options(), and transmit_reinvite_with_sdp().

#define SIP_RINGING   (1 << 3)

Have sent 180 ringing

Definition at line 521 of file chan_sip.c.

Referenced by sip_indicate().

#define SIP_SELFDESTRUCT   (1 << 14)

This is an autocreated peer

Definition at line 532 of file chan_sip.c.

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

#define SIP_SENDRPID   (1 << 30)

Definition at line 568 of file chan_sip.c.

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

#define SIP_TRUSTRPID   (1 << 9)

Trust RPID headers?

Definition at line 527 of file chan_sip.c.

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

#define SIP_USECLIENTCODE   (1 << 12)

Trust X-ClientCode info message

Definition at line 530 of file chan_sip.c.

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

#define SIP_USEREQPHONE   (1 << 10)

Add user=phone to numeric URI. Default off

Definition at line 528 of file chan_sip.c.

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

#define SIPDUMPER

Definition at line 100 of file chan_sip.c.

#define SUPPORTED   1

Define SIP option tags, used in Require: and Supported: headers We need to be aware of these properties in the phones to use the replace: header. We should not do that without knowing that the other end supports it... This is nothing we can configure, we learn by the dialog Supported: header on the REGISTER (peer) or the INVITE (other devices) We are not using many of these today, but will in the future. This is documented in RFC 3261

Definition at line 266 of file chan_sip.c.

#define SUPPORTED_EXTENSIONS   "replaces"

SIP Extensions we support.

Definition at line 326 of file chan_sip.c.

#define VIDEO_CODEC_MASK   0x1fc0000

Definition at line 93 of file chan_sip.c.

Referenced by add_sdp().


Enumeration Type Documentation

enum domain_mode

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

Definition at line 487 of file chan_sip.c.

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

enum parse_register_result

Enumerator:
PARSE_REGISTER_FAILED 
PARSE_REGISTER_UPDATE 
PARSE_REGISTER_QUERY 

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

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

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

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

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

static int __sip_autodestruct ( void *  data  )  [static]

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

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

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

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

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

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

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

static int __sip_do_register ( struct sip_registry r  )  [static]

__sip_do_register: Register with SIP proxy ---

Definition at line 5368 of file chan_sip.c.

References SIP_REGISTER, and transmit_register().

Referenced by sip_reregister().

05369 {
05370    int res;
05371 
05372    res = transmit_register(r, SIP_REGISTER, NULL, NULL);
05373    return res;
05374 }

static int __sip_pretend_ack ( struct sip_pvt p  )  [static]

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

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

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

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

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

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

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

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

08418 {
08419 #define FORMAT3 "%-15.15s  %-10.10s  %-11.11s  %-15.15s  %-13.13s  %-15.15s\n"
08420 #define FORMAT2 "%-15.15s  %-10.10s  %-11.11s  %-11.11s  %-4.4s  %-7.7s  %-15.15s\n"
08421 #define FORMAT  "%-15.15s  %-10.10s  %-11.11s  %5.5d/%5.5d  %-4.4s  %-3.3s %-3.3s  %-15.15s\n"
08422    struct sip_pvt *cur;
08423    char iabuf[INET_ADDRSTRLEN];
08424    int numchans = 0;
08425    if (argc != 3)
08426       return RESULT_SHOWUSAGE;
08427    ast_mutex_lock(&iflock);
08428    cur = iflist;
08429    if (!subscriptions)
08430       ast_cli(fd, FORMAT2, "Peer", "User/ANR", "Call ID", "Seq (Tx/Rx)", "Format", "Hold", "Last Message");
08431    else
08432       ast_cli(fd, FORMAT3, "Peer", "User", "Call ID", "Extension", "Last state", "Type");
08433    while (cur) {
08434       if (cur->subscribed == NONE && !subscriptions) {
08435          ast_cli(fd, FORMAT, ast_inet_ntoa(iabuf, sizeof(iabuf), cur->sa.sin_addr), 
08436             ast_strlen_zero(cur->username) ? ( ast_strlen_zero(cur->cid_num) ? "(None)" : cur->cid_num ) : cur->username, 
08437             cur->callid, 
08438             cur->ocseq, cur->icseq, 
08439             ast_getformatname(cur->owner ? cur->owner->nativeformats : 0), 
08440             ast_test_flag(cur, SIP_CALL_ONHOLD) ? "Yes" : "No",
08441             ast_test_flag(cur, SIP_NEEDDESTROY) ? "(d)" : "",
08442             cur->lastmsg );
08443          numchans++;
08444       }
08445       if (cur->subscribed != NONE && subscriptions) {
08446          ast_cli(fd, FORMAT3, ast_inet_ntoa(iabuf, sizeof(iabuf), cur->sa.sin_addr),
08447                  ast_strlen_zero(cur->username) ? ( ast_strlen_zero(cur->cid_num) ? "(None)" : cur->cid_num ) : cur->username, 
08448                  cur->callid, cur->exten, ast_extension_state2str(cur->laststate), 
08449                  subscription_type2str(cur->subscribed));
08450          numchans++;
08451       }
08452       cur = cur->next;
08453    }
08454    ast_mutex_unlock(&iflock);
08455    if (!subscriptions)
08456       ast_cli(fd, "%d active SIP channel%s\n", numchans, (numchans != 1) ? "s" : "");
08457    else
08458       ast_cli(fd, "%d active SIP subscription%s\n", numchans, (numchans != 1) ? "s" : "");
08459    return RESULT_SUCCESS;
08460 #undef FORMAT
08461 #undef FORMAT2
08462 #undef FORMAT3
08463 }

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

__sip_xmit: Transmit SIP message ---

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

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

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

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

Referenced by transmit_response(), and transmit_response_reliable().

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

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

Definition at line 8023 of file chan_sip.c.

References sip_peer::accountcode, sip_peer::addr, sip_peer::amaflags, ast_callerid_merge(), ast_cdr_flags2str(), ast_cli(), ast_codec_pref_index(), ast_describe_caller_presentation(), ast_getformatname(), ast_getformatname_multiple(), ast_inet_ntoa(), ast_sched_when(), ast_strlen_zero(), ast_test_flag, astman_send_error(), ASTOBJ_UNREF, sip_peer::auth, sip_peer::call_limit, sip_peer::callgroup, sip_peer::callingpres, sip_peer::capability, sip_peer::chanvars, sip_peer::cid_name, sip_peer::cid_num, sip_peer::context, sip_peer::defaddr, dtmfmode2str(), sip_peer::expire, find_peer(), sip_peer::flags_page2, sip_peer::fromdomain, sip_peer::fromuser, sip_peer::fullcontact, sip_peer::ha, insecure2str(), sip_peer::language, sip_peer::lastmsg, sip_peer::lastmsgssent, sip_peer::mailbox, sip_auth::md5secret, sip_peer::md5secret, ast_variable::name, nat2str(), ast_variable::next, sip_auth::next, peer_status(), sip_peer::pickupgroup, sip_peer::prefs, print_codec_to_cli(), print_group(), sip_auth::realm, RESULT_SHOWUSAGE, RESULT_SUCCESS, 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().

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

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 7601 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, RESULT_SUCCESS, s, SIP_NAT, SIP_NAT_ROUTE, and SIP_PAGE2_DYNAMIC.

Referenced by manager_sip_show_peers(), and sip_show_peers().

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

static int add_blank_header ( struct sip_request req  )  [static]

add_blank_header: Add blank header to SIP message

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

03821 {
03822    if (req->headers == SIP_MAX_HEADERS)  {
03823       ast_log(LOG_WARNING, "Out of SIP header space\n");
03824       return -1;
03825    }
03826    if (req->lines) {
03827       ast_log(LOG_WARNING, "Can't add more headers when lines have been added\n");
03828       return -1;
03829    }
03830    if (req->len >= sizeof(req->data) - 4) {
03831       ast_log(LOG_WARNING, "Out of space, can't add anymore\n");
03832       return -1;
03833    }
03834    req->header[req->headers] = req->data + req->len;
03835    snprintf(req->header[req->headers], sizeof(req->data) - req->len, "\r\n");
03836    req->len += strlen(req->header[req->headers]);
03837    req->headers++;
03838    return 0;   
03839 }

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

04375 {
04376    int rtp_code;
04377 
04378    if (debug)
04379       ast_verbose("Adding codec 0x%x (%s) to SDP\n", codec, ast_getformatname(codec));
04380    if ((rtp_code = ast_rtp_lookup_code(p->rtp, 1, codec)) == -1)
04381       return;
04382 
04383    ast_build_string(m_buf, m_size, " %d", rtp_code);
04384    ast_build_string(a_buf, a_size, "a=rtpmap:%d %s/%d\r\n", rtp_code,
04385           ast_rtp_lookup_mime_subtype(1, codec),
04386           sample_rate);
04387    if (codec == AST_FORMAT_G729A)
04388       /* Indicate that we don't support VAD (G.729 annex B) */
04389       ast_build_string(a_buf, a_size, "a=fmtp:%d annexb=no\r\n", rtp_code);
04390 }

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

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

Definition at line 4341 of file chan_sip.c.

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

Referenced by transmit_info_with_digit().

04342 {
04343    char tmp[256];
04344 
04345    snprintf(tmp, sizeof(tmp), "Signal=%c\r\nDuration=250\r\n", digit);
04346    add_header(req, "Content-Type", "application/dtmf-relay");
04347    add_header_contentLength(req, strlen(tmp));
04348    add_line(req, tmp);
04349    return 0;
04350 }

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

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

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

References add_header().

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

03812 {
03813    char clen[10];
03814 
03815    snprintf(clen, sizeof(clen), "%d", len);
03816    return add_header(req, "Content-Length", clen);
03817 }

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

add_line: Add content (not header) to SIP message

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

03843 {
03844    if (req->lines == SIP_MAX_LINES)  {
03845       ast_log(LOG_WARNING, "Out of SIP line space\n");
03846       return -1;
03847    }
03848    if (!req->lines) {
03849       /* Add extra empty return */
03850       snprintf(req->data + req->len, sizeof(req->data) - req->len, "\r\n");
03851       req->len += strlen(req->data + req->len);
03852    }
03853    if (req->len >= sizeof(req->data) - 4) {
03854       ast_log(LOG_WARNING, "Out of space, can't add anymore\n");
03855       return -1;
03856    }
03857    req->line[req->lines] = req->data + req->len;
03858    snprintf(req->line[req->lines], sizeof(req->data) - req->len, "%s", line);
03859    req->len += strlen(req->line[req->lines]);
03860    req->lines++;
03861    return 0;   
03862 }

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

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

Referenced by add_sdp().

04395 {
04396    int rtp_code;
04397 
04398    if (debug)
04399       ast_verbose("Adding non-codec 0x%x (%s) to SDP\n", format, ast_rtp_lookup_mime_subtype(0, format));
04400    if ((rtp_code = ast_rtp_lookup_code(p->rtp, 0, format)) == -1)
04401       return;
04402 
04403    ast_build_string(m_buf, m_size, " %d", rtp_code);
04404    ast_build_string(a_buf, a_size, "a=rtpmap:%d %s/%d\r\n", rtp_code,
04405           ast_rtp_lookup_mime_subtype(0, format),
04406           sample_rate);
04407    if (format == AST_RTP_DTMF)
04408       /* Indicate we support DTMF and FLASH... */
04409       ast_build_string(a_buf, a_size, "a=fmtp:%d 0-16\r\n", rtp_code);
04410 }

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

12025 {
12026    char authcopy[256];
12027    char *username=NULL, *realm=NULL, *secret=NULL, *md5secret=NULL;
12028    char *stringp;
12029    struct sip_auth *auth;
12030    struct sip_auth *b = NULL, *a = authlist;
12031 
12032    if (ast_strlen_zero(configuration))
12033       return authlist;
12034 
12035    ast_log(LOG_DEBUG, "Auth config ::  %s\n", configuration);
12036 
12037    ast_copy_string(authcopy, configuration, sizeof(authcopy));
12038    stringp = authcopy;
12039 
12040    username = stringp;
12041    realm = strrchr(stringp, '@');
12042    if (realm) {
12043       *realm = '\0';
12044       realm++;
12045    }
12046    if (ast_strlen_zero(username) || ast_strlen_zero(realm)) {
12047       ast_log(LOG_WARNING, "Format for authentication entry is user[:secret]@realm at line %d\n", lineno);
12048       return authlist;
12049    }
12050    stringp = username;
12051    username = strsep(&stringp, ":");
12052    if (username) {
12053       secret = strsep(&stringp, ":");
12054       if (!secret) {
12055          stringp = username;
12056          md5secret = strsep(&stringp,"#");
12057       }
12058    }
12059    auth = malloc(sizeof(struct sip_auth));
12060    if (auth) {
12061       memset(auth, 0, sizeof(struct sip_auth));
12062       ast_copy_string(auth->realm, realm, sizeof(auth->realm));
12063       ast_copy_string(auth->username, username, sizeof(auth->username));
12064       if (secret)
12065          ast_copy_string(auth->secret, secret, sizeof(auth->secret));
12066       if (md5secret)
12067          ast_copy_string(auth->md5secret, md5secret, sizeof(auth->md5secret));
12068    } else {
12069       ast_log(LOG_ERROR, "Allocation of auth structure failed, Out of memory\n");
12070       return authlist;
12071    }
12072 
12073    /* Add authentication to authl */
12074    if (!authlist) {  /* No existing list */
12075       return auth;
12076    } 
12077    while(a) {
12078       b = a;
12079       a = a->next;
12080    }
12081    b->next = auth;   /* Add structure add end of list */
12082 
12083    if (option_verbose > 2)
12084       ast_verbose("Added authentication for realm %s\n", realm);
12085 
12086    return authlist;
12087 
12088 }

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

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

Referenced by reqprep().

03961 {
03962    char r[BUFSIZ*2], *p;
03963    int n, rem = sizeof(r);
03964 
03965    if (!route) return;
03966 
03967    p = r;
03968    while (route) {
03969       n = strlen(route->hop);
03970       if ((n+3)>rem) break;
03971       if (p != r) {
03972          *p++ = ',';
03973          --rem;
03974       }
03975       *p++ = '<';
03976       ast_copy_string(p, route->hop, rem);  p += n;
03977       *p++ = '>';
03978       rem -= (n+2);
03979       route = route->next;
03980    }
03981    *p = '\0';
03982    add_header(req, "Route", r);
03983 }

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

add_sdp: Add Session Description Protocol message ---

Definition at line 4413 of file chan_sip.c.

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

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

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

11958 {
11959    struct domain *d;
11960 
11961    if (ast_strlen_zero(domain)) {
11962       ast_log(LOG_WARNING, "Zero length domain.\n");
11963       return 1;
11964    }
11965 
11966    d = calloc(1, sizeof(*d));
11967    if (!d) {
11968       ast_log(LOG_ERROR, "Allocation of domain structure failed, Out of memory\n");
11969       return 0;
11970    }
11971 
11972    ast_copy_string(d->domain, domain, sizeof(d->domain));
11973 
11974    if (!ast_strlen_zero(context))
11975       ast_copy_string(d->context, context, sizeof(d->context));
11976 
11977    d->mode = mode;
11978 
11979    AST_LIST_LOCK(&domain_list);
11980    AST_LIST_INSERT_TAIL(&domain_list, d, list);
11981    AST_LIST_UNLOCK(&domain_list);
11982 
11983    if (sipdebug)  
11984       ast_log(LOG_DEBUG, "Added local SIP domain '%s'\n", domain);
11985 
11986    return 1;
11987 }

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

add_text: Add text body to SIP message ---

Definition at line 4330 of file chan_sip.c.

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

Referenced by transmit_message_with_text().

04331 {
04332    /* XXX Convert \n's to \r\n's XXX */
04333    add_header(req, "Content-Type", "text/plain");
04334    add_header_contentLength(req, strlen(text));
04335    add_line(req, text);
04336    return 0;
04337 }

static int add_vidupdate ( struct sip_request req  )  [static]

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

Definition at line 4354 of file chan_sip.c.

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

Referenced by transmit_info_with_vidupdate().

04355 {
04356    const char *xml_is_a_huge_waste_of_space =
04357       "<?xml version=\"1.0\" encoding=\"utf-8\" ?>\r\n"
04358       " <media_control>\r\n"
04359       "  <vc_primitive>\r\n"
04360       "   <to_encoder>\r\n"
04361       "    <picture_fast_update>\r\n"
04362       "    </picture_fast_update>\r\n"
04363       "   </to_encoder>\r\n"
04364       "  </vc_primitive>\r\n"
04365       " </media_control>\r\n";
04366    add_header(req, "Content-Type", "application/media_control+xml");
04367    add_header_contentLength(req, strlen(xml_is_a_huge_waste_of_space));
04368    add_line(req, xml_is_a_huge_waste_of_space);
04369    return 0;
04370 }

static void append_date ( struct sip_request req  )  [static]

append_date: Append date to SIP message ---

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

04275 {
04276    char tmpdat[256];
04277    struct tm tm;
04278    time_t t;
04279 
04280    time(&t);
04281    gmtime_r(&t, &tm);
04282    strftime(tmpdat, sizeof(tmpdat), "%a, %d %b %Y %T GMT", &tm);
04283    add_header(req, "Date", tmpdat);
04284 }

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

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

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

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

Referenced by attempt_transfer().

10301 {
10302    if (chan && chan->_state == AST_STATE_UP) {
10303       if (chan->generatordata)
10304          ast_deactivate_generator(chan);
10305    }
10306 }

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

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

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

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

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

attempt_transfer: Attempt transfer of SIP call ---

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

10310 {
10311    int res = 0;
10312    struct ast_channel 
10313       *chana = NULL,
10314       *chanb = NULL,
10315       *bridgea = NULL,
10316       *bridgeb = NULL,
10317       *peera = NULL,
10318       *peerb = NULL,
10319       *peerc = NULL,
10320       *peerd = NULL;
10321 
10322    if (!p1->owner || !p2->owner) {
10323       ast_log(LOG_WARNING, "Transfer attempted without dual ownership?\n");
10324       return -1;
10325    }
10326    chana = p1->owner;
10327    chanb = p2->owner;
10328    bridgea = ast_bridged_channel(chana);
10329    bridgeb = ast_bridged_channel(chanb);
10330    
10331    if (bridgea) {
10332       peera = chana;
10333       peerb = chanb;
10334       peerc = bridgea;
10335       peerd = bridgeb;
10336    } else if (bridgeb) {
10337       peera = chanb;
10338       peerb = chana;
10339       peerc = bridgeb;
10340       peerd = bridgea;
10341    }
10342    
10343    if (peera && peerb && peerc && (peerb != peerc)) {
10344       ast_quiet_chan(peera);
10345       ast_quiet_chan(peerb);
10346       ast_quiet_chan(peerc);
10347       ast_quiet_chan(peerd);
10348 
10349       if (peera->cdr && peerb->cdr) {
10350          peerb->cdr = ast_cdr_append(peerb->cdr, peera->cdr);
10351       } else if (peera->cdr) {
10352          peerb->cdr = peera->cdr;
10353       }
10354       peera->cdr = NULL;
10355 
10356       if (peerb->cdr && peerc->cdr) {
10357          peerb->cdr = ast_cdr_append(peerb->cdr, peerc->cdr);
10358       } else if (peerc->cdr) {
10359          peerb->cdr = peerc->cdr;
10360       }
10361       peerc->cdr = NULL;
10362       
10363       if (ast_channel_masquerade(peerb, peerc)) {
10364          ast_log(LOG_WARNING, "Failed to masquerade %s into %s\n", peerb->name, peerc->name);
10365          res = -1;
10366       }
10367       return res;
10368    } else {
10369       ast_log(LOG_NOTICE, "Transfer attempted with no appropriate bridged calls to transfer\n");
10370       if (chana)
10371          ast_softhangup_nolock(chana, AST_SOFTHANGUP_DEV);
10372       if (chanb)
10373          ast_softhangup_nolock(chanb, AST_SOFTHANGUP_DEV);
10374       return -1;
10375    }
10376    return 0;
10377 }

static int auto_congest ( void *  nothing  )  [static]

auto_congest: Scheduled congestion on a call ---

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

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

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

build_callid: Build SIP CALLID header ---

Definition at line 3054 of file chan_sip.c.

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

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

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

static void build_contact ( struct sip_pvt p  )  [static]

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

Definition at line 4730 of file chan_sip.c.

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

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

04731 {
04732    char iabuf[INET_ADDRSTRLEN];
04733 
04734    /* Construct Contact: header */
04735    if (ourport != 5060) /* Needs to be 5060, according to the RFC */
04736       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);
04737    else
04738       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));
04739 }

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

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

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

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

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

09136 {
09137    char a1[256];
09138    char a2[256];
09139    char a1_hash[256];
09140    char a2_hash[256];
09141    char resp[256];
09142    char resp_hash[256];
09143    char uri[256];
09144    char cnonce[80];
09145    char iabuf[INET_ADDRSTRLEN];
09146    char *username;
09147    char *secret;
09148    char *md5secret;
09149    struct sip_auth *auth = (struct sip_auth *) NULL;  /* Realm authentication */
09150 
09151    if (!ast_strlen_zero(p->domain))
09152       ast_copy_string(uri, p->domain, sizeof(uri));
09153    else if (!ast_strlen_zero(p->uri))
09154       ast_copy_string(uri, p->uri, sizeof(uri));
09155    else
09156       snprintf(uri, sizeof(uri), "sip:%s@%s",p->username, ast_inet_ntoa(iabuf, sizeof(iabuf), p->sa.sin_addr));
09157 
09158    snprintf(cnonce, sizeof(cnonce), "%08x", thread_safe_rand());
09159 
09160    /* Check if we have separate auth credentials */
09161    if ((auth = find_realm_authentication(authl, p->realm))) {
09162       username = auth->username;
09163       secret = auth->secret;
09164       md5secret = auth->md5secret;
09165       if (sipdebug)
09166          ast_log(LOG_DEBUG,"Using realm %s authentication for call %s\n", p->realm, p->callid);
09167    } else {
09168       /* No authentication, use peer or register= config */
09169       username = p->authname;
09170       secret =  p->peersecret;
09171       md5secret = p->peermd5secret;
09172    }
09173    if (ast_strlen_zero(username))   /* We have no authentication */
09174       return -1;
09175  
09176 
09177    /* Calculate SIP digest response */
09178    snprintf(a1,sizeof(a1),"%s:%s:%s", username, p->realm, secret);
09179    snprintf(a2,sizeof(a2),"%s:%s", sip_methods[method].text, uri);
09180    if (!ast_strlen_zero(md5secret))
09181       ast_copy_string(a1_hash, md5secret, sizeof(a1_hash));
09182    else
09183       ast_md5_hash(a1_hash,a1);
09184    ast_md5_hash(a2_hash,a2);
09185 
09186    p->noncecount++;
09187    if (!ast_strlen_zero(p->qop))
09188       snprintf(resp,sizeof(resp),"%s:%s:%08x:%s:%s:%s", a1_hash, p->nonce, p->noncecount, cnonce, "auth", a2_hash);
09189    else
09190       snprintf(resp,sizeof(resp),"%s:%s:%s", a1_hash, p->nonce, a2_hash);
09191    ast_md5_hash(resp_hash, resp);
09192    /* XXX We hard code our qop to "auth" for now.  XXX */
09193    if (!ast_strlen_zero(p->qop))
09194       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);
09195    else
09196       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);
09197 
09198    return 0;
09199 }

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

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

Referenced by handle_request_invite(), and handle_response_invite().

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

static void build_rpid ( struct sip_pvt p  )  [static]

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

Definition at line 4742 of file chan_sip.c.

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

Referenced by initreqprep().

04743 {
04744    int send_pres_tags = 1;
04745    const char *privacy=NULL;
04746    const char *screen=NULL;
04747    char buf[256];
04748    const char *clid = default_callerid;
04749    const char *clin = NULL;
04750    char iabuf[INET_ADDRSTRLEN];
04751    const char *fromdomain;
04752 
04753    if (p->rpid || p->rpid_from)
04754       return;
04755 
04756    if (p->owner && p->owner->cid.cid_num)
04757       clid = p->owner->cid.cid_num;
04758    if (p->owner && p->owner->cid.cid_name)
04759       clin = p->owner->cid.cid_name;
04760    if (ast_strlen_zero(clin))
04761       clin = clid;
04762 
04763    switch (p->callingpres) {
04764    case AST_PRES_ALLOWED_USER_NUMBER_NOT_SCREENED:
04765       privacy = "off";
04766       screen = "no";
04767       break;
04768    case AST_PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN:
04769       privacy = "off";
04770       screen = "pass";
04771       break;
04772    case AST_PRES_ALLOWED_USER_NUMBER_FAILED_SCREEN:
04773       privacy = "off";
04774       screen = "fail";
04775       break;
04776    case AST_PRES_ALLOWED_NETWORK_NUMBER:
04777       privacy = "off";
04778       screen = "yes";
04779       break;
04780    case AST_PRES_PROHIB_USER_NUMBER_NOT_SCREENED:
04781       privacy = "full";
04782       screen = "no";
04783       break;
04784    case AST_PRES_PROHIB_USER_NUMBER_PASSED_SCREEN:
04785       privacy = "full";
04786       screen = "pass";
04787       break;
04788    case AST_PRES_PROHIB_USER_NUMBER_FAILED_SCREEN:
04789       privacy = "full";
04790       screen = "fail";
04791       break;
04792    case AST_PRES_PROHIB_NETWORK_NUMBER:
04793       privacy = "full";
04794       screen = "pass";
04795       break;
04796    case AST_PRES_NUMBER_NOT_AVAILABLE:
04797       send_pres_tags = 0;
04798       break;
04799    default:
04800       ast_log(LOG_WARNING, "Unsupported callingpres (%d)\n", p->callingpres);
04801       if ((p->callingpres & AST_PRES_RESTRICTION) != AST_PRES_ALLOWED)
04802          privacy = "full";
04803       else
04804          privacy = "off";
04805       screen = "no";
04806       break;
04807    }
04808    
04809    fromdomain = ast_strlen_zero(p->fromdomain) ? ast_inet_ntoa(iabuf, sizeof(iabuf), p->ourip) : p->fromdomain;
04810 
04811    snprintf(buf, sizeof(buf), "\"%s\" <sip:%s@%s>", clin, clid, fromdomain);
04812    if (send_pres_tags)
04813       snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), ";privacy=%s;screen=%s", privacy, screen);
04814    p->rpid = strdup(buf);
04815 
04816    snprintf(buf, sizeof(buf), "\"%s\" <sip:%s@%s>;tag=%s", clin,
04817        ast_strlen_zero(p->fromuser) ? clid : p->fromuser,
04818        fromdomain, p->tag);
04819    p->rpid_from = strdup(buf);
04820 }

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

12122 {
12123    struct sip_user *user;
12124    int format;
12125    struct ast_ha *oldha = NULL;
12126    char *varname = NULL, *varval = NULL;
12127    struct ast_variable *tmpvar = NULL;
12128    struct ast_flags userflags = {(0)};
12129    struct ast_flags mask = {(0)};
12130 
12131 
12132    user = (struct sip_user *)malloc(sizeof(struct sip_user));
12133    if (!user) {
12134       return NULL;
12135    }
12136    memset(user, 0, sizeof(struct sip_user));
12137    suserobjs++;
12138    ASTOBJ_INIT(user);
12139    ast_copy_string(user->name, name, sizeof(user->name));
12140    oldha = user->ha;
12141    user->ha = NULL;
12142    ast_copy_flags(user, &global_flags, SIP_FLAGS_TO_COPY);
12143    user->capability = global_capability;
12144    user->prefs = prefs;
12145    /* set default context */
12146    strcpy(user->context, default_context);
12147    strcpy(user->language, default_language);
12148    strcpy(user->musicclass, global_musicclass);
12149    while(v) {
12150       if (handle_common_options(&userflags, &mask, v)) {
12151          v = v->next;
12152          continue;
12153       }
12154 
12155       if (!strcasecmp(v->name, "context")) {
12156          ast_copy_string(user->context, v->value, sizeof(user->context));
12157       } else if (!strcasecmp(v->name, "subscribecontext")) {
12158          ast_copy_string(user->subscribecontext, v->value, sizeof(user->subscribecontext));
12159       } else if (!strcasecmp(v->name, "setvar")) {
12160          varname = ast_strdupa(v->value);
12161          if (varname && (varval = strchr(varname,'='))) {
12162             *varval = '\0';
12163             varval++;
12164             if ((tmpvar = ast_variable_new(varname, varval))) {
12165                tmpvar->next = user->chanvars;
12166                user->chanvars = tmpvar;
12167             }
12168          }
12169       } else if (!strcasecmp(v->name, "permit") ||
12170                !strcasecmp(v->name, "deny")) {
12171          user->ha = ast_append_ha(v->name, v->value, user->ha);
12172       } else if (!strcasecmp(v->name, "secret")) {
12173          ast_copy_string(user->secret, v->value, sizeof(user->secret)); 
12174       } else if (!strcasecmp(v->name, "md5secret")) {
12175          ast_copy_string(user->md5secret, v->value, sizeof(user->md5secret));
12176       } else if (!strcasecmp(v->name, "callerid")) {
12177          ast_callerid_split(v->value, user->cid_name, sizeof(user->cid_name), user->cid_num, sizeof(user->cid_num));
12178       } else if (!strcasecmp(v->name, "callgroup")) {
12179          user->callgroup = ast_get_group(v->value);
12180       } else if (!strcasecmp(v->name, "pickupgroup")) {
12181          user->pickupgroup = ast_get_group(v->value);
12182       } else if (!strcasecmp(v->name, "language")) {
12183          ast_copy_string(user->language, v->value, sizeof(user->language));
12184       } else if (!strcasecmp(v->name, "musicclass") || !strcasecmp(v->name, "musiconhold")) {
12185          ast_copy_string(user->musicclass, v->value, sizeof(user->musicclass));
12186       } else if (!strcasecmp(v->name, "accountcode")) {
12187          ast_copy_string(user->accountcode, v->value, sizeof(user->accountcode));
12188       } else if (!strcasecmp(v->name, "call-limit") || !strcasecmp(v->name, "incominglimit")) {
12189          user->call_limit = atoi(v->value);
12190          if (user->call_limit < 0)
12191             user->call_limit = 0;
12192       } else if (!strcasecmp(v->name, "amaflags")) {
12193          format = ast_cdr_amaflags2int(v->value);
12194          if (format < 0) {
12195             ast_log(LOG_WARNING, "Invalid AMA Flags: %s at line %d\n", v->value, v->lineno);
12196          } else {
12197             user->amaflags = format;
12198          }
12199       } else if (!strcasecmp(v->name, "allow")) {
12200          ast_parse_allow_disallow(&user->prefs, &user->capability, v->value, 1);
12201       } else if (!strcasecmp(v->name, "disallow")) {
12202          ast_parse_allow_disallow(&user->prefs, &user->capability, v->value, 0);
12203       } else if (!strcasecmp(v->name, "callingpres")) {
12204          user->callingpres = ast_parse_caller_presentation(v->value);
12205          if (user->callingpres == -1)
12206             user->callingpres = atoi(v->value);
12207       }
12208       /*else if (strcasecmp(v->name,"type"))
12209        * ast_log(LOG_WARNING, "Ignoring %s\n", v->name);
12210        */
12211       v = v->next;
12212    }
12213    ast_copy_flags(user, &userflags, mask.flags);
12214    ast_free_ha(oldha);
12215    return user;
12216 }

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

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

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

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

Referenced by handle_request_subscribe().

06432 {
06433    struct sip_pvt *p = data;
06434 
06435    switch(state) {
06436    case AST_EXTENSION_DEACTIVATED:  /* Retry after a while */
06437    case AST_EXTENSION_REMOVED:   /* Extension is gone */
06438       if (p->autokillid > -1)
06439          sip_cancel_destroy(p);  /* Remove subscription expiry for renewals */
06440       sip_scheddestroy(p, 15000);   /* Delete subscription in 15 secs */
06441       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);
06442       p->stateid = -1;
06443       p->subscribed = NONE;
06444       append_history(p, "Subscribestatus", state == AST_EXTENSION_REMOVED ? "HintRemoved" : "Deactivated");
06445       break;
06446    default: /* Tell user */
06447       p->laststate = state;
06448       break;
06449    }
06450    transmit_state_notify(p, state, 1, 1);
06451 
06452    if (option_debug > 1)
06453       ast_verbose(VERBOSE_PREFIX_1 "Extension Changed %s new state %s for Notify User %s\n", exten, ast_extension_state2str(state), p->username);
06454    return 0;
06455 }

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

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

static void check_pendings ( struct sip_pvt p  )  [static]

check_pendings: Check pending actions on SIP call ---

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

09574 {
09575    if (ast_test_flag(p, SIP_PENDINGBYE)) {
09576       /* if we can't BYE, then this is really a pending CANCEL */
09577       if (!ast_test_flag(p, SIP_CAN_BYE))
09578          transmit_request_with_auth(p, SIP_CANCEL, p->ocseq, 1, 0);
09579          /* Actually don't destroy us yet, wait for the 487 on our original 
09580             INVITE, but do set an autodestruct just in case we never get it. */
09581       else 
09582          transmit_request_with_auth(p, SIP_BYE, 0, 1, 1);
09583       ast_clear_flag(p, SIP_PENDINGBYE);  
09584       sip_scheddestroy(p, 32000);
09585    } else if (ast_test_flag(p, SIP_NEEDREINVITE)) {
09586       ast_log(LOG_DEBUG, "Sending pending reinvite on '%s'\n", p->callid);
09587       /* Didn't get to reinvite yet, so do it now */
09588       transmit_reinvite_with_sdp(p);
09589       ast_clear_flag(p, SIP_NEEDREINVITE);   
09590    }
09591 }

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

11991 {
11992    struct domain *d;
11993    int result = 0;
11994 
11995    AST_LIST_LOCK(&domain_list);
11996    AST_LIST_TRAVERSE(&domain_list, d, list) {
11997       if (strcasecmp(d->domain, domain))
11998          continue;
11999 
12000       if (len && !ast_strlen_zero(d->context))
12001          ast_copy_string(context, d->context, len);
12002       
12003       result = 1;
12004       break;
12005    }
12006    AST_LIST_UNLOCK(&domain_list);
12007 
12008    return result;
12009 }

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

References check_user_full().

Referenced by handle_request_invite().

07358 {
07359    return check_user_full(p, req, sipmethod, uri, reliable, sin, ignore, NULL, 0);
07360 }

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

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

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

06966 {
06967    char via[256];
06968    char iabuf[INET_ADDRSTRLEN];
06969    char *c, *pt;
06970    struct hostent *hp;
06971    struct ast_hostent ahp;
06972 
06973    ast_copy_string(via, get_header(req, "Via"), sizeof(via));
06974 
06975    /* Check for rport */
06976    c = strstr(via, ";rport");
06977    if (c && (c[6] != '=')) /* rport query, not answer */
06978       ast_set_flag(p, SIP_NAT_ROUTE);
06979 
06980    c = strchr(via, ';');
06981    if (c) 
06982       *c = '\0';
06983 
06984    c = strchr(via, ' ');
06985    if (c) {
06986       *c = '\0';
06987       c = ast_skip_blanks(c+1);
06988       if (strcasecmp(via, "SIP/2.0/UDP")) {
06989          ast_log(LOG_WARNING, "Don't know how to respond via '%s'\n", via);
06990          return -1;
06991       }
06992       pt = strchr(c, ':');
06993       if (pt)
06994          *pt++ = '\0';  /* remember port pointer */
06995       hp = ast_gethostbyname(c, &ahp);
06996       if (!hp) {
06997          ast_log(LOG_WARNING, "'%s' is not a valid host\n", c);
06998          return -1;
06999       }
07000       memset(&p->sa, 0, sizeof(p->sa));
07001       p->sa.sin_family = AF_INET;
07002       memcpy(&p->sa.sin_addr, hp->h_addr, sizeof(p->sa.sin_addr));
07003       p->sa.sin_port = htons(pt ? atoi(pt) : DEFAULT_SIP_PORT);
07004 
07005       if (sip_debug_test_pvt(p)) {
07006          c = (ast_test_flag(p, SIP_NAT) & SIP_NAT_ROUTE) ? "NAT" : "non-NAT";
07007          ast_verbose("Sending to %s : %d (%s)\n", ast_inet_ntoa(iabuf, sizeof(iabuf), p->sa.sin_addr), ntohs(p->sa.sin_port), c);
07008       }
07009    }
07010    return 0;
07011 }

static int clear_realm_authentication ( struct sip_auth authlist  )  [static]

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

Definition at line 12091 of file chan_sip.c.

References free, and sip_auth::next.

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

12092 {
12093    struct sip_auth *a = authlist;
12094    struct sip_auth *b;
12095 
12096    while (a) {
12097       b = a;
12098       a = a->next;
12099       free(b);
12100    }
12101 
12102    return 1;
12103 }

static void clear_sip_domains ( void   )  [static]

clear_sip_domains: Clear our domain list (at reload)

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

12013 {
12014    struct domain *d;
12015 
12016    AST_LIST_LOCK(&domain_list);
12017    while ((d = AST_LIST_REMOVE_HEAD(&domain_list, list)))
12018       free(d);
12019    AST_LIST_UNLOCK(&domain_list);
12020 }

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

References complete_sip_peer().

08518 {
08519    if (pos == 3)
08520       return complete_sip_peer(word, state, 0);
08521 
08522    return NULL;
08523 }

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

complete_sip_peer: Do completion on peer name ---

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

08489 {
08490    char *result = NULL;
08491    int wordlen = strlen(word);
08492    int which = 0;
08493 
08494    ASTOBJ_CONTAINER_TRAVERSE(&peerl, !result, do {
08495       /* locking of the object is not required because only the name and flags are being compared */
08496       if (!strncasecmp(word, iterator->name, wordlen)) {
08497          if (flags2 && !ast_test_flag((&iterator->flags_page2), flags2))
08498             continue;
08499          if (++which > state) {
08500             result = strdup(iterator->name);
08501          }
08502       }
08503    } while(0) );
08504    return result;
08505 }

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

References complete_sip_peer(), and SIP_PAGE2_RTCACHEFRIENDS.

08589 {
08590    if (pos == 4)
08591       return complete_sip_peer(word, state, SIP_PAGE2_RTCACHEFRIENDS);
08592    return NULL;
08593 }

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

References complete_sip_user(), and SIP_PAGE2_RTCACHEFRIENDS.

08597 {
08598    if (pos == 4)
08599       return complete_sip_user(word, state, SIP_PAGE2_RTCACHEFRIENDS);
08600 
08601    return NULL;
08602 }

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

References complete_sip_peer().

08509 {
08510    if (pos == 3)
08511       return complete_sip_peer(word, state, 0);
08512 
08513    return NULL;
08514 }

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

References complete_sip_user().

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

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

complete_sip_user: Do completion on user name ---

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

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

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

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

08467 {
08468    int which=0;
08469    struct sip_pvt *cur;
08470    char *c = NULL;
08471 
08472    ast_mutex_lock(&iflock);
08473    cur = iflist;
08474    while(cur) {
08475       if (!strncasecmp(word, cur->callid, strlen(word))) {
08476          if (++which > state) {
08477             c = strdup(cur->callid);
08478             break;
08479          }
08480       }
08481       cur = cur->next;
08482    }
08483    ast_mutex_unlock(&iflock);
08484    return c;
08485 }

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

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

Definition at line 8555 of file chan_sip.c.

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

08556 {
08557    char *c = NULL;
08558 
08559    if (pos == 2) {
08560       int which = 0;
08561       char *cat;
08562 
08563       /* do completion for notify type */
08564 
08565       if (!notify_types)
08566          return NULL;
08567       
08568       cat = ast_category_browse(notify_types, NULL);
08569       while(cat) {
08570          if (!strncasecmp(word, cat, strlen(word))) {
08571             if (++which > state) {
08572                c = strdup(cat);
08573                break;
08574             }
08575          }
08576          cat = ast_category_browse(notify_types, cat);
08577       }
08578       return c;
08579    }
08580 
08581    if (pos > 2)
08582       return complete_sip_peer(word, state, 0);
08583 
08584    return NULL;
08585 }

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

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

Referenced by respprep().

03879 {
03880    char *tmp;
03881    int start = 0;
03882    int copied = 0;
03883    for (;;) {
03884       tmp = __get_header(orig, field, &start);
03885       if (!ast_strlen_zero(tmp)) {
03886          /* Add what we're responding to */
03887          add_header(req, field, tmp);
03888          copied++;
03889       } else
03890          break;
03891    }
03892    return copied ? 0 : -1;
03893 }

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

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

Referenced by reqprep(), and respprep().

03866 {
03867    char *tmp;
03868    tmp = get_header(orig, field);
03869    if (!ast_strlen_zero(tmp)) {
03870       /* Add what we're responding to */
03871       return add_header(req, field, tmp);
03872    }
03873    ast_log(LOG_NOTICE, "No field '%s' present to copy\n", field);
03874    return -1;
03875 }

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

04604 {
04605    long offset;
04606    int x;
04607    offset = ((void *)dst) - ((void *)src);
04608    /* First copy stuff */
04609    memcpy(dst, src, sizeof(*dst));
04610    /* Now fix pointer arithmetic */
04611    for (x=0; x < src->headers; x++)
04612       dst->header[x] += offset;
04613    for (x=0; x < src->lines; x++)
04614       dst->line[x] += offset;
04615 }

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

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

Referenced by respprep().

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

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

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

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

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

char* description ( void   ) 

Provides a description of the module.

Returns:
a short description of your module

Definition at line 13538 of file chan_sip.c.

References desc.

13539 {
13540    return (char *) desc;
13541 }

static void destroy_association ( struct sip_peer peer  )  [static]

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

05726 {
05727    if (!ast_test_flag((&global_flags_page2), SIP_PAGE2_IGNOREREGEXPIRE)) {
05728       if (ast_test_flag(&(peer->flags_page2), SIP_PAGE2_RT_FROMCONTACT)) {
05729          ast_update_realtime("sippeers", "name", peer->name, "fullcontact", "", "ipaddr", "", "port", "", "regseconds", "0", "username", "", NULL);
05730       } else {
05731          ast_db_del("SIP/Registry", peer->name);
05732       }
05733    }
05734 }

static int determine_firstline_parts ( struct sip_request req  )  [static]

determine_firstline_parts: parse first line of incoming SIP request

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

04639 {
04640    char *e, *cmd;
04641    int len;
04642   
04643    cmd = ast_skip_blanks(req->header[0]);
04644    if (!*cmd)
04645       return -1;
04646    req->rlPart1 = cmd;
04647    e = ast_skip_nonblanks(cmd);
04648    /* Get the command */
04649    if (*e)
04650       *e++ = '\0';
04651    e = ast_skip_blanks(e);
04652    if ( !*e )
04653       return -1;
04654 
04655    if ( !strcasecmp(cmd, "SIP/2.0") ) {
04656       /* We have a response */
04657       req->rlPart2 = e;
04658       len = strlen( req->rlPart2 );
04659       if ( len < 2 ) { 
04660          return -1;
04661       }
04662       ast_trim_blanks(e);
04663    } else {
04664       /* We have a request */
04665       if ( *e == '<' ) { 
04666          e++;
04667          if ( !*e ) { 
04668             return -1; 
04669          }  
04670       }
04671       req->rlPart2 = e; /* URI */
04672       if ( ( e= strrchr( req->rlPart2, 'S' ) ) == NULL ) {
04673          return -1;
04674       }
04675       /* XXX maybe trim_blanks() ? */
04676       while( isspace( *(--e) ) ) {}
04677       if ( *e == '>' ) {
04678          *e = '\0';
04679       } else {
04680          *(++e)= '\0';
04681       }
04682    }
04683    return 1;
04684 }

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

do_monitor: The SIP monitoring thread ---

Definition at line 11442 of file chan_sip.c.

References __sip_destroy(), ast_channel::_state, ast_io_add(), AST_IO_IN, ast_io_wait(), ast_log(), ast_mutex_lock(), ast_mutex_trylock(), ast_mutex_unlock(), ast_rtp_get_peer(), ast_rtp_sendcng(), ast_sched_runq(), ast_sched_wait(), AST_SOFTHANGUP_DEV, ast_softhangup_nolock(), AST_STATE_UP, ast_strlen_zero(), ast_test_flag, ast_verbose(), ASTOBJ_CONTAINER_TRAVERSE, ASTOBJ_REF, ASTOBJ_UNLOCK, ASTOBJ_UNREF, ASTOBJ_WRLOCK, global_mwitime, iflist, 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_destroy_peer(), sip_do_reload(), SIP_NEEDDESTROY, sip_reloading, sip_send_mwi_to_peer(), sipsock, sipsock_read(), t, and VERBOSE_PREFIX_1.

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

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

09029 {
09030    char digest[1024];
09031 
09032    if (!p->options) {
09033       p->options = calloc(1, sizeof(*p->options));
09034       if (!p->options) {
09035          ast_log(LOG_ERROR, "Out of memory\n");
09036          return -2;
09037       }
09038    }
09039 
09040    p->authtries++;
09041    if (option_debug > 1)
09042       ast_log(LOG_DEBUG, "Auth attempt %d on %s\n", p->authtries, sip_methods[sipmethod].text);
09043    memset(digest, 0, sizeof(digest));
09044    if (reply_digest(p, req, header, sipmethod, digest, sizeof(digest) )) {
09045       /* No way to authenticate */
09046       return -1;
09047    }
09048    /* Now we have a reply digest */
09049    p->options->auth = digest;
09050    p->options->authheader = respheader;
09051    return transmit_invite(p, sipmethod, sipmethod == SIP_INVITE, init); 
09052 }

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

09005 {
09006    char digest[1024];
09007    p->authtries++;
09008    memset(digest,0,sizeof(digest));
09009    if (reply_digest(p, req, header, SIP_REGISTER, digest, sizeof(digest))) {
09010       /* There's nothing to use for authentication */
09011       /* No digest challenge in request */
09012       if (sip_debug_test_pvt(p) && p->registry)
09013          ast_verbose("No authentication challenge, sending blank registration to domain/host name %s\n", p->registry->hostname);
09014          /* No old challenge */
09015       return -1;
09016    }
09017    if (recordhistory) {
09018       char tmp[80];
09019       snprintf(tmp, sizeof(tmp), "Try: %d", p->authtries);
09020       append_history(p, "RegistryAuth", tmp);
09021    }
09022    if (sip_debug_test_pvt(p) && p->registry)
09023       ast_verbose("Responding to challenge, registration to domain/host name %s\n", p->registry->hostname);
09024    return transmit_register(p->registry, SIP_REGISTER, digest, respheader); 
09025 }

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

Definition at line 7947 of file chan_sip.c.

References SIP_DOMAIN_AUTO, and SIP_DOMAIN_CONFIG.

Referenced by sip_show_domains().

07948 {
07949    switch (mode) {
07950    case SIP_DOMAIN_AUTO:
07951       return "[Automatic]";
07952    case SIP_DOMAIN_CONFIG:
07953       return "[Configured]";
07954    }
07955 
07956    return "";
07957 }

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

dtmfmode2str: Convert DTMF mode to printable string ---

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

07756 {
07757    switch (mode) {
07758    case SIP_DTMF_RFC2833:
07759       return "rfc2833";
07760    case SIP_DTMF_INFO:
07761       return "info";
07762    case SIP_DTMF_INBAND:
07763       return "inband";
07764    case SIP_DTMF_AUTO:
07765       return "auto";
07766    }
07767    return "<error>";
07768 }

static int expire_register ( void *  data  )  [static]

expire_register: Expire registration of SIP peer ---

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

05738 {
05739    struct sip_peer *peer = data;
05740    
05741    if (!peer)     /* Hmmm. We have no peer. Weird. */
05742       return 0;
05743 
05744    memset(&peer->addr, 0, sizeof(peer->addr));
05745 
05746    destroy_association(peer);
05747    
05748    manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: SIP/%s\r\nPeerStatus: Unregistered\r\nCause: Expired\r\n", peer->name);
05749    register_peer_exten(peer, 0); /* Remove regexten */
05750    peer->expire = -1;
05751    ast_device_state_changed("SIP/%s", peer->name);
05752 
05753    /* Do we need to release this peer from memory? 
05754       Only for realtime peers and autocreated peers
05755    */
05756    if (ast_test_flag(peer, SIP_SELFDESTRUCT) || ast_test_flag((&peer->flags_page2), SIP_PAGE2_RTAUTOCLEAR)) {
05757       peer = ASTOBJ_CONTAINER_UNLINK(&peerl, peer);   /* Remove from peer list */
05758       ASTOBJ_UNREF(peer, sip_destroy_peer);
05759    }
05760 
05761    return 0;
05762 }

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

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

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

04717 {
04718    char stripped[256];
04719    char *c, *n;
04720    ast_copy_string(stripped, get_header(req, "Contact"), sizeof(stripped));
04721    c = get_in_brackets(stripped);
04722    n = strchr(c, ';');
04723    if (n)
04724       *n = '\0';
04725    if (!ast_strlen_zero(c))
04726       ast_copy_string(p->uri, c, sizeof(p->uri));
04727 }

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

Definition at line 2940 of file chan_sip.c.

References aliases.

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

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 3172 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, sip_alloc(), sip_methods, SIP_PKT_WITH_TOTAG, SIP_REGISTER, SIP_RESPONSE, sip_pvt::tag, and sip_pvt::theirtag.

Referenced by sipsock_read().

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

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

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

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

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

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

Referenced by build_reply_digest().

12107 {
12108    struct sip_auth *a = authlist;   /* First entry in auth list */
12109 
12110    while (a) {
12111       if (!strcasecmp(a->realm, realm)){
12112          break;
12113       }
12114       a = a->next;
12115    }
12116    
12117    return a;
12118 }

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

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

int find_sip_method ( char *  msg  ) 

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

Definition at line 986 of file chan_sip.c.

References ast_strlen_zero(), sip_methods, and text.

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

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

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

find_subscription_type: Find subscription type in array

Definition at line 8391 of file chan_sip.c.

References subscription_types, and type.

Referenced by transmit_state_notify().

08391                                                                                                 {
08392    int i;
08393 
08394    for (i = 1; (i < (sizeof(subscription_types) / sizeof(subscription_types[0]))); i++) {
08395       if (subscription_types[i].type == subtype) {
08396          return &subscription_types[i];
08397       }
08398    }
08399    return &subscription_types[0];
08400 }

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

References ASTOBJ_CONTAINER_FIND, realtime_user(), and userl.

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

static void free_old_route ( struct sip_route route  )  [static]

free_old_route: Remove route from route list ---

Definition at line 6064 of file chan_sip.c.

References free, and sip_route::next.

Referenced by __sip_destroy(), and build_route().

06065 {
06066    struct sip_route *next;
06067    while (route) {
06068       next = route->next;
06069       free(route);
06070       route = next;
06071    }
06072 }

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

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

09346 {
09347    if (ast_strlen_zero(data)) {
09348       ast_log(LOG_WARNING, "CHECKSIPDOMAIN requires an argument - A domain name\n");
09349       return buf;
09350    }
09351    if (check_sip_domain(data, NULL, 0))
09352       ast_copy_string(buf, data, len);
09353    else
09354       buf[0] = '\0';
09355    return buf;
09356 }

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

09299 {
09300    struct sip_pvt *p;
09301    char *content;
09302    
09303    if (!data) {
09304       ast_log(LOG_WARNING, "This function requires a header name.\n");
09305       return NULL;
09306    }
09307 
09308    ast_mutex_lock(&chan->lock);
09309    if (chan->type != channeltype) {
09310       ast_log(LOG_WARNING, "This function can only be used on SIP channels.\n");
09311       ast_mutex_unlock(&chan->lock);
09312       return NULL;
09313    }
09314 
09315    p = chan->tech_pvt;
09316 
09317    /* If there is no private structure, this channel is no longer alive */
09318    if (!p) {
09319       ast_mutex_unlock(&chan->lock);
09320       return NULL;
09321    }
09322 
09323    content = get_header(&p->initreq, data);
09324 
09325    if (ast_strlen_zero(content)) {
09326       ast_mutex_unlock(&chan->lock);
09327       return NULL;
09328    }
09329 
09330    ast_copy_string(buf, content, len);
09331    ast_mutex_unlock(&chan->lock);
09332 
09333    return buf;
09334 }

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

09473 {
09474    struct sip_pvt *p;
09475    char iabuf[INET_ADDRSTRLEN];
09476 
09477    *buf = 0;
09478    
09479    if (!data) {
09480       ast_log(LOG_WARNING, "This function requires a parameter name.\n");
09481       return NULL;
09482    }
09483 
09484    ast_mutex_lock(&chan->lock);
09485    if (chan->type != channeltype) {
09486       ast_log(LOG_WARNING, "This function can only be used on SIP channels.\n");
09487       ast_mutex_unlock(&chan->lock);
09488       return NULL;
09489    }
09490 
09491 /*    ast_verbose("function_sipchaninfo_read: %s\n", data); */
09492    p = chan->tech_pvt;
09493 
09494    /* If there is no private structure, this channel is no longer alive */
09495    if (!p) {
09496       ast_mutex_unlock(&chan->lock);
09497       return NULL;
09498    }
09499 
09500    if (!strcasecmp(data, "peerip")) {
09501       ast_copy_string(buf, p->sa.sin_addr.s_addr ? ast_inet_ntoa(iabuf, sizeof(iabuf), p->sa.sin_addr) : "", len);
09502    } else  if (!strcasecmp(data, "recvip")) {
09503       ast_copy_string(buf, p->recv.sin_addr.s_addr ? ast_inet_ntoa(iabuf, sizeof(iabuf), p->recv.sin_addr) : "", len);
09504    } else  if (!strcasecmp(data, "from")) {
09505       ast_copy_string(buf, p->from, len);
09506    } else  if (!strcasecmp(data, "uri")) {
09507       ast_copy_string(buf, p->uri, len);
09508    } else  if (!strcasecmp(data, "useragent")) {
09509       ast_copy_string(buf, p->useragent, len);
09510    } else  if (!strcasecmp(data, "peername")) {
09511       ast_copy_string(buf, p->peername, len);
09512    } else {
09513       ast_mutex_unlock(&chan->lock);
09514       return NULL;
09515    }
09516    ast_mutex_unlock(&chan->lock);
09517 
09518    return buf;
09519 }

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

09372 {
09373    char *ret = NULL;
09374    struct sip_peer *peer;
09375    char *peername, *colname;
09376    char iabuf[INET_ADDRSTRLEN];
09377 
09378    if (!(peername = ast_strdupa(data))) {
09379       ast_log(LOG_ERROR, "Memory Error!\n");
09380       return ret;
09381    }
09382 
09383    if ((colname = strchr(peername, ':'))) {
09384       *colname = '\0';
09385       colname++;
09386    } else {
09387       colname = "ip";
09388    }
09389    if (!(peer = find_peer(peername, NULL, 1)))
09390       return ret;
09391 
09392    if (!strcasecmp(colname, "ip")) {
09393       ast_copy_string(buf, peer->addr.sin_addr.s_addr ? ast_inet_ntoa(iabuf, sizeof(iabuf), peer->addr.sin_addr) : "", len);
09394    } else  if (!strcasecmp(colname, "status")) {
09395       peer_status(peer, buf, len);
09396    } else  if (!strcasecmp(colname, "language")) {
09397       ast_copy_string(buf, peer->language, len);
09398    } else  if (!strcasecmp(colname, "regexten")) {
09399       ast_copy_string(buf, peer->regexten, len);
09400    } else  if (!strcasecmp(colname, "limit")) {
09401       snprintf(buf, len, "%d", peer->call_limit);
09402    } else  if (!strcasecmp(colname, "curcalls")) {
09403       snprintf(buf, len, "%d", peer->inUse);
09404    } else  if (!strcasecmp(colname, "accountcode")) {
09405       ast_copy_string(buf, peer->accountcode, len);
09406    } else  if (!strcasecmp(colname, "useragent")) {
09407       ast_copy_string(buf, peer->useragent, len);
09408    } else  if (!strcasecmp(colname, "mailbox")) {
09409       ast_copy_string(buf, peer->mailbox, len);
09410    } else  if (!strcasecmp(colname, "context")) {
09411       ast_copy_string(buf, peer->context, len);
09412    } else  if (!strcasecmp(colname, "expire")) {
09413       snprintf(buf, len, "%d", peer->expire);
09414    } else  if (!strcasecmp(colname, "dynamic")) {
09415       ast_copy_string(buf, (ast_test_flag(&peer->flags_page2, SIP_PAGE2_DYNAMIC) ? "yes" : "no"), len);
09416    } else  if (!strcasecmp(colname, "callerid_name")) {
09417       ast_copy_string(buf, peer->cid_name, len);
09418    } else  if (!strcasecmp(colname, "callerid_num")) {
09419       ast_copy_string(buf, peer->cid_num, len);
09420    } else  if (!strcasecmp(colname, "codecs")) {
09421       ast_getformatname_multiple(buf, len -1, peer->capability);
09422    } else  if (!strncasecmp(colname, "codec[", 6)) {
09423       char *codecnum, *ptr;
09424       int index = 0, codec = 0;
09425       
09426       codecnum = strchr(colname, '[');
09427       *codecnum = '\0';
09428       codecnum++;
09429       if ((ptr = strchr(codecnum, ']'))) {
09430          *ptr = '\0';
09431       }
09432       index = atoi(codecnum);
09433       if((codec = ast_codec_pref_index(&peer->prefs, index))) {
09434          ast_copy_string(buf, ast_getformatname(codec), len);
09435       }
09436    }
09437    ret = buf;
09438 
09439    ASTOBJ_UNREF(peer, sip_destroy_peer);
09440 
09441    return ret;
09442 }

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

06924 {
06925    char tmp[256], *c, *a;
06926    struct sip_request *req;
06927    
06928    req = oreq;
06929    if (!req)
06930       req = &p->initreq;
06931    ast_copy_string(tmp, get_header(req, "Also"), sizeof(tmp));
06932    
06933    c = get_in_brackets(tmp);
06934    
06935       
06936    if (strncmp(c, "sip:", 4)) {
06937       ast_log(LOG_WARNING, "Huh?  Not a SIP header (%s)?\n", c);
06938       return -1;
06939    }
06940    c += 4;
06941    if ((a = strchr(c, '@')))
06942       *a = '\0';
06943    if ((a = strchr(c, ';'))) 
06944       *a = '\0';
06945    
06946    if (sip_debug_test_pvt(p)) {
06947       ast_verbose("Looking for %s in %s\n", c, p->context);
06948    }
06949    if (ast_exists_extension(NULL, p->context, c, 1, NULL)) {
06950       /* This is an unsupervised transfer */
06951       ast_log(LOG_DEBUG,"Assigning Extension %s to REFER-TO\n", c);
06952       ast_copy_string(p->refer_to, c, sizeof(p->refer_to));
06953       ast_copy_string(p->referred_by, "", sizeof(p->referred_by));
06954       ast_copy_string(p->refer_contact, "", sizeof(p->refer_contact));
06955       p->refer_call = NULL;
06956       return 0;
06957    } else if (ast_canmatch_extension(NULL, p->context, c, 1, NULL)) {
06958       return 1;
06959    }
06960 
06961    return -1;
06962 }

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

get_body: get a specific line from the message body

Definition at line 2926 of file chan_sip.c.

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

Referenced by handle_request_info().

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

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

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

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

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

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

Definition at line 7014 of file chan_sip.c.

Referenced by check_user_full().

07015 {
07016    char *end = strchr(input,'<');
07017    char *tmp = strchr(input,'\"');
07018    int bytes = 0;
07019    int maxbytes = outputsize - 1;
07020 
07021    if (!end || (end == input)) return NULL;
07022    /* move away from "<" */
07023    end--;
07024    /* we found "name" */
07025    if (tmp && tmp < end) {
07026       end = strchr(tmp+1, '\"');
07027       if (!end) return NULL;
07028       bytes = (int) (end - tmp);
07029       /* protect the output buffer */
07030       if (bytes > maxbytes)
07031          bytes = maxbytes;
07032       ast_copy_string(output, tmp + 1, bytes);
07033    } else {
07034       /* we didn't find "name" */
07035       /* clear the empty characters in the begining*/
07036       input = ast_skip_blanks(input);
07037       /* clear the empty characters in the end */
07038       while(*end && (*end < 33) && end > input)
07039          end--;
07040       if (end >= input) {
07041          bytes = (int) (end - input) + 2;
07042          /* protect the output buffer */
07043          if (bytes > maxbytes) {
07044             bytes = maxbytes;
07045          }
07046          ast_copy_string(output, input, bytes);
07047       }
07048       else
07049          return NULL;
07050    }
07051    return output;
07052 }

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

06649 {
06650    char tmp[256] = "", *uri, *a, *user, *domain, *opts;
06651    char tmpf[256], *from;
06652    struct sip_request *req;
06653    char *colon;
06654    
06655    req = oreq;
06656    if (!req)
06657       req = &p->initreq;
06658    if (req->rlPart2)
06659       ast_copy_string(tmp, req->rlPart2, sizeof(tmp));
06660    uri = get_in_brackets(tmp);
06661    
06662    ast_copy_string(tmpf, get_header(req, "From"), sizeof(tmpf));
06663 
06664    from = get_in_brackets(tmpf);
06665    
06666    if (strncmp(uri, "sip:", 4)) {
06667       ast_log(LOG_WARNING, "Huh?  Not a SIP header (%s)?\n", uri);
06668       return -1;
06669    }
06670    uri += 4;
06671    if (!ast_strlen_zero(from)) {
06672       if (strncmp(from, "sip:", 4)) {
06673          ast_log(LOG_WARNING, "Huh?  Not a SIP header (%s)?\n", from);
06674          return -1;
06675       }
06676       from += 4;
06677    } else
06678       from = NULL;
06679 
06680    if (pedanticsipchecking) {
06681       ast_uri_decode(uri);
06682       ast_uri_decode(from);
06683    }
06684 
06685    /* Get the target domain first and user */
06686    if ((domain = strchr(uri, '@'))) {
06687       *domain++ = '\0';
06688       user = uri;
06689    } else {
06690       /* No user portion present */
06691       domain = uri;
06692       user = "s";
06693    }
06694 
06695    /* Strip port from domain if present */
06696    if ((colon = strchr(domain, ':'))) {
06697       *colon = '\0';
06698    }
06699 
06700    /* Strip any params or options from user */
06701    if ((opts = strchr(user, ';'))) {
06702       *opts = '\0';
06703    }
06704 
06705    ast_copy_string(p->domain, domain, sizeof(p->domain));
06706 
06707    if (!AST_LIST_EMPTY(&domain_list)) {
06708       char domain_context[AST_MAX_EXTENSION];
06709 
06710       domain_context[0] = '\0';
06711       if (!check_sip_domain(p->domain, domain_context, sizeof(domain_context))) {
06712          if (!allow_external_domains && (req->method == SIP_INVITE || req->method == SIP_REFER)) {
06713             ast_log(LOG_DEBUG, "Got SIP %s to non-local domain '%s'; refusing request.\n", sip_methods[req->method].text, p->domain);
06714             return -2;
06715          }
06716       }
06717       /* If we have a context defined, overwrite the original context */
06718       if (!ast_strlen_zero(domain_context))
06719          ast_copy_string(p->context, domain_context, sizeof(p->context));
06720    }
06721 
06722    if (from) {
06723       if ((a = strchr(from, ';')))
06724          *a = '\0';
06725       if ((a = strchr(from, '@'))) {
06726          *a = '\0';
06727          ast_copy_string(p->fromdomain, a + 1, sizeof(p->fromdomain));
06728       } else
06729          ast_copy_string(p->fromdomain, from, sizeof(p->fromdomain));
06730    }
06731    if (sip_debug_test_pvt(p))
06732       ast_verbose("Looking for %s in %s (domain %s)\n", user, p->context, p->domain);
06733 
06734    /* Return 0 if we have a matching extension */
06735    if (ast_exists_extension(NULL, p->context, user, 1, from) ||
06736       !strcmp(uri, ast_pickup_ext())) {
06737       if (!oreq)
06738          ast_copy_string(p->exten, user, sizeof(p->exten));
06739       return 0;
06740    }
06741 
06742    /* Return 1 for overlap dialling support */
06743    if (ast_canmatch_extension(NULL, p->context, user, 1, from) ||
06744        !strncmp(user, ast_pickup_ext(),strlen(user))) {
06745       return 1;
06746    }
06747    
06748    return -1;
06749 }

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

get_header: Get header from SIP request ---

Definition at line 2985 of file chan_sip.c.

References __get_header().

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

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

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

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

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

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

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

Referenced by receive_message().

07364 {
07365    int x;
07366    int y;
07367 
07368    buf[0] = '\0';
07369    y = len - strlen(buf) - 5;
07370    if (y < 0)
07371       y = 0;
07372    for (x=0;x<req->lines;x++) {
07373       strncat(buf, req->line[x], y); /* safe */
07374       y -= strlen(req->line[x]) + 1;
07375       if (y < 0)
07376          y = 0;
07377       if (y != 0)
07378          strcat(buf, "\n"); /* safe */
07379    }
07380    return 0;
07381 }

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

get_rdnis: get referring dnis ---

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

06621 {
06622    char tmp[256], *c, *a;
06623    struct sip_request *req;
06624    
06625    req = oreq;
06626    if (!req)
06627       req = &p->initreq;
06628    ast_copy_string(tmp, get_header(req, "Diversion"), sizeof(tmp));
06629    if (ast_strlen_zero(tmp))
06630       return 0;
06631    c = get_in_brackets(tmp);
06632    if (strncmp(c, "sip:", 4)) {
06633       ast_log(LOG_WARNING, "Huh?  Not an RDNIS SIP header (%s)?\n", c);
06634       return -1;
06635    }
06636    c += 4;
06637    if ((a = strchr(c, '@')) || (a = strchr(c, ';'))) {
06638       *a = '\0';
06639    }
06640    if (sip_debug_test_pvt(p))
06641       ast_verbose("RDNIS is %s\n", c);
06642    ast_copy_string(p->rdnis, c, sizeof(p->rdnis));
06643 
06644    return 0;
06645 }

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

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

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

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

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

References AST_PRES_PROHIB_USER_NUMBER_NOT_SCREENED.

Referenced by check_user_full().

07059 {
07060    char *start;
07061    char *end;
07062 
07063    start = strchr(input,':');
07064    if (!start) {
07065       output[0] = '\0';
07066       return 0;
07067    }
07068    start++;
07069 
07070    /* we found "number" */
07071    ast_copy_string(output,start,maxlen);
07072    output[maxlen-1] = '\0';
07073 
07074    end = strchr(output,'@');
07075    if (end)
07076       *end = '\0';
07077    else
07078       output[0] = '\0';
07079    if (strstr(input,"privacy=full") || strstr(input,"privacy=uri"))
07080       return AST_PRES_PROHIB_USER_NUMBER_NOT_SCREENED;
07081 
07082    return 0;
07083 }

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

get_sdp: get a specific line from the SDP

Definition at line 2892 of file chan_sip.c.

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

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

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

Definition at line 2911 of file chan_sip.c.

References get_body_by_line(), and sip_request::line.

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

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

06753 {
06754    struct sip_pvt *sip_pvt_ptr = NULL;
06755    
06756    /* Search interfaces and find the match */
06757    ast_mutex_lock(&iflock);
06758    sip_pvt_ptr = iflist;
06759    while(sip_pvt_ptr) {
06760       if (!strcmp(sip_pvt_ptr->callid, callid)) {
06761          /* Go ahead and lock it (and its owner) before returning */
06762          ast_mutex_lock(&sip_pvt_ptr->lock);
06763          if (sip_pvt_ptr->owner) {
06764             while(ast_mutex_trylock(&sip_pvt_ptr->owner->lock)) {
06765                ast_mutex_unlock(&sip_pvt_ptr->lock);
06766                usleep(1);
06767                ast_mutex_lock(&sip_pvt_ptr->lock);
06768                if (!sip_pvt_ptr->owner)
06769                   break;
06770             }
06771          }
06772          break;
06773       }
06774       sip_pvt_ptr = sip_pvt_ptr->next;
06775    }
06776    ast_mutex_unlock(&iflock);
06777    return sip_pvt_ptr;
06778 }

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

gettag: Get tag from packet

Definition at line 10380 of file chan_sip.c.

References get_header(), and strcasestr().

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

10381 {
10382 
10383    char *thetag, *sep;
10384    
10385 
10386    if (!tagbuf)
10387       return NULL;
10388    tagbuf[0] = '\0';    /* reset the buffer */
10389    thetag = get_header(req, header);
10390    thetag = strcasestr(thetag, ";tag=");
10391    if (thetag) {
10392       thetag += 5;
10393       ast_copy_string(tagbuf, thetag, tagbufsize);
10394       sep = strchr(tagbuf, ';');
10395       if (sep)
10396          *sep = '\0';
10397    }
10398    return thetag;
10399 }

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

11849 {
11850    int res = 0;
11851 
11852    if (!strcasecmp(v->name, "trustrpid")) {
11853       ast_set_flag(mask, SIP_TRUSTRPID);
11854       ast_set2_flag(flags, ast_true(v->value), SIP_TRUSTRPID);
11855       res = 1;
11856    } else if (!strcasecmp(v->name, "sendrpid")) {
11857       ast_set_flag(mask, SIP_SENDRPID);
11858       ast_set2_flag(flags, ast_true(v->value), SIP_SENDRPID);
11859       res = 1;
11860    } else if (!strcasecmp(v->name, "useclientcode")) {
11861       ast_set_flag(mask, SIP_USECLIENTCODE);
11862       ast_set2_flag(flags, ast_true(v->value), SIP_USECLIENTCODE);
11863       res = 1;
11864    } else if (!strcasecmp(v->name, "dtmfmode")) {
11865       ast_set_flag(mask, SIP_DTMF);
11866       ast_clear_flag(flags, SIP_DTMF);
11867       if (!strcasecmp(v->value, "inband"))
11868          ast_set_flag(flags, SIP_DTMF_INBAND);
11869       else if (!strcasecmp(v->value, "rfc2833"))
11870          ast_set_flag(flags, SIP_DTMF_RFC2833);
11871       else if (!strcasecmp(v->value, "info"))
11872          ast_set_flag(flags, SIP_DTMF_INFO);
11873       else if (!strcasecmp(v->value, "auto"))
11874          ast_set_flag(flags, SIP_DTMF_AUTO);
11875       else {
11876          ast_log(LOG_WARNING, "Unknown dtmf mode '%s' on line %d, using rfc2833\n", v->value, v->lineno);
11877          ast_set_flag(flags, SIP_DTMF_RFC2833);
11878       }
11879    } else if (!strcasecmp(v->name, "nat")) {
11880       ast_set_flag(mask, SIP_NAT);
11881       ast_clear_flag(flags, SIP_NAT);
11882       if (!strcasecmp(v->value, "never"))
11883          ast_set_flag(flags, SIP_NAT_NEVER);
11884       else if (!strcasecmp(v->value, "route"))
11885          ast_set_flag(flags, SIP_NAT_ROUTE);
11886       else if (ast_true(v->value))
11887          ast_set_flag(flags, SIP_NAT_ALWAYS);
11888       else
11889          ast_set_flag(flags, SIP_NAT_RFC3581);
11890    } else if (!strcasecmp(v->name, "canreinvite")) {
11891       ast_set_flag(mask, SIP_REINVITE);
11892       ast_clear_flag(flags, SIP_REINVITE);
11893       if (!strcasecmp(v->value, "update"))
11894          ast_set_flag(flags, SIP_REINVITE_UPDATE | SIP_CAN_REINVITE);
11895       else
11896          ast_set2_flag(flags, ast_true(v->value), SIP_CAN_REINVITE);
11897    } else if (!strcasecmp(v->name, "insecure")) {
11898       ast_set_flag(mask, SIP_INSECURE_PORT | SIP_INSECURE_INVITE);
11899       ast_clear_flag(flags, SIP_INSECURE_PORT | SIP_INSECURE_INVITE);
11900       if (!strcasecmp(v->value, "very"))
11901          ast_set_flag(flags, SIP_INSECURE_PORT | SIP_INSECURE_INVITE);
11902       else if (ast_true(v->value))
11903          ast_set_flag(flags, SIP_INSECURE_PORT);
11904       else if (!ast_false(v->value)) {
11905          char buf[64];
11906          char *word, *next;
11907 
11908          ast_copy_string(buf, v->value, sizeof(buf));
11909          next = buf;
11910          while ((word = strsep(&next, ","))) {
11911             if (!strcasecmp(word, "port"))
11912                ast_set_flag(flags, SIP_INSECURE_PORT);
11913             else if (!strcasecmp(word, "invite"))
11914                ast_set_flag(flags, SIP_INSECURE_INVITE);
11915             else
11916                ast_log(LOG_WARNING, "Unknown insecure mode '%s' on line %d\n", v->value, v->lineno);
11917          }
11918       }
11919    } else if (!strcasecmp(v->name, "progressinband")) {
11920       ast_set_flag(mask, SIP_PROG_INBAND);
11921       ast_clear_flag(flags, SIP_PROG_INBAND);
11922       if (ast_true(v->value))
11923          ast_set_flag(flags, SIP_PROG_INBAND_YES);
11924       else if (strcasecmp(v->value, "never"))
11925          ast_set_flag(flags, SIP_PROG_INBAND_NO);
11926    } else if (!strcasecmp(v->name, "allowguest")) {
11927 #ifdef OSP_SUPPORT
11928       if (!strcasecmp(v->value, "osp"))
11929          global_allowguest = 2;
11930       else 
11931 #endif
11932          if (ast_true(v->value)) 
11933             global_allowguest = 1;
11934          else
11935             global_allowguest = 0;
11936 #ifdef OSP_SUPPORT
11937    } else if (!strcasecmp(v->name, "ospauth")) {
11938       ast_set_flag(mask, SIP_OSPAUTH);
11939       ast_clear_flag(flags, SIP_OSPAUTH);
11940       if (!strcasecmp(v->value, "proxy"))
11941          ast_set_flag(flags, SIP_OSPAUTH_PROXY);
11942       else if (!strcasecmp(v->value, "gateway"))
11943          ast_set_flag(flags, SIP_OSPAUTH_GATEWAY);
11944       else if(!strcasecmp (v->value, "exclusive"))
11945          ast_set_flag(flags, SIP_OSPAUTH_EXCLUSIVE);
11946 #endif
11947    } else if (!strcasecmp(v->name, "promiscredir")) {
11948       ast_set_flag(mask, SIP_PROMISCREDIR);
11949       ast_set2_flag(flags, ast_true(v->value), SIP_PROMISCREDIR);
11950       res = 1;
11951    }
11952 
11953    return res;
11954 }

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

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

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

10789 {
10790    struct ast_channel *c=NULL;
10791    int res;
10792    struct ast_channel *bridged_to;
10793    char iabuf[INET_ADDRSTRLEN];
10794    
10795    if (p->pendinginvite && !ast_test_flag(p, SIP_OUTGOING) && !ignore)
10796       transmit_response_reliable(p, "487 Request Terminated", &p->initreq, 1);
10797 
10798    copy_request(&p->initreq, req);
10799    check_via(p, req);
10800    ast_set_flag(p, SIP_ALREADYGONE);   
10801    if (p->rtp) {
10802       /* Immediately stop RTP */
10803       ast_rtp_stop(p->rtp);
10804    }
10805    if (p->vrtp) {
10806       /* Immediately stop VRTP */
10807       ast_rtp_stop(p->vrtp);
10808    }
10809    if (!ast_strlen_zero(get_header(req, "Also"))) {
10810       ast_log(LOG_NOTICE, "Client '%s' using deprecated BYE/Also transfer method.  Ask vendor to support REFER instead\n",
10811          ast_inet_ntoa(iabuf, sizeof(iabuf), p->recv.sin_addr));
10812       if (ast_strlen_zero(p->context))
10813          strcpy(p->context, default_context);
10814       res = get_also_info(p, req);
10815       if (!res) {
10816          c = p->owner;
10817          if (c) {
10818             bridged_to = ast_bridged_channel(c);
10819             if (bridged_to) {
10820                /* Don't actually hangup here... */
10821                ast_moh_stop(bridged_to);
10822                ast_async_goto(bridged_to, p->context, p->refer_to,1);
10823             } else
10824                ast_queue_hangup(p->owner);
10825          }
10826       } else {
10827          ast_log(LOG_WARNING, "Invalid transfer information from '%s'\n", ast_inet_ntoa(iabuf, sizeof(iabuf), p->recv.sin_addr));
10828          if (p->owner)
10829             ast_queue_hangup(p->owner);
10830       }
10831    } else if (p->owner) {
10832       ast_queue_hangup(p->owner);
10833       if (option_debug > 2)
10834          ast_log(LOG_DEBUG, "Received bye, issuing owner hangup\n.");
10835    } else {
10836       ast_set_flag(p, SIP_NEEDDESTROY);   
10837       if (option_debug > 2)
10838          ast_log(LOG_DEBUG, "Received bye, no owner, selfdestruct soon.\n.");
10839    }
10840    transmit_response(p, "200 OK", req);
10841 
10842    return 1;
10843 }

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

10760 {
10761       
10762    check_via(p, req);
10763    ast_set_flag(p, SIP_ALREADYGONE);   
10764    if (p->rtp) {
10765       /* Immediately stop RTP */
10766       ast_rtp_stop(p->rtp);
10767    }
10768    if (p->vrtp) {
10769       /* Immediately stop VRTP */
10770       ast_rtp_stop(p->vrtp);
10771    }
10772    if (p->owner)
10773       ast_queue_hangup(p->owner);
10774    else
10775       ast_set_flag(p, SIP_NEEDDESTROY);   
10776    if (p->initreq.len > 0) {
10777       if (!ignore)
10778          transmit_response_reliable(p, "487 Request Terminated", &p->initreq, 1);
10779       transmit_response(p, "200 OK", req);
10780       return 1;
10781    } else {
10782       transmit_response(p, "481 Call Leg Does Not Exist", req);
10783       return 0;
10784    }
10785 }

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

handle_request_info: Receive SIP INFO Message ---

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

08745 {
08746    char buf[1024];
08747    unsigned int event;
08748    char *c;
08749    
08750    /* Need to check the media/type */
08751    if (!strcasecmp(get_header(req, "Content-Type"), "application/dtmf-relay") ||
08752        !strcasecmp(get_header(req, "Content-Type"), "application/vnd.nortelnetworks.digits")) {
08753 
08754       /* Try getting the "signal=" part */
08755       if (ast_strlen_zero(c = get_body(req, "Signal")) && ast_strlen_zero(c = get_body(req, "d"))) {
08756          ast_log(LOG_WARNING, "Unable to retrieve DTMF signal from INFO message from %s\n", p->callid);
08757          transmit_response(p, "200 OK", req); /* Should return error */
08758          return;
08759       } else {
08760          ast_copy_string(buf, c, sizeof(buf));
08761       }
08762    
08763       if (!p->owner) {  /* not a PBX call */
08764          transmit_response(p, "481 Call leg/transaction does not exist", req);
08765          ast_set_flag(p, SIP_NEEDDESTROY);
08766          return;
08767       }
08768 
08769       if (ast_strlen_zero(buf)) {
08770          transmit_response(p, "200 OK", req);
08771          return;
08772       }
08773 
08774       if (buf[0] == '*')
08775          event = 10;
08776       else if (buf[0] == '#')
08777          event = 11;
08778       else if ((buf[0] >= 'A') && (buf[0] <= 'D'))
08779          event = 12 + buf[0] - 'A';
08780       else
08781          event = atoi(buf);
08782       if (event == 16) {
08783          /* send a FLASH event */
08784          struct ast_frame f = { AST_FRAME_CONTROL, AST_CONTROL_FLASH, };
08785          ast_queue_frame(p->owner, &f);
08786          if (sipdebug)
08787             ast_verbose("* DTMF-relay event received: FLASH\n");
08788       } else {
08789          /* send a DTMF event */
08790          struct ast_frame f = { AST_FRAME_DTMF, };
08791          if (event < 10) {
08792             f.subclass = '0' + event;
08793          } else if (event < 11) {
08794             f.subclass = '*';
08795          } else if (event < 12) {
08796             f.subclass = '#';
08797          } else if (event < 16) {
08798             f.subclass = 'A' + (event - 12);
08799          }
08800          ast_queue_frame(p->owner, &f);
08801          if (sipdebug)
08802             ast_verbose("* DTMF-relay event received: %c\n", f.subclass);
08803       }
08804       transmit_response(p, "200 OK", req);
08805       return;
08806    } else if (!strcasecmp(get_header(req, "Content-Type"), "application/media_control+xml")) {
08807       /* Eh, we'll just assume it's a fast picture update for now */
08808       if (p->owner)
08809          ast_queue_control(p->owner, AST_CONTROL_VIDUPDATE);
08810       transmit_response(p, "200 OK", req);
08811       return;
08812    } else if ((c = get_header(req, "X-ClientCode"))) {
08813       /* Client code (from SNOM phone) */
08814       if (ast_test_flag(p, SIP_USECLIENTCODE)) {
08815          if (p->owner && p->owner->cdr)
08816             ast_cdr_setuserfield(p->owner, c);
08817          if (p->owner && ast_bridged_channel(p->owner) && ast_bridged_channel(p->owner)->cdr)
08818             ast_cdr_setuserfield(ast_bridged_channel(p->owner), c);
08819          transmit_response(p, "200 OK", req);
08820       } else {
08821          transmit_response(p, "403 Unauthorized", req);
08822       }
08823       return;
08824    }
08825    /* Other type of INFO message, not really understood by Asterisk */
08826    /* if (get_msg_text(buf, sizeof(buf), req)) { */
08827 
08828    ast_log(LOG_WARNING, "Unable to parse INFO message from %s. Content %s\n", p->callid, buf);
08829    transmit_response(p, "415 Unsupported media type", req);
08830    return;
08831 }

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

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

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

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

Referenced by handle_request().

10847 {
10848    if (!ignore) {
10849       if (debug)
10850          ast_verbose("Receiving message!\n");
10851       receive_message(p, req);
10852    } else {
10853       transmit_response(p, "202 Accepted", req);
10854    }
10855    return 1;
10856 }

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

10403 {
10404    int res;
10405 
10406    res = get_destination(p, req);
10407    build_contact(p);
10408    /* XXX Should we authenticate OPTIONS? XXX */
10409    if (ast_strlen_zero(p->context))
10410       strcpy(p->context, default_context);
10411    if (res < 0)
10412       transmit_response_with_allow(p, "404 Not Found", req, 0);
10413    else if (res > 0)
10414       transmit_response_with_allow(p, "484 Address Incomplete", req, 0);
10415    else 
10416       transmit_response_with_allow(p, "200 OK", req, 0);
10417    /* Destroy if this OPTIONS was the opening request, but not if
10418       it's in the middle of a normal call flow. */
10419    if (!p->lastinvite)
10420       ast_set_flag(p, SIP_NEEDDESTROY);   
10421 
10422    return res;
10423 }

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

10692 {
10693    struct ast_channel *c=NULL;
10694    int res;
10695    struct ast_channel *transfer_to;
10696 
10697    if (option_debug > 2)
10698       ast_log(LOG_DEBUG, "SIP call transfer received for call %s (REFER)!\n", p->callid);
10699    if (ast_strlen_zero(p->context))
10700       strcpy(p->context, default_context);
10701    res = get_refer_info(p, req);
10702    if (res < 0)
10703       transmit_response(p, "603 Declined", req);
10704    else if (res > 0)
10705       transmit_response(p, "484 Address Incomplete", req);
10706    else {
10707       int nobye = 0;
10708       if (!ignore) {
10709          if (p->refer_call) {
10710             ast_log(LOG_DEBUG,"202 Accepted (supervised)\n");
10711             attempt_transfer(p, p->refer_call);
10712             if (p->refer_call->owner)
10713                ast_mutex_unlock(&p->refer_call->owner->lock);
10714             ast_mutex_unlock(&p->refer_call->lock);
10715             p->refer_call = NULL;
10716             ast_set_flag(p, SIP_GOTREFER);   
10717          } else {
10718             ast_log(LOG_DEBUG,"202 Accepted (blind)\n");
10719             c = p->owner;
10720             if (c) {
10721                transfer_to = ast_bridged_channel(c);
10722                if (transfer_to) {
10723                   ast_log(LOG_DEBUG, "Got SIP blind transfer, applying to '%s'\n", transfer_to->name);
10724                   ast_moh_stop(transfer_to);
10725                   if (!strcmp(p->refer_to, ast_parking_ext())) {
10726                      /* Must release c's lock now, because it will not longer
10727                          be accessible after the transfer! */
10728                      *nounlock = 1;
10729                      ast_mutex_unlock(&c->lock);
10730                      sip_park(transfer_to, c, req);
10731                      nobye = 1;
10732                   } else {
10733                      /* Must release c's lock now, because it will not longer
10734                          be accessible after the transfer! */
10735                      *nounlock = 1;
10736                      ast_mutex_unlock(&c->lock);
10737                      ast_async_goto(transfer_to,p->context, p->refer_to,1);
10738                   }
10739                } else {
10740                   ast_log(LOG_DEBUG, "Got SIP blind transfer but nothing to transfer to.\n");
10741                   ast_queue_hangup(p->owner);
10742                }
10743             }
10744             ast_set_flag(p, SIP_GOTREFER);   
10745          }
10746          transmit_response(p, "202 Accepted", req);
10747          transmit_notify_with_sipfrag(p, seqno);
10748          /* Always increment on a BYE */
10749          if (!nobye) {
10750             transmit_request_with_auth(p, SIP_BYE, 0, 1, 1);
10751             ast_set_flag(p, SIP_ALREADYGONE);   
10752          }
10753       }
10754    }
10755    return res;
10756 }

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

11076 {
11077    int res = 0;
11078    char iabuf[INET_ADDRSTRLEN];
11079 
11080    /* Use this as the basis */
11081    if (debug)
11082       ast_verbose("Using latest REGISTER request as basis request\n");
11083    copy_request(&p->initreq, req);
11084    check_via(p, req);
11085    if ((res = register_verify(p, sin, req, e, ignore)) < 0) 
11086       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"));
11087    if (res < 1) {
11088       /* Destroy the session, but keep us around for just a bit in case they don't
11089          get our 200 OK */
11090       sip_scheddestroy(p, 15*1000);
11091    }
11092    return res;
11093 }

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

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

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

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

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

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

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

09869 {
09870    struct sip_peer *peer;
09871    int pingtime;
09872    struct timeval tv;
09873 
09874    if (resp != 100) {
09875       int statechanged = 0;
09876       int newstate = 0;
09877       peer = p->peerpoke;
09878       gettimeofday(&tv, NULL);
09879       pingtime = ast_tvdiff_ms(tv, peer->ps);
09880       if (pingtime < 1)
09881          pingtime = 1;
09882       if ((peer->lastms < 0)  || (peer->lastms > peer->maxms)) {
09883          if (pingtime <= peer->maxms) {
09884             ast_log(LOG_NOTICE, "Peer '%s' is now REACHABLE! (%dms / %dms)\n", peer->name, pingtime, peer->maxms);
09885             statechanged = 1;
09886             newstate = 1;
09887          }
09888       } else if ((peer->lastms > 0) && (peer->lastms <= peer->maxms)) {
09889          if (pingtime > peer->maxms) {
09890             ast_log(LOG_NOTICE, "Peer '%s' is now TOO LAGGED! (%dms / %dms)\n", peer->name, pingtime, peer->maxms);
09891             statechanged = 1;
09892             newstate = 2;
09893          }
09894       }
09895       if (!peer->lastms)
09896          statechanged = 1;
09897       peer->lastms = pingtime;
09898       peer->call = NULL;
09899       if (statechanged) {
09900          ast_device_state_changed("SIP/%s", peer->name);
09901          if (newstate == 2) {
09902             manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: SIP/%s\r\nPeerStatus: Lagged\r\nTime: %d\r\n", peer->name, pingtime);
09903          } else {
09904             manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: SIP/%s\r\nPeerStatus: Reachable\r\nTime: %d\r\n", peer->name, pingtime);
09905          }
09906       }
09907 
09908       if (peer->pokeexpire > -1)
09909          ast_sched_del(sched, peer->pokeexpire);
09910       if (sipmethod == SIP_INVITE)  /* Does this really happen? */
09911          transmit_request(p, SIP_ACK, seqno, 0, 0);
09912       ast_set_flag(p, SIP_NEEDDESTROY);   
09913 
09914       /* Try again eventually */
09915       if ((peer->lastms < 0)  || (peer->lastms > peer->maxms))
09916          peer->pokeexpire = ast_sched_add(sched, DEFAULT_FREQ_NOTOK, sip_poke_peer_s, peer);
09917       else
09918          peer->pokeexpire = ast_sched_add(sched, DEFAULT_FREQ_OK, sip_poke_peer_s, peer);
09919    }
09920    return 1;
09921 }

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

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

Referenced by handle_response().

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

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

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

static int hangup_sip2cause ( int  cause  )  [static]

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

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

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

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

init_req: Initialize SIP request ---

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

04066 {
04067    /* Initialize a response */
04068    if (req->headers || req->len) {
04069       ast_log(LOG_WARNING, "Request already initialized?!?\n");
04070       return -1;
04071    }
04072    req->header[req->headers] = req->data + req->len;
04073    snprintf(req->header[req->headers], sizeof(req->data) - req->len, "%s %s SIP/2.0\r\n", sip_methods[sipmethod].text, recip);
04074    req->len += strlen(req->header[req->headers]);
04075    req->headers++;
04076    req->method = sipmethod;
04077    return 0;
04078 }

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

04050 {
04051    /* Initialize a response */
04052    if (req->headers || req->len) {
04053       ast_log(LOG_WARNING, "Request already initialized?!?\n");
04054       return -1;
04055    }
04056    req->method = SIP_RESPONSE;
04057    req->header[req->headers] = req->data + req->len;
04058    snprintf(req->header[req->headers], sizeof(req->data) - req->len, "SIP/2.0 %s\r\n", resp);
04059    req->len += strlen(req->header[req->headers]);
04060    req->headers++;
04061    return 0;
04062 }

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

References add_header(), ast_build_string(), AST_DIGIT_ANYNUM, ast_inet_ntoa(), AST_PRES_ALLOWED, AST_PRES_RESTRICTION, ast_strlen_zero(), ast_test_flag, ast_uri_encode(), build_contact(), build_rpid(), CALLERID_UNKNOWN, sip_pvt::callid, sip_pvt::callingpres, ast_channel::cid, ast_callerid::cid_name, ast_callerid::cid_num, default_callerid, DEFAULT_MAX_FORWARDS, default_useragent, sip_pvt::exten, sip_pvt::fromdomain, sip_pvt::fromname, sip_pvt::fromuser, sip_pvt::fullcontact, init_req(), sip_pvt::lastmsg, n, sip_pvt::ocseq, sip_pvt::options, sip_pvt::our_contact, sip_pvt::ourip, ourport, sip_pvt::owner, pedanticsipchecking, sip_pvt::rpid, sip_pvt::sa, SIP_INVITE, sip_methods, SIP_NOTIFY, SIP_SENDRPID, SIP_USEREQPHONE, sip_pvt::tag, cfsip_methods::text, sip_pvt::theirtag, sip_pvt::tohost, sip_pvt::uri, sip_invite_param::uri_options, sip_pvt::username, sip_pvt::via, and sip_invite_param::vxml_url.

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

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

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

insecure2str: Convert Insecure setting to printable string ---

Definition at line 7771 of file chan_sip.c.

Referenced by _sip_show_peer().

07772 {
07773    if (port && invite)
07774       return "port,invite";
07775    else if (port)
07776       return "port";
07777    else if (invite)
07778       return "invite";
07779    else
07780       return "no";
07781 }

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

References ASTERISK_GPL_KEY.

13534 {
13535    return ASTERISK_GPL_KEY;
13536 }

static void list_route ( struct sip_route route  )  [static]

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

Definition at line 6075 of file chan_sip.c.

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

Referenced by build_route().

06076 {
06077    if (!route) {
06078       ast_verbose("list_route: no route\n");
06079       return;
06080    }
06081    while (route) {
06082       ast_verbose("list_route: hop: <%s>\n", route->hop);
06083       route = route->next;
06084    }
06085 }

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

References 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, EVENT_FLAG_SYSTEM, io, io_context_create(), LOG_ERROR, LOG_WARNING, manager_sip_show_peer(), manager_sip_show_peers(), mandescr_show_peer, 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, and userl.

13382 {
13383    ASTOBJ_CONTAINER_INIT(&userl);   /* User object list */
13384    ASTOBJ_CONTAINER_INIT(&peerl);   /* Peer object list */
13385    ASTOBJ_CONTAINER_INIT(&regl); /* Registry object list */
13386 
13387    sched = sched_context_create();
13388    if (!sched) {
13389       ast_log(LOG_WARNING, "Unable to create schedule context\n");
13390    }
13391 
13392    io = io_context_create();
13393    if (!io) {
13394       ast_log(LOG_WARNING, "Unable to create I/O context\n");
13395    }
13396 
13397    reload_config();  /* Load the configuration from sip.conf */
13398 
13399    /* Make sure we can register our sip channel type */
13400    if (ast_channel_register(&sip_tech)) {
13401       ast_log(LOG_ERROR, "Unable to register channel type %s\n", channeltype);
13402       return -1;
13403    }
13404 
13405    /* Register all CLI functions for SIP */
13406    ast_cli_register_multiple(my_clis, sizeof(my_clis)/ sizeof(my_clis[0]));
13407 
13408    /* Tell the RTP subdriver that we're here */
13409    ast_rtp_proto_register(&sip_rtp);
13410 
13411    /* Register dialplan applications */
13412    ast_register_application(app_dtmfmode, sip_dtmfmode, synopsis_dtmfmode, descrip_dtmfmode);
13413 
13414    /* These will be removed soon */
13415    ast_register_application(app_sipaddheader, sip_addheader, synopsis_sipaddheader, descrip_sipaddheader);
13416    ast_register_application(app_sipgetheader, sip_getheader, synopsis_sipgetheader, descrip_sipgetheader);
13417 
13418    /* Register dialplan functions */
13419    ast_custom_function_register(&sip_header_function);
13420    ast_custom_function_register(&sippeer_function);
13421    ast_custom_function_register(&sipchaninfo_function);
13422    ast_custom_function_register(&checksipdomain_function);
13423 
13424    /* Register manager commands */
13425    ast_manager_register2("SIPpeers", EVENT_FLAG_SYSTEM, manager_sip_show_peers,
13426          "List SIP peers (text format)", mandescr_show_peers);
13427    ast_manager_register2("SIPshowpeer", EVENT_FLAG_SYSTEM, manager_sip_show_peer,
13428          "Show SIP peer (text format)", mandescr_show_peer);
13429 
13430    sip_poke_all_peers();   
13431    sip_send_all_registers();
13432    
13433    /* And start the monitor for the first time */
13434    restart_monitor();
13435 
13436    return 0;
13437 }

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

lws2sws: Parse multiline SIP headers into one header

Definition at line 3321 of file chan_sip.c.

References t.

Referenced by sipsock_read().

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

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

Definition at line 3073 of file chan_sip.c.

References thread_safe_rand().

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

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

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

07992 {
07993    char *id = astman_get_header(m,"ActionID");
07994    char *a[4];
07995    char *peer;
07996    int ret;
07997 
07998    peer = astman_get_header(m,"Peer");
07999    if (ast_strlen_zero(peer)) {
08000       astman_send_error(s, m, "Peer: <name> missing.\n");
08001       return 0;
08002    }
08003    a[0] = "sip";
08004    a[1] = "show";
08005    a[2] = "peer";
08006    a[3] = peer;
08007 
08008    if (!ast_strlen_zero(id))
08009       ast_cli(s->fd, "ActionID: %s\r\n",id);
08010    ret = _sip_show_peer(1, s->fd, s, m, 4, a );
08011    ast_cli( s->fd, "\r\n\r\n" );
08012    return ret;
08013 }

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

07573 {
07574    char *id = astman_get_header(m,"ActionID");
07575    char *a[] = { "sip", "show", "peers" };
07576    char idtext[256] = "";
07577    int total = 0;
07578 
07579    if (!ast_strlen_zero(id))
07580       snprintf(idtext,256,"ActionID: %s\r\n",id);
07581 
07582    astman_send_ack(s, m, "Peer status list will follow");
07583    /* List the peers in separate manager events */
07584    _sip_show_peers(s->fd, &total, s, m, 3, a);
07585    /* Send final confirmation */
07586    ast_cli(s->fd,
07587    "Event: PeerlistComplete\r\n"
07588    "ListItems: %d\r\n"
07589    "%s"
07590    "\r\n", total, idtext);
07591    return 0;
07592 }

static char* nat2str ( int  nat  )  [static]

nat2str: Convert NAT setting to text string

Definition at line 7474 of file chan_sip.c.

References SIP_NAT_ALWAYS, SIP_NAT_NEVER, SIP_NAT_RFC3581, and SIP_NAT_ROUTE.

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

07475 {
07476    switch(nat) {
07477    case SIP_NAT_NEVER:
07478       return "No";
07479    case SIP_NAT_ROUTE:
07480       return "Route";
07481    case SIP_NAT_ALWAYS:
07482       return "Always";
07483    case SIP_NAT_RFC3581:
07484       return "RFC3581";
07485    default:
07486       return "Unknown";
07487    }
07488 }

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

parse_copy: Copy SIP request, parse it

Definition at line 1472 of file chan_sip.c.

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

Referenced by send_request(), and send_response().

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

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

09540 {
09541    char tmp[256];
09542    char *s, *e;
09543    ast_copy_string(tmp, get_header(req, "Contact"), sizeof(tmp));
09544    s = get_in_brackets(tmp);
09545    e = strchr(s, ';');
09546    if (e)
09547       *e = '\0';
09548    if (ast_test_flag(p, SIP_PROMISCREDIR)) {
09549       if (!strncasecmp(s, "sip:", 4))
09550          s += 4;
09551       e = strchr(s, '/');
09552       if (e)
09553          *e = '\0';
09554       ast_log(LOG_DEBUG, "Found promiscuous redirection to 'SIP/%s'\n", s);
09555       if (p->owner)
09556          snprintf(p->owner->call_forward, sizeof(p->owner->call_forward), "SIP/%s", s);
09557    } else {
09558       e = strchr(tmp, '@');
09559       if (e)
09560          *e = '\0';
09561       e = strchr(tmp, '/');
09562       if (e)
09563          *e = '\0';
09564       if (!strncasecmp(s, "sip:", 4))
09565          s += 4;
09566       ast_log(LOG_DEBUG, "Found 302 Redirect to extension '%s'\n", s);
09567       if (p->owner)
09568          ast_copy_string(p->owner->call_forward, s, sizeof(p->owner->call_forward));
09569    }
09570 }

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 5836 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, n, sip_pvt::okcontacturi, sip_pvt::recv, sip_pvt::sa, SIP_LEN_CONTACT, SIP_NAT, and SIP_NAT_ROUTE.

Referenced by handle_response_invite().

05837 {
05838    char contact[SIP_LEN_CONTACT]; 
05839    char *c, *n, *pt;
05840    int port;
05841    struct hostent *hp;
05842    struct ast_hostent ahp;
05843    struct sockaddr_in oldsin;
05844 
05845    /* Look for brackets */
05846    ast_copy_string(contact, get_header(req, "Contact"), sizeof(contact));
05847    c = get_in_brackets(contact);
05848 
05849    /* Save full contact to call pvt for later bye or re-invite */
05850    ast_copy_string(pvt->fullcontact, c, sizeof(pvt->fullcontact));   
05851 
05852    /* Save URI for later ACKs, BYE or RE-invites */
05853    ast_copy_string(pvt->okcontacturi, c, sizeof(pvt->okcontacturi));
05854    
05855    /* Make sure it's a SIP URL */
05856    if (strncasecmp(c, "sip:", 4)) {
05857       ast_log(LOG_NOTICE, "'%s' is not a valid SIP contact (missing sip:) trying to use anyway\n", c);
05858    } else
05859       c += 4;
05860 
05861    /* Ditch arguments */
05862    n = strchr(c, ';');
05863    if (n) 
05864       *n = '\0';
05865 
05866    /* Grab host */
05867    n = strchr(c, '@');
05868    if (!n) {
05869       n = c;
05870       c = NULL;
05871    } else {
05872       *n = '\0';
05873       n++;
05874    }
05875    pt = strchr(n, ':');
05876    if (pt) {
05877       *pt = '\0';
05878       pt++;
05879       port = atoi(pt);
05880    } else
05881       port = DEFAULT_SIP_PORT;
05882 
05883    memcpy(&oldsin, &pvt->sa, sizeof(oldsin));
05884 
05885    if (!(ast_test_flag(pvt, SIP_NAT) & SIP_NAT_ROUTE)) {
05886       /* XXX This could block for a long time XXX */
05887       /* We should only do this if it's a name, not an IP */
05888       hp = ast_gethostbyname(n, &ahp);
05889       if (!hp)  {
05890          ast_log(LOG_WARNING, "Invalid host '%s'\n", n);
05891          return -1;
05892       }
05893       pvt->sa.sin_family = AF_INET;
05894       memcpy(&pvt->sa.sin_addr, hp->h_addr, sizeof(pvt->sa.sin_addr));
05895       pvt->sa.sin_port = htons(port);
05896    } else {
05897       /* Don't trust the contact field.  Just use what they came to us
05898          with. */
05899       memcpy(&pvt->sa, &pvt->recv, sizeof(pvt->sa));
05900    }
05901    return 0;
05902 }

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 5912 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, n, option_verbose, sip_pvt::our_contact, PARSE_REGISTER_FAILED, PARSE_REGISTER_QUERY, PARSE_REGISTER_UPDATE, sip_pvt::recv, register_peer_exten(), SIP_NAT, SIP_NAT_ROUTE, SIP_PAGE2_RT_FROMCONTACT, sip_poke_peer(), SIP_REALTIME, sip_pvt::sipoptions, sip_peer::sipoptions, strcasestr(), sip_peer::useragent, sip_peer::username, and VERBOSE_PREFIX_3.

Referenced by register_verify().

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

static void parse_request ( struct sip_request req  )  [static]

parse_request: Parse a SIP message ----

Definition at line 3366 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, and SIP_MAX_LINES.

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

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

unsigned int parse_sip_options ( struct sip_pvt pvt,
char *  supported 
)

parse_sip_options: Parse supported header in incoming packet

Definition at line 1001 of file chan_sip.c.

References ast_log(), ast_strdupa, ast_strlen_zero(), sip_pvt::callid, LOG_DEBUG, option_debug, sip_options, sip_pvt::sipoptions, and text.

Referenced by handle_request_invite().

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

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

peer_status: Report Peer status in character string

Definition at line 7492 of file chan_sip.c.

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

07493 {
07494    int res = 0;
07495    if (peer->maxms) {
07496       if (peer->lastms < 0) {
07497          ast_copy_string(status, "UNREACHABLE", statuslen);
07498       } else if (peer->lastms > peer->maxms) {
07499          snprintf(status, statuslen, "LAGGED (%d ms)", peer->lastms);
07500          res = 1;
07501       } else if (peer->lastms) {
07502          snprintf(status, statuslen, "OK (%d ms)", peer->lastms);
07503          res = 1;
07504       } else {
07505          ast_copy_string(status, "UNKNOWN", statuslen);
07506       }
07507    } else { 
07508       ast_copy_string(status, "Unmonitored", statuslen);
07509       /* Checking if port is 0 */
07510       res = -1;
07511    }
07512    return res;
07513 }

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

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

Referenced by _sip_show_peer(), and sip_show_settings().

07932 {
07933    int x, codec;
07934 
07935    for(x = 0; x < 32 ; x++) {
07936       codec = ast_codec_pref_index(pref, x);
07937       if (!codec)
07938          break;
07939       ast_cli(fd, "%s", ast_getformatname(codec));
07940       if (x < 31 && ast_codec_pref_index(pref, x + 1))
07941          ast_cli(fd, ",");
07942    }
07943    if (!x)
07944       ast_cli(fd, "none");
07945 }

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

print_group: Print call group and pickup group ---

Definition at line 7748 of file chan_sip.c.

References ast_cli(), and ast_print_group().

Referenced by _sip_show_peer(), and sip_show_user().

07749 {
07750    char buf[256];
07751    ast_cli(fd, crlf ? "%s\r\n" : "%s\n", ast_print_group(buf, sizeof(buf), group) );
07752 }

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

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

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

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

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

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

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

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

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

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

receive_message: Receive SIP MESSAGE method messages ---

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

07388 {
07389    char buf[1024];
07390    struct ast_frame f;
07391    char *content_type;
07392 
07393    content_type = get_header(req, "Content-Type");
07394    if (strcmp(content_type, "text/plain")) { /* No text/plain attachment */
07395       transmit_response(p, "415 Unsupported Media Type", req); /* Good enough, or? */
07396       ast_set_flag(p, SIP_NEEDDESTROY);
07397       return;
07398    }
07399 
07400    if (get_msg_text(buf, sizeof(buf), req)) {
07401       ast_log(LOG_WARNING, "Unable to retrieve text from %s\n", p->callid);
07402       transmit_response(p, "202 Accepted", req);
07403       ast_set_flag(p, SIP_NEEDDESTROY);
07404       return;
07405    }
07406 
07407    if (p->owner) {
07408       if (sip_debug_test_pvt(p))
07409          ast_verbose("Message received: '%s'\n", buf);
07410       memset(&f, 0, sizeof(f));
07411       f.frametype = AST_FRAME_TEXT;
07412       f.subclass = 0;
07413       f.offset = 0;
07414       f.data = buf;
07415       f.datalen = strlen(buf);
07416       ast_queue_frame(p->owner, &f);
07417       transmit_response(p, "202 Accepted", req); /* We respond 202 accepted, since we relay the message */
07418    } else { /* Message outside of a call, we do not support that */
07419       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);
07420       transmit_response(p, "405 Method Not Allowed", req); /* Good enough, or? */
07421    }
07422    ast_set_flag(p, SIP_NEEDDESTROY);
07423    return;
07424 }

static void reg_source_db ( struct sip_peer peer  )  [static]

reg_source_db: Get registration details from Asterisk DB ---

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

05776 {
05777    char data[256];
05778    char iabuf[INET_ADDRSTRLEN];
05779    struct in_addr in;
05780    int expiry;
05781    int port;
05782    char *scan, *addr, *port_str, *expiry_str, *username, *contact;
05783 
05784    if (ast_test_flag(&(peer->flags_page2), SIP_PAGE2_RT_FROMCONTACT)) 
05785       return;
05786    if (ast_db_get("SIP/Registry", peer->name, data, sizeof(data)))
05787       return;
05788 
05789    scan = data;
05790    addr = strsep(&scan, ":");
05791    port_str = strsep(&scan, ":");
05792    expiry_str = strsep(&scan, ":");
05793    username = strsep(&scan, ":");
05794    contact = scan;   /* Contact include sip: and has to be the last part of the database entry as long as we use : as a separator */
05795 
05796    if (!inet_aton(addr, &in))
05797       return;
05798 
05799    if (port_str)
05800       port = atoi(port_str);
05801    else
05802       return;
05803 
05804    if (expiry_str)
05805       expiry = atoi(expiry_str);
05806    else
05807       return;
05808 
05809    if (username)
05810       ast_copy_string(peer->username, username, sizeof(peer->username));
05811    if (contact)
05812       ast_copy_string(peer->fullcontact, contact, sizeof(peer->fullcontact));
05813 
05814    if (option_verbose > 2)
05815       ast_verbose(VERBOSE_PREFIX_3 "SIP Seeding peer from astdb: '%s' at %s@%s:%d for %d\n",
05816              peer->name, peer->username, ast_inet_ntoa(iabuf, sizeof(iabuf), in), port, expiry);
05817 
05818    memset(&peer->addr, 0, sizeof(peer->addr));
05819    peer->addr.sin_family = AF_INET;
05820    peer->addr.sin_addr = in;
05821    peer->addr.sin_port = htons(port);
05822    if (sipsock < 0) {
05823       /* SIP isn't up yet, so schedule a poke only, pretty soon */
05824       if (peer->pokeexpire > -1)
05825          ast_sched_del(sched, peer->pokeexpire);
05826       peer->pokeexpire = ast_sched_add(sched, thread_safe_rand() % 5000 + 1, sip_poke_peer_s, peer);
05827    } else
05828       sip_poke_peer(peer);
05829    if (peer->expire > -1)
05830       ast_sched_del(sched, peer->expire);
05831    peer->expire = ast_sched_add(sched, (expiry + 10) * 1000, expire_register, peer);
05832    register_peer_exten(peer, 1);
05833 }

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

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

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

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

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

static char* regstate2str ( int  regstate  )  [static]

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

05316 {
05317    switch(regstate) {
05318    case REG_STATE_FAILED:
05319       return "Failed";
05320    case REG_STATE_UNREGISTERED:
05321       return "Unregistered";
05322    case REG_STATE_REGSENT:
05323       return "Request Sent";
05324    case REG_STATE_AUTHSENT:
05325       return "Auth. Sent";
05326    case REG_STATE_REGISTERED:
05327       return "Registered";
05328    case REG_STATE_REJECTED:
05329       return "Rejected";
05330    case REG_STATE_TIMEOUT:
05331       return "Timeout";
05332    case REG_STATE_NOAUTH:
05333       return "No Authentication";
05334    default:
05335       return "Unknown";
05336    }
05337 }

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

References sip_reload().

13346 {
13347    return sip_reload(0, 0, NULL);
13348 }

static int reload_config ( void   )  [static]

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

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

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

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

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

Referenced by do_proxy_auth(), and do_register_auth().

09060 {
09061    char tmp[512];
09062    char *c;
09063    char oldnonce[256];
09064 
09065    /* table of recognised keywords, and places where they should be copied */
09066    const struct x {
09067       const char *key;
09068       char *dst;
09069       int dstlen;
09070    } *i, keys[] = {
09071       { "realm=", p->realm, sizeof(p->realm) },
09072       { "nonce=", p->nonce, sizeof(p->nonce) },
09073       { "opaque=", p->opaque, sizeof(p->opaque) },
09074       { "qop=", p->qop, sizeof(p->qop) },
09075       { "domain=", p->domain, sizeof(p->domain) },
09076       { NULL, NULL, 0 },
09077    };
09078 
09079    ast_copy_string(tmp, get_header(req, header), sizeof(tmp));
09080    if (ast_strlen_zero(tmp)) 
09081       return -1;
09082    if (strncasecmp(tmp, "Digest ", strlen("Digest "))) {
09083       ast_log(LOG_WARNING, "missing Digest.\n");
09084       return -1;
09085    }
09086    c = tmp + strlen("Digest ");
09087    for (i = keys; i->key != NULL; i++)
09088       i->dst[0] = '\0'; /* init all to empty strings */
09089    ast_copy_string(oldnonce, p->nonce, sizeof(oldnonce));
09090    while (c && *(c = ast_skip_blanks(c))) {  /* lookup for keys */
09091       for (i = keys; i->key != NULL; i++) {
09092          char *src, *separator;
09093          if (strncasecmp(c, i->key, strlen(i->key)) != 0)
09094             continue;
09095          /* Found. Skip keyword, take text in quotes or up to the separator. */
09096          c += strlen(i->key);
09097          if (*c == '\"') {
09098             src = ++c;
09099             separator = "\"";
09100          } else {
09101             src = c;
09102             separator = ",";
09103          }
09104          strsep(&c, separator); /* clear separator and move ptr */
09105          ast_copy_string(i->dst, src, i->dstlen);
09106          break;
09107       }
09108       if (i->key == NULL) /* not found, try ',' */
09109          strsep(&c, ",");
09110    }
09111    /* Reset nonce count */
09112    if (strcmp(p->nonce, oldnonce)) 
09113       p->noncecount = 0;
09114 
09115    /* Save auth data for following registrations */
09116    if (p->registry) {
09117       struct sip_registry *r = p->registry;
09118 
09119       if (strcmp(r->nonce, p->nonce)) {
09120          ast_copy_string(r->realm, p->realm, sizeof(r->realm));
09121          ast_copy_string(r->nonce, p->nonce, sizeof(r->nonce));
09122          ast_copy_string(r->domain, p->domain, sizeof(r->domain));
09123          ast_copy_string(r->opaque, p->opaque, sizeof(r->opaque));
09124          ast_copy_string(r->qop, p->qop, sizeof(r->qop));
09125          r->noncecount = 0;
09126       }
09127    }
09128    return build_reply_digest(p, sipmethod, digest, digest_len); 
09129 }

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

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

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

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

static int restart_monitor ( void   )  [static]

restart_monitor: Start the channel monitor thread ---

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

11586 {
11587    /* If we're supposed to be stopped -- stay stopped */
11588    if (monitor_thread == AST_PTHREADT_STOP)
11589       return 0;
11590    if (ast_mutex_lock(&monlock)) {
11591       ast_log(LOG_WARNING, "Unable to lock monitor\n");
11592       return -1;
11593    }
11594    if (monitor_thread == pthread_self()) {
11595       ast_mutex_unlock(&monlock);
11596       ast_log(LOG_WARNING, "Cannot kill myself\n");
11597       return -1;
11598    }
11599    if (monitor_thread != AST_PTHREADT_NULL) {
11600       /* Wake up the thread */
11601       pthread_kill(monitor_thread, SIGURG);
11602    } else {
11603       /* Start a new monitor */
11604       if (ast_pthread_create(&monitor_thread, NULL, do_monitor, NULL) < 0) {
11605          ast_mutex_unlock(&monlock);
11606          ast_log(LOG_ERROR, "Unable to start monitor thread.\n");
11607          return -1;
11608       }
11609    }
11610    ast_mutex_unlock(&monlock);
11611    return 0;
11612 }

static int retrans_pkt ( void *  data  )  [static]

retrans_pkt: Retransmit SIP message if no answer ---

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

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

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

Definition at line 2906 of file chan_sip.c.

References sip_request::sdp_start.

02907 {
02908    *iterator = req->sdp_start;
02909 }

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

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

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

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

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

set_destination: Set destination from SIP URI ---

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

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

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

sip_addheader: Add a SIP header ---

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

13084 {
13085    int no = 0;
13086    int ok = 0;
13087    char varbuf[128];
13088    
13089    if (ast_strlen_zero((char *)data)) {
13090       ast_log(LOG_WARNING, "This application requires the argument: Header\n");
13091       return 0;
13092    }
13093    ast_mutex_lock(&chan->lock);
13094 
13095    /* Check for headers */
13096    while (!ok && no <= 50) {
13097       no++;
13098       snprintf(varbuf, sizeof(varbuf), "_SIPADDHEADER%02d", no);
13099       if (ast_strlen_zero(pbx_builtin_getvar_helper(chan, varbuf + 1)))
13100          ok = 1;
13101    }
13102    if (ok) {
13103       pbx_builtin_setvar_helper (chan, varbuf, (char *)data);
13104       if (sipdebug)
13105          ast_log(LOG_DEBUG,"SIP Header added \"%s\" as %s\n", (char *) data, varbuf);
13106    } else {
13107       ast_log(LOG_WARNING, "Too many SIP headers added, max 50\n");
13108    }
13109    ast_mutex_unlock(&chan->lock);
13110    return 0;
13111 }

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

sip_addrcmp: Support routine for find_peer ---

Definition at line 1754 of file chan_sip.c.

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

Referenced by find_peer().

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

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

References 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, free, global_flags, iflist, io, LOG_DEBUG, LOG_WARNING, make_our_tag(), NONE, option_debug, prefs, sched, SIP_DTMF, SIP_DTMF_AUTO, SIP_DTMF_RFC2833, SIP_FLAGS_TO_COPY, sip_methods, SIP_NAT, SIP_NAT_ROUTE, SIP_OPTIONS, SIP_REGISTER, text, and thread_safe_rand().

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

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

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

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

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

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

static int sip_cancel_destroy ( struct sip_pvt p  )  [static]

sip_cancel_destroy: Cancel destruction of SIP call ---

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

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

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

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

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

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

sip_debug_test_pvt: Test PVT for debugging output

Definition at line 1062 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(), build_route(), check_via(), do_register_auth(), get_also_info(), get_destination(), get_rdnis(), get_refer_info(), handle_request(), process_sdp(), receive_message(), retrans_pkt(), send_request(), send_response(), set_destination(), sip_scheddestroy(), sip_sendtext(), transmit_invite(), transmit_notify_with_mwi(), transmit_notify_with_sipfrag(), transmit_register(), transmit_reinvite_with_sdp(), and transmit_sip_request().

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

static void sip_destroy ( struct sip_pvt p  )  [static]

sip_destroy: Destroy SIP call structure ---

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

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

static void sip_destroy_peer ( struct sip_peer peer  )  [static]

sip_destroy_peer: Destroy peer object from memory

Definition at line 1645 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(), do_monitor(), expire_register(), function_sippeer(), register_verify(), reload_config(), sip_devicestate(), sip_do_debug_peer(), sip_prune_realtime(), unload_module(), and update_call_counter().

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

static void sip_destroy_user ( struct sip_user user  )  [static]

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

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

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

static int sip_devicestate ( void *  data  )  [static]

sip_devicestate: Part of PBX channel interface ---

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

11712 {
11713    char *host;
11714    char *tmp;
11715 
11716    struct hostent *hp;
11717    struct ast_hostent ahp;
11718    struct sip_peer *p;
11719 
11720    int res = AST_DEVICE_INVALID;
11721 
11722    host = ast_strdupa(data);
11723    if ((tmp = strchr(host, '@')))
11724       host = tmp + 1;
11725 
11726    if (option_debug > 2) 
11727       ast_log(LOG_DEBUG, "Checking device state for peer %s\n", host);
11728 
11729    if ((p = find_peer(host, NULL, 1))) {
11730       if (p->addr.sin_addr.s_addr || p->defaddr.sin_addr.s_addr) {
11731          /* we have an address for the peer */
11732          /* if qualify is turned on, check the status */
11733          if (p->maxms && (p->lastms > p->maxms)) {
11734             res = AST_DEVICE_UNAVAILABLE;
11735          } else {
11736             /* qualify is not on, or the peer is responding properly */
11737             /* check call limit */
11738             if (p->call_limit && (p->inUse == p->call_limit))
11739                res = AST_DEVICE_BUSY;
11740             else if (p->call_limit && p->inUse)
11741                res = AST_DEVICE_INUSE;
11742             else if (p->call_limit)
11743                res = AST_DEVICE_NOT_INUSE;
11744             else
11745                res = AST_DEVICE_UNKNOWN;
11746          }
11747       } else {
11748          /* there is no address, it's unavailable */
11749          res = AST_DEVICE_UNAVAILABLE;
11750       }
11751       ASTOBJ_UNREF(p,sip_destroy_peer);
11752    } else {
11753       hp = ast_gethostbyname(host, &ahp);
11754       if (hp)
11755          res = AST_DEVICE_UNKNOWN;
11756    }
11757 
11758    return res;
11759 }

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

sip_do_debug: Turn on SIP debugging (CLI command)

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

08891 {
08892    int oldsipdebug = sipdebug & SIP_DEBUG_CONSOLE;
08893    if (argc != 2) {
08894       if (argc != 4) 
08895          return RESULT_SHOWUSAGE;
08896       else if (strncmp(argv[2], "ip\0", 3) == 0)
08897          return sip_do_debug_ip(fd, argc, argv);
08898       else if (strncmp(argv[2], "peer\0", 5) == 0)
08899          return sip_do_debug_peer(fd, argc, argv);
08900       else return RESULT_SHOWUSAGE;
08901    }
08902    sipdebug |= SIP_DEBUG_CONSOLE;
08903    memset(&debugaddr, 0, sizeof(debugaddr));
08904    if (oldsipdebug)
08905       ast_cli(fd, "SIP Debugging re-enabled\n");
08906    else
08907       ast_cli(fd, "SIP Debugging enabled\n");
08908    return RESULT_SUCCESS;
08909 }

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

sip_do_debug: Enable SIP Debugging in CLI ---

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

08835 {
08836    struct hostent *hp;
08837    struct ast_hostent ahp;
08838    char iabuf[INET_ADDRSTRLEN];
08839    int port = 0;
08840    char *p, *arg;
08841 
08842    if (argc != 4)
08843       return RESULT_SHOWUSAGE;
08844    arg = argv[3];
08845    p = strstr(arg, ":");
08846    if (p) {
08847       *p = '\0';
08848       p++;
08849       port = atoi(p);
08850    }
08851    hp = ast_gethostbyname(arg, &ahp);
08852    if (hp == NULL)  {
08853       return RESULT_SHOWUSAGE;
08854    }
08855    debugaddr.sin_family = AF_INET;
08856    memcpy(&debugaddr.sin_addr, hp->h_addr, sizeof(debugaddr.sin_addr));
08857    debugaddr.sin_port = htons(port);
08858    if (port == 0)
08859       ast_cli(fd, "SIP Debugging Enabled for IP: %s\n", ast_inet_ntoa(iabuf, sizeof(iabuf), debugaddr.sin_addr));
08860    else
08861       ast_cli(fd, "SIP Debugging Enabled for IP: %s:%d\n", ast_inet_ntoa(iabuf, sizeof(iabuf), debugaddr.sin_addr), port);
08862    sipdebug |= SIP_DEBUG_CONSOLE;
08863    return RESULT_SUCCESS;
08864 }

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

08868 {
08869    struct sip_peer *peer;
08870    char iabuf[INET_ADDRSTRLEN];
08871    if (argc != 4)
08872       return RESULT_SHOWUSAGE;
08873    peer = find_peer(argv[3], NULL, 1);
08874    if (peer) {
08875       if (peer->addr.sin_addr.s_addr) {
08876          debugaddr.sin_family = AF_INET;
08877          memcpy(&debugaddr.sin_addr, &peer->addr.sin_addr, sizeof(debugaddr.sin_addr));
08878          debugaddr.sin_port = peer->addr.sin_port;
08879          ast_cli(fd, "SIP Debugging Enabled for IP: %s:%d\n", ast_inet_ntoa(iabuf, sizeof(iabuf), debugaddr.sin_addr), ntohs(debugaddr.sin_port));
08880          sipdebug |= SIP_DEBUG_CONSOLE;
08881       } else
08882          ast_cli(fd, "Unable to get IP address of peer '%s'\n", argv[3]);
08883       ASTOBJ_UNREF(peer,sip_destroy_peer);
08884    } else
08885       ast_cli(fd, "No such peer '%s'\n", argv[3]);
08886    return RESULT_SUCCESS;
08887 }

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

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

Definition at line 8969 of file chan_sip.c.

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

08970 {
08971    if (argc != 2) {
08972       return RESULT_SHOWUSAGE;
08973    }
08974    recordhistory = 1;
08975    ast_cli(fd, "SIP History Recording Enabled (use 'sip show history')\n");
08976    return RESULT_SUCCESS;
08977 }

static int sip_do_reload ( void   )  [static]

sip_do_reload: Reload module

Definition at line 13297 of file chan_sip.c.

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

Referenced by do_monitor().

13298 {
13299    clear_realm_authentication(authl);
13300    clear_sip_domains();
13301    authl = NULL;
13302 
13303    /* First, destroy all outstanding registry calls */
13304    /* This is needed, since otherwise active registry entries will not be destroyed */
13305    ASTOBJ_CONTAINER_TRAVERSE(&regl, 1, do {
13306       ASTOBJ_RDLOCK(iterator);
13307       if (iterator->call) {
13308          if (option_debug > 2)
13309             ast_log(LOG_DEBUG, "Destroying active SIP dialog for registry %s@%s\n", iterator->username, iterator->hostname);
13310          /* This will also remove references to the registry */
13311          sip_destroy(iterator->call);
13312       }
13313       ASTOBJ_UNLOCK(iterator);
13314    } while(0));
13315 
13316    ASTOBJ_CONTAINER_DESTROYALL(&userl, sip_destroy_user);
13317    ASTOBJ_CONTAINER_DESTROYALL(&regl, sip_registry_destroy);
13318    ASTOBJ_CONTAINER_MARKALL(&peerl);
13319    reload_config();
13320    /* Prune peers who still are supposed to be deleted */
13321    ASTOBJ_CONTAINER_PRUNE_MARKED(&peerl, sip_destroy_peer);
13322 
13323    sip_poke_all_peers();
13324    sip_send_all_registers();
13325 
13326    return 0;
13327 }

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

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

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

13034 {
13035    struct sip_pvt *p;
13036    char *mode;
13037    if (data)
13038       mode = (char *)data;
13039    else {
13040       ast_log(LOG_WARNING, "This application requires the argument: info, inband, rfc2833\n");
13041       return 0;
13042    }
13043    ast_mutex_lock(&chan->lock);
13044    if (chan->type != channeltype) {
13045       ast_log(LOG_WARNING, "Call this application only on SIP incoming calls\n");
13046       ast_mutex_unlock(&chan->lock);
13047       return 0;
13048    }
13049    p = chan->tech_pvt;
13050    if (!p) {
13051       ast_mutex_unlock(&chan->lock);
13052       return 0;
13053    }
13054    ast_mutex_lock(&p->lock);
13055    if (!strcasecmp(mode,"info")) {
13056       ast_clear_flag(p, SIP_DTMF);
13057       ast_set_flag(p, SIP_DTMF_INFO);
13058    } else if (!strcasecmp(mode,"rfc2833")) {
13059       ast_clear_flag(p, SIP_DTMF);
13060       ast_set_flag(p, SIP_DTMF_RFC2833);
13061    } else if (!strcasecmp(mode,"inband")) { 
13062       ast_clear_flag(p, SIP_DTMF);
13063       ast_set_flag(p, SIP_DTMF_INBAND);
13064    } else
13065       ast_log(LOG_WARNING, "I don't know about this dtmf mode: %s\n",mode);
13066    if (ast_test_flag(p, SIP_DTMF) == SIP_DTMF_INBAND) {
13067       if (!p->vad) {
13068          p->vad = ast_dsp_new();
13069          ast_dsp_set_features(p->vad, DSP_FEATURE_DTMF_DETECT);
13070       }
13071    } else {
13072       if (p->vad) {
13073          ast_dsp_free(p->vad);
13074          p->vad = NULL;
13075       }
13076    }
13077    ast_mutex_unlock(&p->lock);
13078    ast_mutex_unlock(&chan->lock);
13079    return 0;
13080 }

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

08716 {
08717    int x;
08718    struct sip_history *hist;
08719 
08720    if (!dialog)
08721       return;
08722 
08723    ast_log(LOG_DEBUG, "\n---------- SIP HISTORY for '%s' \n", dialog->callid);
08724    if (dialog->subscribed)
08725       ast_log(LOG_DEBUG, "  * Subscription\n");
08726    else
08727       ast_log(LOG_DEBUG, "  * SIP Call\n");
08728    x = 0;
08729    hist = dialog->history;
08730    while(hist) {
08731       x++;
08732       ast_log(LOG_DEBUG, "  %d. %s\n", x, hist->event);
08733       hist = hist->next;
08734    }
08735    if (!x)
08736       ast_log(LOG_DEBUG, "Call '%s' has no history\n", dialog->callid);
08737    ast_log(LOG_DEBUG, "\n---------- END SIP HISTORY for '%s' \n", dialog->callid);
08738    
08739 }

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

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

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

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

13249 {
13250    struct sip_pvt *p = chan->tech_pvt;
13251    return p->peercapability;  
13252 }

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

12926 {
12927    struct sip_pvt *p;
12928    struct ast_rtp *rtp = NULL;
12929    p = chan->tech_pvt;
12930    if (!p)
12931       return NULL;
12932    ast_mutex_lock(&p->lock);
12933    if (p->rtp && ast_test_flag(p, SIP_CAN_REINVITE))
12934       rtp =  p->rtp;
12935    ast_mutex_unlock(&p->lock);
12936    return rtp;
12937 }

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

12941 {
12942    struct sip_pvt *p;
12943    struct ast_rtp *rtp = NULL;
12944    p = chan->tech_pvt;
12945    if (!p)
12946       return NULL;
12947 
12948    ast_mutex_lock(&p->lock);
12949    if (p->vrtp && ast_test_flag(p, SIP_CAN_REINVITE))
12950       rtp = p->vrtp;
12951    ast_mutex_unlock(&p->lock);
12952    return rtp;
12953 }

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

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

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

13115 {
13116    char *argv, *varname = NULL, *header = NULL, *content, *options = NULL;
13117    static int dep_warning = 0;
13118    struct sip_pvt *p;
13119    int priority_jump = 0;
13120    
13121    if (!dep_warning) {
13122       ast_log(LOG_WARNING, "SIPGetHeader is deprecated, use the SIP_HEADER function instead.\n");
13123       dep_warning = 1;
13124    }
13125 
13126    argv = ast_strdupa(data);
13127    if (!argv) {
13128       ast_log(LOG_DEBUG, "Memory allocation failed\n");
13129       return 0;
13130    }
13131 
13132    if (strchr (argv, '=') ) { /* Pick out argument */
13133       varname = strsep (&argv, "=");
13134       if (strchr(argv, '|')) {
13135          header = strsep (&argv, "|");
13136          options = strsep (&argv, "\0");
13137       } else {
13138          header = strsep (&argv, "\0");
13139       }
13140 
13141    }
13142 
13143    if (!varname || !header) {
13144       ast_log(LOG_DEBUG, "SIPGetHeader: Ignoring command, Syntax error in argument\n");
13145       return 0;
13146    }
13147 
13148    if (options) {
13149       if (strchr(options, 'j'))
13150          priority_jump = 1;
13151    }
13152 
13153    ast_mutex_lock(&chan->lock);
13154    if (chan->type != channeltype) {
13155       ast_log(LOG_WARNING, "Call this application only on incoming SIP calls\n");
13156       ast_mutex_unlock(&chan->lock);
13157       return 0;
13158    }
13159 
13160    p = chan->tech_pvt;
13161    content = get_header(&p->initreq, header);   /* Get the header */
13162    if (!ast_strlen_zero(content)) {
13163       pbx_builtin_setvar_helper(chan, varname, content);
13164       if (option_verbose > 2)
13165          ast_verbose(VERBOSE_PREFIX_3 "SIPGetHeader: set variable %s to %s\n", varname, content);
13166       pbx_builtin_setvar_helper(chan, "SIPGETSTATUS", "FOUND");
13167    } else {
13168       ast_log(LOG_WARNING,"SIP Header %s not found for channel variable %s\n", header, varname);
13169       if (priority_jump || option_priority_jumping) {
13170          /* Goto priority n+101 if it exists, where n is the current priority number */
13171          ast_goto_if_exists(chan, chan->context, chan->exten, chan->priority + 101);
13172       }
13173       pbx_builtin_setvar_helper(chan, "SIPGETSTATUS", "NOTFOUND");
13174    }
13175    
13176    ast_mutex_unlock(&chan->lock);
13177    return 0;
13178 }

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

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

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

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

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

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

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

sip_no_debug: Disable SIP Debugging in CLI ---

Definition at line 8991 of file chan_sip.c.

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

08993 {
08994    if (argc != 3)
08995       return RESULT_SHOWUSAGE;
08996    sipdebug &= ~SIP_DEBUG_CONSOLE;
08997    ast_cli(fd, "SIP Debugging Disabled\n");
08998    return RESULT_SUCCESS;
08999 }

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

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

Definition at line 8980 of file chan_sip.c.

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

08981 {
08982    if (argc != 3) {
08983       return RESULT_SHOWUSAGE;
08984    }
08985    recordhistory = 0;
08986    ast_cli(fd, "SIP History Recording Disabled\n");
08987    return RESULT_SUCCESS;
08988 }

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

sip_notify: Send SIP notify to peer

Definition at line 8912 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, RESULT_SUCCESS, sip_pvt::sa, sip_alloc(), sip_destroy(), SIP_NOTIFY, sip_scheddestroy(), transmit_sip_request(), var, and sip_pvt::via.

08913 {
08914    struct ast_variable *varlist;
08915    int i;
08916 
08917    if (argc < 4)
08918       return RESULT_SHOWUSAGE;
08919 
08920    if (!notify_types) {
08921       ast_cli(fd, "No %s file found, or no types listed there\n", notify_config);
08922       return RESULT_FAILURE;
08923    }
08924 
08925    varlist = ast_variable_browse(notify_types, argv[2]);
08926 
08927    if (!varlist) {
08928       ast_cli(fd, "Unable to find notify type '%s'\n", argv[2]);
08929       return RESULT_FAILURE;
08930    }
08931 
08932    for (i = 3; i < argc; i++) {
08933       struct sip_pvt *p;
08934       struct sip_request req;
08935       struct ast_variable *var;
08936 
08937       p = sip_alloc(NULL, NULL, 0, SIP_NOTIFY);
08938       if (!p) {
08939          ast_log(LOG_WARNING, "Unable to build sip pvt data for notify\n");
08940          return RESULT_FAILURE;
08941       }
08942 
08943       if (create_addr(p, argv[i])) {
08944          /* Maybe they're not registered, etc. */
08945          sip_destroy(p);
08946          ast_cli(fd, "Could not create address for '%s'\n", argv[i]);
08947          continue;
08948       }
08949 
08950       initreqprep(&req, p, SIP_NOTIFY);
08951 
08952       for (var = varlist; var; var = var->next)
08953          add_header(&req, var->name, var->value);
08954 
08955       add_blank_header(&req);
08956       /* Recalculate our side, and recalculate Call ID */
08957       if (ast_sip_ouraddrfor(&p->sa.sin_addr, &p->ourip))
08958          memcpy(&p->ourip, &__ourip, sizeof(p->ourip));
08959       build_via(p, p->via, sizeof(p->via));
08960       build_callid(p->callid, sizeof(p->callid), p->ourip, p->fromdomain);
08961       ast_cli(fd, "Sending NOTIFY of type '%s' to '%s'\n", argv[2], argv[i]);
08962       transmit_sip_request(p, &req);
08963       sip_scheddestroy(p, 15000);
08964    }
08965 
08966    return RESULT_SUCCESS;
08967 }

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

10243 {
10244    struct sip_dual *d;
10245    struct ast_channel *chan1m, *chan2m;
10246    pthread_t th;
10247    chan1m = ast_channel_alloc(0);
10248    chan2m = ast_channel_alloc(0);
10249    if ((!chan2m) || (!chan1m)) {
10250       if (chan1m)
10251          ast_hangup(chan1m);
10252       if (chan2m)
10253          ast_hangup(chan2m);
10254       return -1;
10255    }
10256    snprintf(chan1m->name, sizeof(chan1m->name), "Parking/%s", chan1->name);
10257    /* Make formats okay */
10258    chan1m->readformat = chan1->readformat;
10259    chan1m->writeformat = chan1->writeformat;
10260    ast_channel_masquerade(chan1m, chan1);
10261    /* Setup the extensions and such */
10262    ast_copy_string(chan1m->context, chan1->context, sizeof(chan1m->context));
10263    ast_copy_string(chan1m->exten, chan1->exten, sizeof(chan1m->exten));
10264    chan1m->priority = chan1->priority;
10265       
10266    /* We make a clone of the peer channel too, so we can play
10267       back the announcement */
10268    snprintf(chan2m->name, sizeof (chan2m->name), "SIPPeer/%s",chan2->name);
10269    /* Make formats okay */
10270    chan2m->readformat = chan2->readformat;
10271    chan2m->writeformat = chan2->writeformat;
10272    ast_channel_masquerade(chan2m, chan2);
10273    /* Setup the extensions and such */
10274    ast_copy_string(chan2m->context, chan2->context, sizeof(chan2m->context));
10275    ast_copy_string(chan2m->exten, chan2->exten, sizeof(chan2m->exten));
10276    chan2m->priority = chan2->priority;
10277    ast_mutex_lock(&chan2m->lock);
10278    if (ast_do_masquerade(chan2m)) {
10279       ast_log(LOG_WARNING, "Masquerade failed :(\n");
10280       ast_mutex_unlock(&chan2m->lock);
10281       ast_hangup(chan2m);
10282       return -1;
10283    }
10284    ast_mutex_unlock(&chan2m->lock);
10285    d = malloc(sizeof(struct sip_dual));
10286    if (d) {
10287       memset(d, 0, sizeof(*d));
10288       /* Save original request for followup */
10289       copy_request(&d->req, req);
10290       d->chan1 = chan1m;
10291       d->chan2 = chan2m;
10292       if (!ast_pthread_create(&th, NULL, sip_park_thread, d))
10293          return 0;
10294       free(d);
10295    }
10296    return -1;
10297 }

static void* sip_park_thread ( void *  stuff  )  [static]

sip_park_thread: Park SIP call support function

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

10220 {
10221    struct ast_channel *chan1, *chan2;
10222    struct sip_dual *d;
10223    struct sip_request req;
10224    int ext;
10225    int res;
10226    d = stuff;
10227    chan1 = d->chan1;
10228    chan2 = d->chan2;
10229    copy_request(&req, &d->req);
10230    free(d);
10231    ast_mutex_lock(&chan1->lock);
10232    ast_do_masquerade(chan1);
10233    ast_mutex_unlock(&chan1->lock);
10234    res = ast_park_call(chan1, chan2, 0, &ext);
10235    /* Then hangup */
10236    ast_hangup(chan2);
10237    ast_log(LOG_DEBUG, "Parked on extension '%d'\n", ext);
10238    return NULL;
10239 }

static void sip_poke_all_peers ( void   )  [static]

sip_poke_all_peers: Send a poke to all known peers

Definition at line 13264 of file chan_sip.c.

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

Referenced by load_module().

13265 {
13266    ASTOBJ_CONTAINER_TRAVERSE(&peerl, 1, do {
13267       ASTOBJ_WRLOCK(iterator);
13268       sip_poke_peer(iterator);
13269       ASTOBJ_UNLOCK(iterator);
13270    } while (0)
13271    );
13272 }

static int sip_poke_noanswer ( void *  data  )  [static]

sip_poke_noanswer: No answer to Qualify poke ---

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

11616 {
11617    struct sip_peer *peer = data;
11618    
11619    peer->pokeexpire = -1;
11620    if (peer->lastms > -1) {
11621       ast_log(LOG_NOTICE, "Peer '%s' is now UNREACHABLE!  Last qualify: %d\n", peer->name, peer->lastms);
11622       manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: SIP/%s\r\nPeerStatus: Unreachable\r\nTime: %d\r\n", peer->name, -1);
11623    }
11624    if (peer->call)
11625       sip_destroy(peer->call);
11626    peer->call = NULL;
11627    peer->lastms = -1;
11628    ast_device_state_changed("SIP/%s", peer->name);
11629    /* Try again quickly */
11630    peer->pokeexpire = ast_sched_add(sched, DEFAULT_FREQ_NOTOK, sip_poke_peer_s, peer);
11631    return 0;
11632 }

static int sip_poke_peer ( struct sip_peer peer  )  [static]

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

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

11638 {
11639    struct sip_pvt *p;
11640    if (!peer->maxms || !peer->addr.sin_addr.s_addr) {
11641       /* IF we have no IP, or this isn't to be monitored, return
11642         imeediately after clearing things out */
11643       if (peer->pokeexpire > -1)
11644          ast_sched_del(sched, peer->pokeexpire);
11645       peer->lastms = 0;
11646       peer->pokeexpire = -1;
11647       peer->call = NULL;
11648       return 0;
11649    }
11650    if (peer->call > 0) {
11651       if (sipdebug)
11652          ast_log(LOG_NOTICE, "Still have a QUALIFY dialog active, deleting\n");
11653       sip_destroy(peer->call);
11654    }
11655    p = peer->call = sip_alloc(NULL, NULL, 0, SIP_OPTIONS);
11656    if (!peer->call) {
11657       ast_log(LOG_WARNING, "Unable to allocate dialog for poking peer '%s'\n", peer->name);
11658       return -1;
11659    }
11660    memcpy(&p->sa, &peer->addr, sizeof(p->sa));
11661    memcpy(&p->recv, &peer->addr, sizeof(p->sa));
11662    ast_copy_flags(p, peer, SIP_FLAGS_TO_COPY);
11663 
11664    /* Send OPTIONs to peer's fullcontact */
11665    if (!ast_strlen_zero(peer->fullcontact)) {
11666       ast_copy_string (p->fullcontact, peer->fullcontact, sizeof(p->fullcontact));
11667    }
11668 
11669    if (!ast_strlen_zero(peer->tohost))
11670       ast_copy_string(p->tohost, peer->tohost, sizeof(p->tohost));
11671    else
11672       ast_inet_ntoa(p->tohost, sizeof(p->tohost), peer->addr.sin_addr);
11673 
11674    /* Recalculate our side, and recalculate Call ID */
11675    if (ast_sip_ouraddrfor(&p->sa.sin_addr,&p->ourip))
11676       memcpy(&p->ourip, &__ourip, sizeof(p->ourip));
11677    build_via(p, p->via, sizeof(p->via));
11678    build_callid(p->callid, sizeof(p->callid), p->ourip, p->fromdomain);
11679 
11680    if (peer->pokeexpire > -1)
11681       ast_sched_del(sched, peer->pokeexpire);
11682    p->peerpoke = peer;
11683    ast_set_flag(p, SIP_OUTGOING);
11684 #ifdef VOCAL_DATA_HACK
11685    ast_copy_string(p->username, "__VOCAL_DATA_SHOULD_READ_THE_SIP_SPEC__", sizeof(p->username));
11686    transmit_invite(p, SIP_INVITE, 0, 2);
11687 #else
11688    transmit_invite(p, SIP_OPTIONS, 0, 2);
11689 #endif
11690    gettimeofday(&peer->ps, NULL);
11691    peer->pokeexpire = ast_sched_add(sched, DEFAULT_MAXMS * 2, sip_poke_noanswer, peer);
11692 
11693    return 0;
11694 }

static int sip_poke_peer_s ( void *  data  )  [static]

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

05767 {
05768    struct sip_peer *peer = data;
05769    peer->pokeexpire = -1;
05770    sip_poke_peer(peer);
05771    return 0;
05772 }

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

References ast_cli(), ast_test_flag, ASTOBJ_CONTAINER_PRUNE_MARKED, ASTOBJ_CONTAINER_TRAVERSE, ASTOBJ_CONTAINER_UNLOCK, ASTOBJ_CONTAINER_WRLOCK, ASTOBJ_MARK, ASTOBJ_RDLOCK, ASTOBJ_UNLOCK, name, peerl, RESULT_SHOWUSAGE, sip_destroy_peer(), SIP_PAGE2_RTCACHEFRIENDS, and user.

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

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

sip_read: Read SIP RTP from channel

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

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

static int sip_reg_timeout ( void *  data  )  [static]

sip_reg_timeout: Registration timeout, register again

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

05378 {
05379 
05380    /* if we are here, our registration timed out, so we'll just do it over */
05381    struct sip_registry *r = ASTOBJ_REF((struct sip_registry *) data);
05382    struct sip_pvt *p;
05383    int res;
05384 
05385    /* if we couldn't get a reference to the registry object, punt */
05386    if (!r)
05387       return 0;
05388 
05389    ast_log(LOG_NOTICE, "   -- Registration for '%s@%s' timed out, trying again (Attempt #%d)\n", r->username, r->hostname, r->regattempts); 
05390    if (r->call) {
05391       /* Unlink us, destroy old call.  Locking is not relevant here because all this happens
05392          in the single SIP manager thread. */
05393       p = r->call;
05394       if (p->registry)
05395          ASTOBJ_UNREF(p->registry, sip_registry_destroy);
05396       r->call = NULL;
05397       ast_set_flag(p, SIP_NEEDDESTROY);   
05398       /* Pretend to ACK anything just in case */
05399       __sip_pretend_ack(p);
05400    }
05401    /* If we have a limit, stop registration and give up */
05402    if (global_regattempts_max && (r->regattempts > global_regattempts_max)) {
05403       /* Ok, enough is enough. Don't try any more */
05404       /* We could add an external notification here... 
05405          steal it from app_voicemail :-) */
05406       ast_log(LOG_NOTICE, "   -- Giving up forever trying to register '%s@%s'\n", r->username, r->hostname);
05407       r->regstate=REG_STATE_FAILED;
05408    } else {
05409       r->regstate=REG_STATE_UNREGISTERED;
05410       r->timeout = -1;
05411       res=transmit_register(r, SIP_REGISTER, NULL, NULL);
05412    }
05413    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));
05414    ASTOBJ_UNREF(r,sip_registry_destroy);
05415    return 0;
05416 }

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

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

Definition at line 3247 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(), sip_registry::expire, sip_registry::hostname, hostname, LOG_ERROR, LOG_WARNING, malloc, sip_registry::ocseq, sip_registry::portno, sip_registry::refresh, regl, sip_registry::secret, secret, sip_registry_destroy(), strsep(), sip_registry::timeout, sip_registry::username, and username.

Referenced by reload_config().

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

static void sip_registry_destroy ( struct sip_registry reg  )  [static]

sip_registry_destroy: Destroy registry object ---

Definition at line 2093 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(), handle_response_register(), sip_reg_timeout(), sip_register(), sip_reregister(), and unload_module().

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

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

sip_reload: Force reload of module from cli ---

Definition at line 13330 of file chan_sip.c.

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

Referenced by reload().

13331 {
13332 
13333    ast_mutex_lock(&sip_reload_lock);
13334    if (sip_reloading) {
13335       ast_verbose("Previous SIP reload not yet done\n");
13336    } else
13337       sip_reloading = 1;
13338    ast_mutex_unlock(&sip_reload_lock);
13339    restart_monitor();
13340 
13341    return 0;
13342 }

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

References __ourip, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL, AST_CAUSE_SWITCH_CONGESTION, AST_CAUSE_UNREGISTERED, AST_FORMAT_MAX_AUDIO, ast_getformatname(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_sip_ouraddrfor(), AST_STATE_DOWN, ast_strlen_zero(), ast_update_use_count(), build_callid(), build_via(), 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.

11764 {
11765    int oldformat;
11766    struct sip_pvt *p;
11767    struct ast_channel *tmpc = NULL;
11768    char *ext, *host;
11769    char tmp[256];
11770    char *dest = data;
11771 
11772    oldformat = format;
11773    format &= ((AST_FORMAT_MAX_AUDIO << 1) - 1);
11774    if (!format) {
11775       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));
11776       *cause = AST_CAUSE_BEARERCAPABILITY_NOTAVAIL;   /* Can't find codec to connect to host */
11777       return NULL;
11778    }
11779    p = sip_alloc(NULL, NULL, 0, SIP_INVITE);
11780    if (!p) {
11781       ast_log(LOG_ERROR, "Unable to build sip pvt data for '%s' (Out of memory)\n", (char *)data);
11782       *cause = AST_CAUSE_SWITCH_CONGESTION;
11783       return NULL;
11784    }
11785 
11786    p->options = calloc(1, sizeof(*p->options));
11787    if (!p->options) {
11788       sip_destroy(p);
11789       ast_log(LOG_ERROR, "Unable to build option SIP data structure - Out of memory\n");
11790       *cause = AST_CAUSE_SWITCH_CONGESTION;
11791       return NULL;
11792    }
11793 
11794    ast_copy_string(tmp, dest, sizeof(tmp));
11795    host = strchr(tmp, '@');
11796    if (host) {
11797       *host = '\0';
11798       host++;
11799       ext = tmp;
11800    } else {
11801       ext = strchr(tmp, '/');
11802       if (ext) {
11803          *ext++ = '\0';
11804          host = tmp;
11805       }
11806       else {
11807          host = tmp;
11808          ext = NULL;
11809       }
11810    }
11811 
11812    if (create_addr(p, host)) {
11813       *cause = AST_CAUSE_UNREGISTERED;
11814       sip_destroy(p);
11815       return NULL;
11816    }
11817    if (ast_strlen_zero(p->peername) && ext)
11818       ast_copy_string(p->peername, ext, sizeof(p->peername));
11819    /* Recalculate our side, and recalculate Call ID */
11820    if (ast_sip_ouraddrfor(&p->sa.sin_addr,&p->ourip))
11821       memcpy(&p->ourip, &__ourip, sizeof(p->ourip));
11822    build_via(p, p->via, sizeof(p->via));
11823    build_callid(p->callid, sizeof(p->callid), p->ourip, p->fromdomain);
11824    
11825    /* We have an extension to call, don't use the full contact here */
11826    /* This to enable dialling registered peers with extension dialling,
11827       like SIP/peername/extension   
11828       SIP/peername will still use the full contact */
11829    if (ext) {
11830       ast_copy_string(p->username, ext, sizeof(p->username));
11831       p->fullcontact[0] = 0;  
11832    }
11833 #if 0
11834    printf("Setting up to call extension '%s' at '%s'\n", ext ? ext : "<none>", host);
11835 #endif
11836    p->prefcodec = format;
11837    ast_mutex_lock(&p->lock);
11838    tmpc = sip_new(p, AST_STATE_DOWN, host);  /* Place the call */
11839    ast_mutex_unlock(&p->lock);
11840    if (!tmpc)
11841       sip_destroy(p);
11842    ast_update_use_count();
11843    restart_monitor();
11844    return tmpc;
11845 }

static int sip_reregister ( void *  data  )  [static]

sip_reregister: Update registration with SIP Proxy---

Definition at line 5342 of file chan_sip.c.

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

Referenced by handle_response_register(), and sip_send_all_registers().

05343 {
05344    /* if we are here, we know that we need to reregister. */
05345    struct sip_registry *r= ASTOBJ_REF((struct sip_registry *) data);
05346 
05347    /* if we couldn't get a reference to the registry object, punt */
05348    if (!r)
05349       return 0;
05350 
05351    if (r->call && recordhistory) {
05352       char tmp[80];
05353       snprintf(tmp, sizeof(tmp), "Account: %s@%s", r->username, r->hostname);
05354       append_history(r->call, "RegistryRenew", tmp);
05355    }
05356    /* Since registry's are only added/removed by the the monitor thread, this
05357       may be overkill to reference/dereference at all here */
05358    if (sipdebug)
05359       ast_log(LOG_NOTICE, "   -- Re-registration for  %s@%s\n", r->username, r->hostname);
05360 
05361    r->expire = -1;
05362    __sip_do_register(r);
05363    ASTOBJ_UNREF(r, sip_registry_destroy);
05364    return 0;
05365 }

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

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

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

sip_scheddestroy: Schedule destruction of SIP call ---

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

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

static void sip_send_all_registers ( void   )  [static]

sip_send_all_registers: Send all known registrations

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

13276 {
13277    int ms;
13278    int regspacing;
13279    if (!regobjs)
13280       return;
13281    regspacing = default_expiry * 1000/regobjs;
13282    if (regspacing > 100)
13283       regspacing = 100;
13284    ms = regspacing;
13285    ASTOBJ_CONTAINER_TRAVERSE(&regl, 1, do {
13286       ASTOBJ_WRLOCK(iterator);
13287       if (iterator->expire > -1)
13288          ast_sched_del(sched, iterator->expire);
13289       ms += regspacing;
13290       iterator->expire = ast_sched_add(sched, ms, sip_reregister, iterator);
13291       ASTOBJ_UNLOCK(iterator);
13292    } while (0)
13293    );
13294 }

static int sip_send_mwi_to_peer ( struct sip_peer peer  )  [static]

sip_send_mwi_to_peer: Send message waiting indication ---

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

Referenced by do_monitor().

11403 {
11404    /* Called with peerl lock, but releases it */
11405    struct sip_pvt *p;
11406    int newmsgs, oldmsgs;
11407 
11408    /* Check for messages */
11409    ast_app_messagecount(peer->mailbox, &newmsgs, &oldmsgs);
11410    
11411    time(&peer->lastmsgcheck);
11412    
11413    /* Return now if it's the same thing we told them last time */
11414    if (((newmsgs << 8) | (oldmsgs)) == peer->lastmsgssent) {
11415       return 0;
11416    }
11417    
11418    p = sip_alloc(NULL, NULL, 0, SIP_NOTIFY);
11419    if (!p) {
11420       ast_log(LOG_WARNING, "Unable to build sip pvt data for MWI\n");
11421       return -1;
11422    }
11423    peer->lastmsgssent = ((newmsgs << 8) | (oldmsgs));
11424    if (create_addr_from_peer(p, peer)) {
11425       /* Maybe they're not registered, etc. */
11426       sip_destroy(p);
11427       return 0;
11428    }
11429    /* Recalculate our side, and recalculate Call ID */
11430    if (ast_sip_ouraddrfor(&p->sa.sin_addr,&p->ourip))
11431       memcpy(&p->ourip, &__ourip, sizeof(p->ourip));
11432    build_via(p, p->via, sizeof(p->via));
11433    build_callid(p->callid, sizeof(p->callid), p->ourip, p->fromdomain);
11434    /* Send MWI */
11435    ast_set_flag(p, SIP_OUTGOING);
11436    transmit_notify_with_mwi(p, newmsgs, oldmsgs, peer->vmexten);
11437    sip_scheddestroy(p, 15000);
11438    return 0;
11439 }

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

sip_senddigit: Send DTMF character on SIP channel

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

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

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

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

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

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

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

12957 {
12958    struct sip_pvt *p;
12959    int changed = 0;
12960 
12961    p = chan->tech_pvt;
12962    if (!p) 
12963       return -1;
12964    ast_mutex_lock(&p->lock);
12965    if (rtp) {
12966       changed |= ast_rtp_get_peer(rtp, &p->redirip);
12967    } else if (p->redirip.sin_addr.s_addr || ntohs(p->redirip.sin_port) != 0) {
12968       memset(&p->redirip, 0, sizeof(p->redirip));
12969       changed = 1;
12970    }
12971    if (vrtp) {
12972       changed |= ast_rtp_get_peer(vrtp, &p->vredirip);
12973    } else if (p->vredirip.sin_addr.s_addr || ntohs(p->vredirip.sin_port) != 0) {
12974       memset(&p->vredirip, 0, sizeof(p->vredirip));
12975       changed = 1;
12976    }
12977    if (codecs && (p->redircodecs != codecs)) {
12978       p->redircodecs = codecs;
12979       changed = 1;
12980    }
12981    if (changed && !ast_test_flag(p, SIP_GOTREFER)) {
12982       if (!p->pendinginvite) {
12983          if (option_debug > 2) {
12984             char iabuf[INET_ADDRSTRLEN];
12985             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));
12986          }
12987          transmit_reinvite_with_sdp(p);
12988       } else if (!ast_test_flag(p, SIP_PENDINGBYE)) {
12989          if (option_debug > 2) {
12990             char iabuf[INET_ADDRSTRLEN];
12991             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));
12992          }
12993          ast_set_flag(p, SIP_NEEDREINVITE);  
12994       }
12995    }
12996    /* Reset lastrtprx timer */
12997    time(&p->lastrtprx);
12998    time(&p->lastrtptx);
12999    ast_mutex_unlock(&p->lock);
13000    return 0;
13001 }

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

sip_show_channel: Show details of one call ---

Definition at line 8605 of file chan_sip.c.

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

08606 {
08607    struct sip_pvt *cur;
08608    char iabuf[INET_ADDRSTRLEN];
08609    size_t len;
08610    int found = 0;
08611 
08612    if (argc != 4)
08613       return RESULT_SHOWUSAGE;
08614    len = strlen(argv[3]);
08615    ast_mutex_lock(&iflock);
08616    cur = iflist;
08617    while(cur) {
08618       if (!strncasecmp(cur->callid, argv[3],len)) {
08619          ast_cli(fd,"\n");
08620          if (cur->subscribed != NONE)
08621             ast_cli(fd, "  * Subscription (type: %s)\n", subscription_type2str(cur->subscribed));
08622          else
08623             ast_cli(fd, "  * SIP Call\n");
08624          ast_cli(fd, "  Direction:              %s\n", ast_test_flag(cur, SIP_OUTGOING)?"Outgoing":"Incoming");
08625          ast_cli(fd, "  Call-ID:                %s\n", cur->callid);
08626          ast_cli(fd, "  Our Codec Capability:   %d\n", cur->capability);
08627          ast_cli(fd, "  Non-Codec Capability:   %d\n", cur->noncodeccapability);
08628          ast_cli(fd, "  Their Codec Capability:   %d\n", cur->peercapability);
08629          ast_cli(fd, "  Joint Codec Capability:   %d\n", cur->jointcapability);
08630          ast_cli(fd, "  Format                  %s\n", ast_getformatname(cur->owner ? cur->owner->nativeformats : 0) );
08631          ast_cli(fd, "  Theoretical Address:    %s:%d\n", ast_inet_ntoa(iabuf, sizeof(iabuf), cur->sa.sin_addr), ntohs(cur->sa.sin_port));
08632          ast_cli(fd, "  Received Address:       %s:%d\n", ast_inet_ntoa(iabuf, sizeof(iabuf), cur->recv.sin_addr), ntohs(cur->recv.sin_port));
08633          ast_cli(fd, "  NAT Support:            %s\n", nat2str(ast_test_flag(cur, SIP_NAT)));
08634          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)" );
08635          ast_cli(fd, "  Our Tag:                %s\n", cur->tag);
08636          ast_cli(fd, "  Their Tag:              %s\n", cur->theirtag);
08637          ast_cli(fd, "  SIP User agent:         %s\n", cur->useragent);
08638          if (!ast_strlen_zero(cur->username))
08639             ast_cli(fd, "  Username:               %s\n", cur->username);
08640          if (!ast_strlen_zero(cur->peername))
08641             ast_cli(fd, "  Peername:               %s\n", cur->peername);
08642          if (!ast_strlen_zero(cur->uri))
08643             ast_cli(fd, "  Original uri:           %s\n", cur->uri);
08644          if (!ast_strlen_zero(cur->cid_num))
08645             ast_cli(fd, "  Caller-ID:              %s\n", cur->cid_num);
08646          ast_cli(fd, "  Need Destroy:           %d\n", ast_test_flag(cur, SIP_NEEDDESTROY));
08647          ast_cli(fd, "  Last Message:           %s\n", cur->lastmsg);
08648          ast_cli(fd, "  Promiscuous Redir:      %s\n", ast_test_flag(cur, SIP_PROMISCREDIR) ? "Yes" : "No");
08649          ast_cli(fd, "  Route:                  %s\n", cur->route ? cur->route->hop : "N/A");
08650          ast_cli(fd, "  DTMF Mode:              %s\n", dtmfmode2str(ast_test_flag(cur, SIP_DTMF)));
08651          ast_cli(fd, "  SIP Options:            ");
08652          if (cur->sipoptions) {
08653             int x;
08654             for (x=0 ; (x < (sizeof(sip_options) / sizeof(sip_options[0]))); x++) {
08655                if (cur->sipoptions & sip_options[x].id)
08656                   ast_cli(fd, "%s ", sip_options[x].text);
08657             }
08658          } else
08659             ast_cli(fd, "(none)\n");
08660          ast_cli(fd, "\n\n");
08661          found++;
08662       }
08663       cur = cur->next;
08664    }
08665    ast_mutex_unlock(&iflock);
08666    if (!found) 
08667       ast_cli(fd, "No such SIP Call ID starting with '%s'\n", argv[3]);
08668    return RESULT_SUCCESS;
08669 }

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

sip_show_channels: Show active SIP channels ---

Definition at line 8406 of file chan_sip.c.

References __sip_show_channels().

08407 {
08408         return __sip_show_channels(fd, argc, argv, 0);
08409 }

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

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

07962 {
07963    struct domain *d;
07964 
07965    if (AST_LIST_EMPTY(&domain_list)) {
07966       ast_cli(fd, "SIP Domain support not enabled.\n\n");
07967       return RESULT_SUCCESS;
07968    } else {
07969       ast_cli(fd, FORMAT, "Our local SIP domains:", "Context", "Set by");
07970       AST_LIST_LOCK(&domain_list);
07971       AST_LIST_TRAVERSE(&domain_list, d, list)
07972          ast_cli(fd, FORMAT, d->domain, ast_strlen_zero(d->context) ? "(default)": d->context,
07973             domain_mode_to_text(d->mode));
07974       AST_LIST_UNLOCK(&domain_list);
07975       ast_cli(fd, "\n");
07976       return RESULT_SUCCESS;
07977    }
07978 }

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

sip_show_history: Show history details of one call ---

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

08673 {
08674    struct sip_pvt *cur;
08675    struct sip_history *hist;
08676    size_t len;
08677    int x;
08678    int found = 0;
08679 
08680    if (argc != 4)
08681       return RESULT_SHOWUSAGE;
08682    if (!recordhistory)
08683       ast_cli(fd, "\n***Note: History recording is currently DISABLED.  Use 'sip history' to ENABLE.\n");
08684    len = strlen(argv[3]);
08685    ast_mutex_lock(&iflock);
08686    cur = iflist;
08687    while(cur) {
08688       if (!strncasecmp(cur->callid, argv[3], len)) {
08689          ast_cli(fd,"\n");
08690          if (cur->subscribed != NONE)
08691             ast_cli(fd, "  * Subscription\n");
08692          else
08693             ast_cli(fd, "  * SIP Call\n");
08694          x = 0;
08695          hist = cur->history;
08696          while(hist) {
08697             x++;
08698             ast_cli(fd, "%d. %s\n", x, hist->event);
08699             hist = hist->next;
08700          }
08701          if (!x)
08702             ast_cli(fd, "Call '%s' has no history\n", cur->callid);
08703          found++;
08704       }
08705       cur = cur->next;
08706    }
08707    ast_mutex_unlock(&iflock);
08708    if (!found) 
08709       ast_cli(fd, "No such SIP Call ID starting with '%s'\n", argv[3]);
08710    return RESULT_SUCCESS;
08711 }

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

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

07428                                                           {
07429 #define FORMAT  "%-25.25s %-15.15s %-15.15s \n"
07430 #define FORMAT2 "%-25.25s %-15.15s %-15.15s \n"
07431    char ilimits[40];
07432    char iused[40];
07433    int showall = 0;
07434 
07435    if (argc < 3) 
07436       return RESULT_SHOWUSAGE;
07437 
07438    if (argc == 4 && !strcmp(argv[3],"all")) 
07439          showall = 1;
07440    
07441    ast_cli(fd, FORMAT, "* User name", "In use", "Limit");
07442    ASTOBJ_CONTAINER_TRAVERSE(&userl, 1, do {
07443       ASTOBJ_RDLOCK(iterator);
07444       if (iterator->call_limit)
07445          snprintf(ilimits, sizeof(ilimits), "%d", iterator->call_limit);
07446       else 
07447          ast_copy_string(ilimits, "N/A", sizeof(ilimits));
07448       snprintf(iused, sizeof(iused), "%d", iterator->inUse);
07449       if (showall || iterator->call_limit)
07450          ast_cli(fd, FORMAT2, iterator->name, iused, ilimits);
07451       ASTOBJ_UNLOCK(iterator);
07452    } while (0) );
07453 
07454    ast_cli(fd, FORMAT, "* Peer name", "In use", "Limit");
07455 
07456    ASTOBJ_CONTAINER_TRAVERSE(&peerl, 1, do {
07457       ASTOBJ_RDLOCK(iterator);
07458       if (iterator->call_limit)
07459          snprintf(ilimits, sizeof(ilimits), "%d", iterator->call_limit);
07460       else 
07461          ast_copy_string(ilimits, "N/A", sizeof(ilimits));
07462       snprintf(iused, sizeof(iused), "%d", iterator->inUse);
07463       if (showall || iterator->call_limit)
07464          ast_cli(fd, FORMAT2, iterator->name, iused, ilimits);
07465       ASTOBJ_UNLOCK(iterator);
07466    } while (0) );
07467 
07468    return RESULT_SUCCESS;
07469 #undef FORMAT
07470 #undef FORMAT2
07471 }

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

sip_show_objects: List all allocated SIP Objects ---

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

07735 {
07736    char tmp[256];
07737    if (argc != 3)
07738       return RESULT_SHOWUSAGE;
07739    ast_cli(fd, "-= User objects: %d static, %d realtime =-\n\n", suserobjs, ruserobjs);
07740    ASTOBJ_CONTAINER_DUMP(fd, tmp, sizeof(tmp), &userl);
07741    ast_cli(fd, "-= Peer objects: %d static, %d realtime, %d autocreate =-\n\n", speerobjs, rpeerobjs, apeerobjs);
07742    ASTOBJ_CONTAINER_DUMP(fd, tmp, sizeof(tmp), &peerl);
07743    ast_cli(fd, "-= Registry objects: %d =-\n\n", regobjs);
07744    ASTOBJ_CONTAINER_DUMP(fd, tmp, sizeof(tmp), &regl);
07745    return RESULT_SUCCESS;
07746 }

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

sip_show_peer: Show one peer in detail ---

Definition at line 8018 of file chan_sip.c.

References _sip_show_peer().

08019 {
08020    return _sip_show_peer(0, fd, NULL, NULL, argc, argv);
08021 }

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

sip_show_peers: CLI Show Peers command

Definition at line 7595 of file chan_sip.c.

References _sip_show_peers().

07596 {
07597    return _sip_show_peers(fd, NULL, NULL, NULL, argc, argv);
07598 }

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

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

08271 {
08272 #define FORMAT2 "%-30.30s  %-12.12s  %8.8s %-20.20s\n"
08273 #define FORMAT  "%-30.30s  %-12.12s  %8d %-20.20s\n"
08274    char host[80];
08275 
08276    if (argc != 3)
08277       return RESULT_SHOWUSAGE;
08278    ast_cli(fd, FORMAT2, "Host", "Username", "Refresh", "State");
08279    ASTOBJ_CONTAINER_TRAVERSE(&regl, 1, do {
08280       ASTOBJ_RDLOCK(iterator);
08281       snprintf(host, sizeof(host), "%s:%d", iterator->hostname, iterator->portno ? iterator->portno : DEFAULT_SIP_PORT);
08282       ast_cli(fd, FORMAT, host, iterator->username, iterator->refresh, regstate2str(iterator->regstate));
08283       ASTOBJ_UNLOCK(iterator);
08284    } while(0));
08285    return RESULT_SUCCESS;
08286 #undef FORMAT
08287 #undef FORMAT2
08288 }

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

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

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

sip_show_subscriptions: Show active SIP subscriptions ---

Definition at line 8412 of file chan_sip.c.

References __sip_show_channels().

08413 {
08414         return __sip_show_channels(fd, argc, argv, 1);
08415 }

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

sip_show_user: Show one user in detail ---

Definition at line 8206 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, RESULT_SUCCESS, sip_destroy_user(), user, and ast_variable::value.

08207 {
08208    char cbuf[256];
08209    struct sip_user *user;
08210    struct ast_codec_pref *pref;
08211    struct ast_variable *v;
08212    int x = 0, codec = 0, load_realtime = 0;
08213 
08214    if (argc < 4)
08215       return RESULT_SHOWUSAGE;
08216 
08217    /* Load from realtime storage? */
08218    load_realtime = (argc == 5 && !strcmp(argv[4], "load")) ? 1 : 0;
08219 
08220    user = find_user(argv[3], load_realtime);
08221    if (user) {
08222       ast_cli(fd,"\n\n");
08223       ast_cli(fd, "  * Name       : %s\n", user->name);
08224       ast_cli(fd, "  Secret       : %s\n", ast_strlen_zero(user->secret)?"<Not set>":"<Set>");
08225       ast_cli(fd, "  MD5Secret    : %s\n", ast_strlen_zero(user->md5secret)?"<Not set>":"<Set>");
08226       ast_cli(fd, "  Context      : %s\n", user->context);
08227       ast_cli(fd, "  Language     : %s\n", user->language);
08228       if (!ast_strlen_zero(user->accountcode))
08229          ast_cli(fd, "  Accountcode  : %s\n", user->accountcode);
08230       ast_cli(fd, "  AMA flags    : %s\n", ast_cdr_flags2str(user->amaflags));
08231       ast_cli(fd, "  CallingPres  : %s\n", ast_describe_caller_presentation(user->callingpres));
08232       ast_cli(fd, "  Call limit   : %d\n", user->call_limit);
08233       ast_cli(fd, "  Callgroup    : ");
08234       print_group(fd, user->callgroup, 0);
08235       ast_cli(fd, "  Pickupgroup  : ");
08236       print_group(fd, user->pickupgroup, 0);
08237       ast_cli(fd, "  Callerid     : %s\n", ast_callerid_merge(cbuf, sizeof(cbuf), user->cid_name, user->cid_num, "<unspecified>"));
08238       ast_cli(fd, "  ACL          : %s\n", (user->ha?"Yes":"No"));
08239       ast_cli(fd, "  Codec Order  : (");
08240       pref = &user->prefs;
08241       for(x = 0; x < 32 ; x++) {
08242          codec = ast_codec_pref_index(pref,x);
08243          if (!codec)
08244             break;
08245          ast_cli(fd, "%s", ast_getformatname(codec));
08246          if (x < 31 && ast_codec_pref_index(pref,x+1))
08247             ast_cli(fd, "|");
08248       }
08249 
08250       if (!x)
08251          ast_cli(fd, "none");
08252       ast_cli(fd, ")\n");
08253 
08254       if (user->chanvars) {
08255          ast_cli(fd, "  Variables    :\n");
08256          for (v = user->chanvars ; v ; v = v->next)
08257             ast_cli(fd, "                 %s = %s\n", v->name, v->value);
08258       }
08259       ast_cli(fd,"\n");
08260       ASTOBJ_UNREF(user,sip_destroy_user);
08261    } else {
08262       ast_cli(fd,"User %s not found.\n", argv[3]);
08263       ast_cli(fd,"\n");
08264    }
08265 
08266    return RESULT_SUCCESS;
08267 }

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

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

Definition at line 7516 of file chan_sip.c.

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

07517 {
07518    regex_t regexbuf;
07519    int havepattern = 0;
07520 
07521 #define FORMAT  "%-25.25s  %-15.15s  %-15.15s  %-15.15s  %-5.5s%-10.10s\n"
07522 
07523    switch (argc) {
07524    case 5:
07525       if (!strcasecmp(argv[3], "like")) {
07526          if (regcomp(&regexbuf, argv[4], REG_EXTENDED | REG_NOSUB))
07527             return RESULT_SHOWUSAGE;
07528          havepattern = 1;
07529       } else
07530          return RESULT_SHOWUSAGE;
07531    case 3:
07532       break;
07533    default:
07534       return RESULT_SHOWUSAGE;
07535    }
07536 
07537    ast_cli(fd, FORMAT, "Username", "Secret", "Accountcode", "Def.Context", "ACL", "NAT");
07538    ASTOBJ_CONTAINER_TRAVERSE(&userl, 1, do {
07539       ASTOBJ_RDLOCK(iterator);
07540 
07541       if (havepattern && regexec(&regexbuf, iterator->name, 0, NULL, 0)) {
07542          ASTOBJ_UNLOCK(iterator);
07543          continue;
07544       }
07545 
07546       ast_cli(fd, FORMAT, iterator->name, 
07547          iterator->secret, 
07548          iterator->accountcode,
07549          iterator->context,
07550          iterator->ha ? "Yes" : "No",
07551          nat2str(ast_test_flag(iterator, SIP_NAT)));
07552       ASTOBJ_UNLOCK(iterator);
07553    } while (0)
07554    );
07555 
07556    if (havepattern)
07557       regfree(&regexbuf);
07558 
07559    return RESULT_SUCCESS;
07560 #undef FORMAT
07561 }

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

13185 {
13186    char *cdest;
13187    char *extension, *host, *port;
13188    char tmp[80];
13189    
13190    cdest = ast_strdupa(dest);
13191    if (!cdest) {
13192       ast_log(LOG_ERROR, "Problem allocating the memory\n");
13193       return 0;
13194    }
13195    extension = strsep(&cdest, "@");
13196    host = strsep(&cdest, ":");
13197    port = strsep(&cdest, ":");
13198    if (!extension) {
13199       ast_log(LOG_ERROR, "Missing mandatory argument: extension\n");
13200       return 0;
13201    }
13202 
13203    /* we'll issue the redirect message here */
13204    if (!host) {
13205       char *localtmp;
13206       ast_copy_string(tmp, get_header(&p->initreq, "To"), sizeof(tmp));
13207       if (!strlen(tmp)) {
13208          ast_log(LOG_ERROR, "Cannot retrieve the 'To' header from the original SIP request!\n");
13209          return 0;
13210       }
13211       if ((localtmp = strstr(tmp, "sip:")) && (localtmp = strchr(localtmp, '@'))) {
13212          char lhost[80], lport[80];
13213          memset(lhost, 0, sizeof(lhost));
13214          memset(lport, 0, sizeof(lport));
13215          localtmp++;
13216          /* This is okey because lhost and lport are as big as tmp */
13217          sscanf(localtmp, "%[^<>:; ]:%[^<>:; ]", lhost, lport);
13218          if (!strlen(lhost)) {
13219             ast_log(LOG_ERROR, "Can't find the host address\n");
13220             return 0;
13221          }
13222          host = ast_strdupa(lhost);
13223          if (!host) {
13224             ast_log(LOG_ERROR, "Problem allocating the memory\n");
13225             return 0;
13226          }
13227          if (!ast_strlen_zero(lport)) {
13228             port = ast_strdupa(lport);
13229             if (!port) {
13230                ast_log(LOG_ERROR, "Problem allocating the memory\n");
13231                return 0;
13232             }
13233          }
13234       }
13235    }
13236 
13237    snprintf(p->our_contact, sizeof(p->our_contact), "Transfer <sip:%s@%s%s%s>", extension, host, port ? ":" : "", port ? port : "");
13238    transmit_response_reliable(p, "302 Moved Temporarily", &p->initreq, 1);
13239 
13240    /* this is all that we want to send to that SIP device */
13241    ast_set_flag(p, SIP_ALREADYGONE);
13242 
13243    /* hangup here */
13244    return -1;
13245 }

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

sip_transfer: Transfer SIP call

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

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

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

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

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

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

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

sipsock_read: Read data from SIP socket ---

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

11304 {
11305    struct sip_request req;
11306    struct sockaddr_in sin = { 0, };
11307    struct sip_pvt *p;
11308    int res;
11309    socklen_t len;
11310    int nounlock;
11311    int recount = 0;
11312    char iabuf[INET_ADDRSTRLEN];
11313    unsigned int lockretry = 100;
11314 
11315    len = sizeof(sin);
11316    memset(&req, 0, sizeof(req));
11317    res = recvfrom(sipsock, req.data, sizeof(req.data) - 1, 0, (struct sockaddr *)&sin, &len);
11318    if (res < 0) {
11319 #if !defined(__FreeBSD__)
11320       if (errno == EAGAIN)
11321          ast_log(LOG_NOTICE, "SIP: Received packet with bad UDP checksum\n");
11322       else 
11323 #endif
11324       if (errno != ECONNREFUSED)
11325          ast_log(LOG_WARNING, "Recv error: %s\n", strerror(errno));
11326       return 1;
11327    }
11328    if (res == sizeof(req.data)) {
11329       ast_log(LOG_DEBUG, "Received packet exceeds buffer. Data is possibly lost\n");
11330       req.data[sizeof(req.data) - 1] = '\0';
11331    } else
11332       req.data[res] = '\0';
11333    req.len = res;
11334    if(sip_debug_test_addr(&sin))
11335       ast_set_flag(&req, SIP_PKT_DEBUG);
11336    if (pedanticsipchecking)
11337       req.len = lws2sws(req.data, req.len);  /* Fix multiline headers */
11338    if (ast_test_flag(&req, SIP_PKT_DEBUG)) {
11339       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);
11340    }
11341    parse_request(&req);
11342    req.method = find_sip_method(req.rlPart1);
11343    if (ast_test_flag(&req, SIP_PKT_DEBUG)) {
11344       ast_verbose("--- (%d headers %d lines)", req.headers, req.lines);
11345       if (req.headers + req.lines == 0) 
11346          ast_verbose(" Nat keepalive ");
11347       ast_verbose("---\n");
11348    }
11349 
11350    if (req.headers < 2) {
11351       /* Must have at least two headers */
11352       return 1;
11353    }
11354 
11355 
11356    /* Process request, with netlock held */
11357 retrylock:
11358    ast_mutex_lock(&netlock);
11359    p = find_call(&req, &sin, req.method);
11360    if (p) {
11361       /* Go ahead and lock the owner if it has one -- we may need it */
11362       if (p->owner && ast_mutex_trylock(&p->owner->lock)) {
11363          ast_log(LOG_DEBUG, "Failed to grab lock, trying again...\n");
11364          ast_mutex_unlock(&p->lock);
11365          ast_mutex_unlock(&netlock);
11366          /* Sleep for a very short amount of time */
11367          usleep(1);
11368          if (--lockretry)
11369             goto retrylock;
11370       }
11371       if (!lockretry) {
11372          ast_log(LOG_ERROR, "We could NOT get the channel lock for %s! \n", p->owner->name);
11373          ast_log(LOG_ERROR, "SIP MESSAGE JUST IGNORED: %s \n", req.data);
11374          ast_log(LOG_ERROR, "BAD! BAD! BAD!\n");
11375          return 1;
11376       }
11377       memcpy(&p->recv, &sin, sizeof(p->recv));
11378       if (recordhistory) {
11379          char tmp[80];
11380          /* This is a response, note what it was for */
11381          snprintf(tmp, sizeof(tmp), "%s / %s /%s", req.data, get_header(&req, "CSeq"), req.rlPart2);
11382          append_history(p, "Rx", tmp);
11383       }
11384       nounlock = 0;
11385       if (handle_request(p, &req, &sin, &recount, &nounlock) == -1) {
11386          /* Request failed */
11387          ast_log(LOG_DEBUG, "SIP message could not be handled, bad request: %-70.70s\n", p->callid[0] ? p->callid : "<no callid>");
11388       }
11389       
11390       if (p->owner && !nounlock)
11391          ast_mutex_unlock(&p->owner->lock);
11392       ast_mutex_unlock(&p->lock);
11393    }
11394    ast_mutex_unlock(&netlock);
11395    if (recount)
11396       ast_update_use_count();
11397 
11398    return 1;
11399 }

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

subscription_type2str: Show subscription type in string format

Definition at line 8379 of file chan_sip.c.

References subscription_types, and type.

Referenced by __sip_show_channels(), and sip_show_channel().

08379                                                                         {
08380    int i;
08381 
08382    for (i = 1; (i < (sizeof(subscription_types) / sizeof(subscription_types[0]))); i++) {
08383       if (subscription_types[i].type == subtype) {
08384          return subscription_types[i].text;
08385       }
08386    }
08387    return subscription_types[0].text;
08388 }

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

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

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

12220 {
12221    struct sip_peer *peer;
12222 
12223    peer = malloc(sizeof(*peer));
12224    if (!peer)
12225       return NULL;
12226 
12227    memset(peer, 0, sizeof(*peer));
12228    apeerobjs++;
12229    ASTOBJ_INIT(peer);
12230 
12231    peer->expire = -1;
12232    peer->pokeexpire = -1;
12233    ast_copy_string(peer->name, name, sizeof(peer->name));
12234    ast_copy_flags(peer, &global_flags, SIP_FLAGS_TO_COPY);
12235    strcpy(peer->context, default_context);
12236    strcpy(peer->subscribecontext, default_subscribecontext);
12237    strcpy(peer->language, default_language);
12238    strcpy(peer->musicclass, global_musicclass);
12239    peer->addr.sin_port = htons(DEFAULT_SIP_PORT);
12240    peer->addr.sin_family = AF_INET;
12241    peer->capability = global_capability;
12242    peer->rtptimeout = global_rtptimeout;
12243    peer->rtpholdtimeout = global_rtpholdtimeout;
12244    peer->rtpkeepalive = global_rtpkeepalive;
12245    ast_set_flag(peer, SIP_SELFDESTRUCT);
12246    ast_set_flag(&peer->flags_page2, SIP_PAGE2_DYNAMIC);
12247    peer->prefs = prefs;
12248    reg_source_db(peer);
12249 
12250    return peer;
12251 }

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

References ast_mutex_lock(), and ast_mutex_unlock().

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

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

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

06461 {
06462    snprintf(randdata, randlen, "%08x", thread_safe_rand());
06463    transmit_response_with_auth(p, "401 Unauthorized", req, randdata, reliable, "WWW-Authenticate", 0);
06464 }

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

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

Referenced by sip_senddigit().

05666 {
05667    struct sip_request req;
05668    reqprep(&req, p, SIP_INFO, 0, 1);
05669    add_digit(&req, digit);
05670    return send_request(p, &req, 1, p->ocseq);
05671 }

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

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

Referenced by sip_indicate().

05675 {
05676    struct sip_request req;
05677    reqprep(&req, p, SIP_INFO, 0, 1);
05678    add_vidupdate(&req);
05679    return send_request(p, &req, 1, p->ocseq);
05680 }

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

04966 {
04967    struct sip_request req;
04968    
04969    req.method = sipmethod;
04970    if (init) {
04971       /* Bump branch even on initial requests */
04972       p->branch ^= thread_safe_rand();
04973       build_via(p, p->via, sizeof(p->via));
04974       if (init > 1)
04975          initreqprep(&req, p, sipmethod);
04976       else
04977          reqprep(&req, p, sipmethod, 0, 1);
04978    } else
04979       reqprep(&req, p, sipmethod, 0, 1);
04980       
04981    if (p->options && p->options->auth)
04982       add_header(&req, p->options->authheader, p->options->auth);
04983    append_date(&req);
04984    if (sipmethod == SIP_REFER) { /* Call transfer */
04985       if (!ast_strlen_zero(p->refer_to))
04986          add_header(&req, "Refer-To", p->refer_to);
04987       if (!ast_strlen_zero(p->referred_by))
04988          add_header(&req, "Referred-By", p->referred_by);
04989    }
04990 #ifdef OSP_SUPPORT
04991    if ((req.method != SIP_OPTIONS) && p->options && !ast_strlen_zero(p->options->osptoken)) {
04992       ast_log(LOG_DEBUG,"Adding OSP Token: %s\n", p->options->osptoken);
04993       add_header(&req, "P-OSP-Auth-Token", p->options->osptoken);
04994    }
04995 #endif
04996    if (p->options && !ast_strlen_zero(p->options->distinctive_ring))
04997    {
04998       add_header(&req, "Alert-Info", p->options->distinctive_ring);
04999    }
05000    add_header(&req, "Allow", ALLOWED_METHODS);
05001    if (p->options && p->options->addsipheaders ) {
05002       struct ast_channel *ast;
05003       char *header = (char *) NULL;
05004       char *content = (char *) NULL;
05005       char *end = (char *) NULL;
05006       struct varshead *headp = (struct varshead *) NULL;
05007       struct ast_var_t *current;
05008 
05009       ast = p->owner;   /* The owner channel */
05010       if (ast) {
05011          char *headdup;
05012          headp = &ast->varshead;
05013          if (!headp)
05014             ast_log(LOG_WARNING,"No Headp for the channel...ooops!\n");
05015          else {
05016             AST_LIST_TRAVERSE(headp, current, entries) {  
05017                /* SIPADDHEADER: Add SIP header to outgoing call        */
05018                if (!strncasecmp(ast_var_name(current), "SIPADDHEADER", strlen("SIPADDHEADER"))) {
05019                   header = ast_var_value(current);
05020                   headdup = ast_strdupa(header);
05021                   /* Strip of the starting " (if it's there) */
05022                   if (*headdup == '"')
05023                      headdup++;
05024                   if ((content = strchr(headdup, ':'))) {
05025                      *content = '\0';
05026                      content++;  /* Move pointer ahead */
05027                      /* Skip white space */
05028                      while (*content == ' ')
05029                         content++;
05030                      /* Strip the ending " (if it's there) */
05031                      end = content + strlen(content) -1; 
05032                      if (*end == '"')
05033                         *end = '\0';
05034                   
05035                      add_header(&req, headdup, content);
05036                      if (sipdebug)
05037                         ast_log(LOG_DEBUG, "Adding SIP Header \"%s\" with content :%s: \n", headdup, content);
05038                   }
05039                }
05040             }
05041          }
05042       }
05043    }
05044    if (sdp && p->rtp) {
05045       ast_rtp_offered_from_local(p->rtp, 1);
05046       add_sdp(&req, p);
05047    } else {
05048       add_header_contentLength(&req, 0);
05049       add_blank_header(&req);
05050    }
05051 
05052    if (!p->initreq.headers) {
05053       /* Use this as the basis */
05054       copy_request(&p->initreq, &req);
05055       parse_request(&p->initreq);
05056       if (sip_debug_test_pvt(p))
05057          ast_verbose("%d headers, %d lines\n", p->initreq.headers, p->initreq.lines);
05058    }
05059    p->lastinvite = p->ocseq;
05060    return send_request(p, &req, init ? 2 : 1, p->ocseq);
05061 }

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

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

Referenced by sip_sendtext().

05612 {
05613    struct sip_request req;
05614    reqprep(&req, p, SIP_MESSAGE, 0, 1);
05615    add_text(&req, text);
05616    return send_request(p, &req, 1, p->ocseq);
05617 }

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

05237 {
05238    struct sip_request req;
05239    char tmp[500];
05240    char *t = tmp;
05241    size_t maxbytes = sizeof(tmp);
05242    char iabuf[INET_ADDRSTRLEN];
05243 
05244    initreqprep(&req, p, SIP_NOTIFY);
05245    add_header(&req, "Event", "message-summary");
05246    add_header(&req, "Content-Type", default_notifymime);
05247 
05248    ast_build_string(&t, &maxbytes, "Messages-Waiting: %s\r\n", newmsgs ? "yes" : "no");
05249    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);
05250    ast_build_string(&t, &maxbytes, "Voice-Message: %d/%d (0/0)\r\n", newmsgs, oldmsgs);
05251 
05252    if (t > tmp + sizeof(tmp))
05253       ast_log(LOG_WARNING, "Buffer overflow detected!!  (Please file a bug report)\n");
05254 
05255    add_header_contentLength(&req, strlen(tmp));
05256    add_line(&req, tmp);
05257 
05258    if (!p->initreq.headers) { /* Use this as the basis */
05259       copy_request(&p->initreq, &req);
05260       parse_request(&p->initreq);
05261       if (sip_debug_test_pvt(p))
05262          ast_verbose("%d headers, %d lines\n", p->initreq.headers, p->initreq.lines);
05263       determine_firstline_parts(&p->initreq);
05264    }
05265 
05266    return send_request(p, &req, 1, p->ocseq);
05267 }

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

05290 {
05291    struct sip_request req;
05292    char tmp[20];
05293    reqprep(&req, p, SIP_NOTIFY, 0, 1);
05294    snprintf(tmp, sizeof(tmp), "refer;id=%d", cseq);
05295    add_header(&req, "Event", tmp);
05296    add_header(&req, "Subscription-state", "terminated;reason=noresource");
05297    add_header(&req, "Content-Type", "message/sipfrag;version=2.0");
05298 
05299    strcpy(tmp, "SIP/2.0 200 OK");
05300    add_header_contentLength(&req, strlen(tmp));
05301    add_line(&req, tmp);
05302 
05303    if (!p->initreq.headers) {
05304       /* Use this as the basis */
05305       copy_request(&p->initreq, &req);
05306       parse_request(&p->initreq);
05307       if (sip_debug_test_pvt(p))
05308          ast_verbose("%d headers, %d lines\n", p->initreq.headers, p->initreq.lines);
05309       determine_firstline_parts(&p->initreq);
05310    }
05311 
05312    return send_request(p, &req, 1, p->ocseq);
05313 }

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

transmit_refer: Transmit SIP REFER message ---

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

05621 {
05622    struct sip_request req;
05623    char from[256];
05624    char *of, *c;
05625    char referto[256];
05626 
05627    if (ast_test_flag(p, SIP_OUTGOING)) 
05628       of = get_header(&p->initreq, "To");
05629    else
05630       of = get_header(&p->initreq, "From");
05631    ast_copy_string(from, of, sizeof(from));
05632    of = get_in_brackets(from);
05633    ast_copy_string(p->from,of,sizeof(p->from));
05634    if (strncmp(of, "sip:", 4)) {
05635       ast_log(LOG_NOTICE, "From address missing 'sip:', using it anyway\n");
05636    } else
05637       of += 4;
05638    /* Get just the username part */
05639    if ((c = strchr(dest, '@'))) {
05640       c = NULL;
05641    } else if ((c = strchr(of, '@'))) {
05642       *c = '\0';
05643       c++;
05644    }
05645    if (c) {
05646       snprintf(referto, sizeof(referto), "<sip:%s@%s>", dest, c);
05647    } else {
05648       snprintf(referto, sizeof(referto), "<sip:%s>", dest);
05649    }
05650 
05651    /* save in case we get 407 challenge */
05652    ast_copy_string(p->refer_to, referto, sizeof(p->refer_to));
05653    ast_copy_string(p->referred_by, p->our_contact, sizeof(p->referred_by));
05654 
05655    reqprep(&req, p, SIP_REFER, 0, 1);
05656    add_header(&req, "Refer-To", referto);
05657    if (!ast_strlen_zero(p->our_contact))
05658       add_header(&req, "Referred-By", p->our_contact);
05659    add_blank_header(&req);
05660    return send_request(p, &req, 1, p->ocseq);
05661 }

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

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

static int transmit_reinvite_with_sdp ( struct sip_pvt p  )  [static]

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

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

04693 {
04694    struct sip_request req;
04695    if (ast_test_flag(p, SIP_REINVITE_UPDATE))
04696       reqprep(&req, p, SIP_UPDATE, 0, 1);
04697    else 
04698       reqprep(&req, p, SIP_INVITE, 0, 1);
04699    
04700    add_header(&req, "Allow", ALLOWED_METHODS);
04701    if (sipdebug)
04702       add_header(&req, "X-asterisk-info", "SIP re-invite (RTP bridge)");
04703    ast_rtp_offered_from_local(p->rtp, 1);
04704    add_sdp(&req, p);
04705    /* Use this as the basis */
04706    copy_request(&p->initreq, &req);
04707    parse_request(&p->initreq);
04708    if (sip_debug_test_pvt(p))
04709       ast_verbose("%d headers, %d lines\n", p->initreq.headers, p->initreq.lines);
04710    p->lastinvite = p->ocseq;
04711    ast_set_flag(p, SIP_OUTGOING);
04712    return send_request(p, &req, 1, p->ocseq);
04713 }

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

05684 {
05685    struct sip_request resp;
05686    reqprep(&resp, p, sipmethod, seqno, newbranch);
05687    add_header_contentLength(&resp, 0);
05688    add_blank_header(&resp);
05689    return send_request(p, &resp, reliable, seqno ? seqno : p->ocseq);
05690 }

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

05694 {
05695    struct sip_request resp;
05696 
05697    reqprep(&resp, p, sipmethod, seqno, newbranch);
05698    if (*p->realm) {
05699       char digest[1024];
05700 
05701       memset(digest, 0, sizeof(digest));
05702       if(!build_reply_digest(p, sipmethod, digest, sizeof(digest))) {
05703          if (p->options && p->options->auth_type == PROXY_AUTH)
05704             add_header(&resp, "Proxy-Authorization", digest);
05705          else if (p->options && p->options->auth_type == WWW_AUTH)
05706             add_header(&resp, "Authorization", digest);
05707          else  /* Default, to be backwards compatible (maybe being too careful, but leaving it for now) */
05708             add_header(&resp, "Proxy-Authorization", digest);
05709       } else
05710          ast_log(LOG_WARNING, "No authentication available for call %s\n", p->callid);
05711    }
05712    /* If we are hanging up and know a cause for that, send it in clear text to make
05713       debugging easier. */
05714    if (sipmethod == SIP_BYE) {
05715       if (p->owner && p->owner->hangupcause) {
05716          add_header(&resp, "X-Asterisk-HangupCause", ast_cause2str(p->owner->hangupcause));
05717       }
05718    }
05719 
05720    add_header_contentLength(&resp, 0);
05721    add_blank_header(&resp);
05722    return send_request(p, &resp, reliable, seqno ? seqno : p->ocseq);   
05723 }

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

transmit_response: Transmit response, no retransmits

Definition at line 4252 of file chan_sip.c.

References __transmit_response().

04253 {
04254    return __transmit_response(p, msg, req, 0);
04255 }

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

04269 {
04270    return __transmit_response(p, msg, req, fatal ? 2 : 1);
04271 }

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

04299 {
04300    struct sip_request resp;
04301    respprep(&resp, p, msg, req);
04302    add_header(&resp, "Accept", "application/sdp");
04303    add_header_contentLength(&resp, 0);
04304    add_blank_header(&resp);
04305    return send_response(p, &resp, reliable, 0);
04306 }

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

04310 {
04311    struct sip_request resp;
04312    char tmp[512];
04313    int seqno = 0;
04314 
04315    if (reliable && (sscanf(get_header(req, "CSeq"), "%d ", &seqno) != 1)) {
04316       ast_log(LOG_WARNING, "Unable to determine sequence number from '%s'\n", get_header(req, "CSeq"));
04317       return -1;
04318    }
04319    /* Stale means that they sent us correct authentication, but 
04320       based it on an old challenge (nonce) */
04321    snprintf(tmp, sizeof(tmp), "Digest algorithm=MD5, realm=\"%s\", nonce=\"%s\"%s", global_realm, randdata, stale ? ", stale=true" : "");
04322    respprep(&resp, p, msg, req);
04323    add_header(&resp, header, tmp);
04324    add_header_contentLength(&resp, 0);
04325    add_blank_header(&resp);
04326    return send_response(p, &resp, reliable, seqno);
04327 }

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

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

Referenced by register_verify().

04288 {
04289    struct sip_request resp;
04290    respprep(&resp, p, msg, req);
04291    append_date(&resp);
04292    add_header_contentLength(&resp, 0);
04293    add_blank_header(&resp);
04294    return send_response(p, &resp, 0, 0);
04295 }

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

04619 {
04620    struct sip_request resp;
04621    int seqno;
04622    if (sscanf(get_header(req, "CSeq"), "%d ", &seqno) != 1) {
04623       ast_log(LOG_WARNING, "Unable to get seqno from '%s'\n", get_header(req, "CSeq"));
04624       return -1;
04625    }
04626    respprep(&resp, p, msg, req);
04627    if (p->rtp) {
04628       ast_rtp_offered_from_local(p->rtp, 0);
04629       try_suggested_sip_codec(p);   
04630       add_sdp(&resp, p);
04631    } else {
04632       ast_log(LOG_ERROR, "Can't add SDP to response, since we have no RTP session allocated. Call-ID %s\n", p->callid);
04633    }
04634    return send_response(p, &resp, retrans, seqno);
04635 }

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

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

Referenced by handle_request_invite().

04259 {
04260    struct sip_request resp;
04261    respprep(&resp, p, msg, req);
04262    append_date(&resp);
04263    add_header(&resp, "Unsupported", unsupported);
04264    return send_response(p, &resp, 0, 0);
04265 }

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

transmit_sip_request: Transmit SIP request

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

05271 {
05272    if (!p->initreq.headers) {
05273       /* Use this as the basis */
05274       copy_request(&p->initreq, req);
05275       parse_request(&p->initreq);
05276       if (sip_debug_test_pvt(p))
05277          ast_verbose("%d headers, %d lines\n", p->initreq.headers, p->initreq.lines);
05278       determine_firstline_parts(&p->initreq);
05279    }
05280 
05281    return send_request(p, req, 0, p->ocseq);
05282 }

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

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

static void try_suggested_sip_codec ( struct sip_pvt p  )  [static]

Try setting codec suggested by the SIP_CODEC channel variable.

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

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

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

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

13440 {
13441    struct sip_pvt *p, *pl;
13442    
13443    /* First, take us out of the channel type list */
13444    ast_channel_unregister(&sip_tech);
13445 
13446    ast_custom_function_unregister(&sipchaninfo_function);
13447    ast_custom_function_unregister(&sippeer_function);
13448    ast_custom_function_unregister(&sip_header_function);
13449    ast_custom_function_unregister(&checksipdomain_function);
13450 
13451    ast_unregister_application(app_dtmfmode);
13452    ast_unregister_application(app_sipaddheader);
13453    ast_unregister_application(app_sipgetheader);
13454 
13455    ast_cli_unregister_multiple(my_clis, sizeof(my_clis) / sizeof(my_clis[0]));
13456 
13457    ast_rtp_proto_unregister(&sip_rtp);
13458 
13459    ast_manager_unregister("SIPpeers");
13460    ast_manager_unregister("SIPshowpeer");
13461 
13462    if (!ast_mutex_lock(&iflock)) {
13463       /* Hangup all interfaces if they have an owner */
13464       p = iflist;
13465       while (p) {
13466          if (p->owner)
13467             ast_softhangup(p->owner, AST_SOFTHANGUP_APPUNLOAD);
13468          p = p->next;
13469       }
13470       ast_mutex_unlock(&iflock);
13471    } else {
13472       ast_log(LOG_WARNING, "Unable to lock the interface list\n");
13473       return -1;
13474    }
13475 
13476    if (!ast_mutex_lock(&monlock)) {
13477       if (monitor_thread && (monitor_thread != AST_PTHREADT_STOP)) {
13478          pthread_cancel(monitor_thread);
13479          pthread_kill(monitor_thread, SIGURG);
13480          pthread_join(monitor_thread, NULL);
13481       }
13482       monitor_thread = AST_PTHREADT_STOP;
13483       ast_mutex_unlock(&monlock);
13484    } else {
13485       ast_log(LOG_WARNING, "Unable to lock the monitor\n");
13486       return -1;
13487    }
13488 
13489    if (!ast_mutex_lock(&iflock)) {
13490       /* Destroy all the interfaces and free their memory */
13491       p = iflist;
13492       while (p) {
13493          pl = p;
13494          p = p->next;
13495          /* Free associated memory */
13496          ast_mutex_destroy(&pl->lock);
13497          if (pl->chanvars) {
13498             ast_variables_destroy(pl->chanvars);
13499             pl->chanvars = NULL;
13500          }
13501          free(pl);
13502       }
13503       iflist = NULL;
13504       ast_mutex_unlock(&iflock);
13505    } else {
13506       ast_log(LOG_WARNING, "Unable to lock the interface list\n");
13507       return -1;
13508    }
13509 
13510    /* Free memory for local network address mask */
13511    ast_free_ha(localaddr);
13512 
13513    ASTOBJ_CONTAINER_DESTROYALL(&userl, sip_destroy_user);
13514    ASTOBJ_CONTAINER_DESTROY(&userl);
13515    ASTOBJ_CONTAINER_DESTROYALL(&peerl, sip_destroy_peer);
13516    ASTOBJ_CONTAINER_DESTROY(&peerl);
13517    ASTOBJ_CONTAINER_DESTROYALL(&regl, sip_registry_destroy);
13518    ASTOBJ_CONTAINER_DESTROY(&regl);
13519 
13520    clear_realm_authentication(authl);
13521    clear_sip_domains();
13522    close(sipsock);
13523    sched_context_destroy(sched);
13524       
13525    return 0;
13526 }

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

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

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

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

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

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

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

References usecnt.

13529 {
13530    return usecnt;
13531 }


Variable Documentation

struct in_addr __ourip [static]

Definition at line 413 of file chan_sip.c.

struct cfalias aliases[] [static]

Structure for conversion between compressed SIP and "normal" SIP.

int allow_external_domains

Accept calls to external SIP domains?

Definition at line 501 of file chan_sip.c.

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

int apeerobjs = 0 [static]

Definition at line 381 of file chan_sip.c.

Referenced by sip_show_objects(), and temp_peer().

char* app_dtmfmode = "SIPDtmfMode" [static]

Definition at line 13005 of file chan_sip.c.

char* app_sipaddheader = "SIPAddHeader" [static]

Definition at line 13007 of file chan_sip.c.

char* app_sipgetheader = "SIPGetHeader" [static]

Definition at line 13019 of file chan_sip.c.

struct sip_auth* authl [static]

Authentication list

Definition at line 884 of file chan_sip.c.

Referenced by build_reply_digest(), reload_config(), sip_do_reload(), sip_show_settings(), and unload_module().

int autocreatepeer = 0 [static]

Auto creation of peers at registration? Default off.

Definition at line 363 of file chan_sip.c.

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

struct sockaddr_in bindaddr = { 0, } [static]

Definition at line 874 of file chan_sip.c.

int callevents = 0 [static]

Definition at line 909 of file chan_sip.c.

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

const char channeltype[] = "SIP" [static]

Definition at line 145 of file chan_sip.c.

struct ast_custom_function checksipdomain_function [static]

Definition at line 9358 of file chan_sip.c.

Referenced by load_module(), and unload_module().

int compactheaders = 0 [static]

send compact sip headers

Definition at line 426 of file chan_sip.c.

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

const char config[] = "sip.conf" [static]

Definition at line 146 of file chan_sip.c.

char debug_usage[] [static]

Definition at line 9257 of file chan_sip.c.

struct sockaddr_in debugaddr [static]

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

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

char default_context[AST_MAX_CONTEXT] = DEFAULT_CONTEXT [static]

Definition at line 334 of file chan_sip.c.

int default_expiry = DEFAULT_DEFAULT_EXPIRY [static]

Definition at line 121 of file chan_sip.c.

Referenced by handle_response_register(), parse_register_contact(), reload_config(), sip_send_all_registers(), sip_show_settings(), and transmit_register().

char default_fromdomain[AST_MAX_EXTENSION] = "" [static]

Definition at line 345 of file chan_sip.c.

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

char default_language[MAX_LANGUAGE] = "" [static]

Definition at line 340 of file chan_sip.c.

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

char default_notifymime[AST_MAX_EXTENSION] = DEFAULT_NOTIFYMIME [static]

Definition at line 348 of file chan_sip.c.

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

int default_qualify = 0 [static]

Default Qualify= setting

Definition at line 354 of file chan_sip.c.

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

char default_subscribecontext[AST_MAX_CONTEXT] [static]

Definition at line 335 of file chan_sip.c.

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

char default_useragent[AST_MAX_EXTENSION] = DEFAULT_USERAGENT [static]

Definition at line 331 of file chan_sip.c.

Referenced by initreqprep(), reload_config(), reqprep(), respprep(), sip_show_settings(), and transmit_register().

const char desc[] = "Session Initiation Protocol (SIP)" [static]

Definition at line 144 of file chan_sip.c.

char* descrip_dtmfmode = "SIPDtmfMode(inband|info|rfc2833): Changes the dtmfmode for a SIP call\n" [static]

Definition at line 13004 of file chan_sip.c.

char* descrip_sipaddheader [static]

Definition at line 13011 of file chan_sip.c.

char* descrip_sipgetheader [static]

Definition at line 13022 of file chan_sip.c.

int dumphistory = 0 [static]

Dump history to verbose before destroying SIP dialog

Definition at line 429 of file chan_sip.c.

Referenced by reload_config().

int expiry = DEFAULT_EXPIRY [static]

Definition at line 437 of file chan_sip.c.

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

time_t externexpire = 0 [static]

Definition at line 877 of file chan_sip.c.

Referenced by ast_sip_ouraddrfor(), and reload_config().

char externhost[MAXHOSTNAMELEN] = "" [static]

Definition at line 876 of file chan_sip.c.

Referenced by ast_sip_ouraddrfor(), and reload_config().

struct sockaddr_in externip [static]

Definition at line 875 of file chan_sip.c.

Referenced by reload_config().

int externrefresh = 10 [static]

Definition at line 878 of file chan_sip.c.

Referenced by ast_sip_ouraddrfor(), and reload_config().

int global_allowguest = 1 [static]

allow unauthenticated users/peers to connect?

Definition at line 384 of file chan_sip.c.

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

int global_alwaysauthreject = 0 [static]

Send 401 Unauthorized for all failing requests

Definition at line 352 of file chan_sip.c.

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

int global_capability = AST_FORMAT_ULAW | AST_FORMAT_ALAW | AST_FORMAT_GSM | AST_FORMAT_H263 [static]

Codecs that we support by default:.

Definition at line 410 of file chan_sip.c.

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

struct ast_flags global_flags = {0} [static]

global SIP_ flags

Definition at line 356 of file chan_sip.c.

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

struct ast_flags global_flags_page2 = {0} [static]

more global SIP_ flags

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

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

int global_mwitime = DEFAULT_MWITIME [static]

Time between MWI checks for peers

Definition at line 387 of file chan_sip.c.

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

int global_notifyringing = 1 [static]

Send notifications on ringing

Definition at line 350 of file chan_sip.c.

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

char global_realm[MAXHOSTNAMELEN] = DEFAULT_REALM [static]

Default realm

Definition at line 433 of file chan_sip.c.

Referenced by check_auth(), reload_config(), sip_show_settings(), and transmit_response_with_auth().

int global_reg_timeout = DEFAULT_REGISTRATION_TIMEOUT [static]

Definition at line 373 of file chan_sip.c.

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

int global_regattempts_max = 0 [static]

Definition at line 374 of file chan_sip.c.

Referenced by handle_response_register(), reload_config(), sip_reg_timeout(), and sip_show_settings().

int global_rtautoclear [static]

Definition at line 589 of file chan_sip.c.

int global_rtpholdtimeout = 0 [static]

Definition at line 369 of file chan_sip.c.

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

int global_rtpkeepalive = 0 [static]

Definition at line 371 of file chan_sip.c.

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

int global_rtptimeout = 0 [static]

Definition at line 367 of file chan_sip.c.

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

char global_vmexten[AST_MAX_EXTENSION] = DEFAULT_VMEXTEN [static]

Definition at line 338 of file chan_sip.c.

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

char history_usage[] [static]

Initial value:

 
"Usage: sip history\n"
"       Enables recording of SIP dialog history for debugging purposes.\n"
"Use 'sip show history' to view the history of a call number.\n"

Definition at line 9274 of file chan_sip.c.

struct sip_pvt * iflist [static]

sip_pvt: PVT structures are used for each SIP conversation, ie. a call

struct io_context* io [static]

Definition at line 440 of file chan_sip.c.

struct ast_ha* localaddr [static]

Definition at line 879 of file chan_sip.c.

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

char mandescr_show_peer[] [static]

Definition at line 7981 of file chan_sip.c.

Referenced by load_module().

char mandescr_show_peers[] [static]

Initial value:

 
"Description: Lists SIP peers in text format with details on current status.\n"
"Variables: \n"
"  ActionID: <id> Action ID for this transaction. Will be returned.\n"

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

struct ast_cli_entry my_clis[] [static]

Definition at line 13350 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 9266 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 9270 of file chan_sip.c.

int noncodeccapability = AST_RTP_DTMF [static]

Definition at line 411 of file chan_sip.c.

Referenced by process_sdp().

const char notify_config[] = "sip_notify.conf" [static]

Definition at line 147 of file chan_sip.c.

Referenced by reload_config(), and sip_notify().

struct ast_config* notify_types

Definition at line 882 of file chan_sip.c.

Referenced by complete_sipnotify(), reload_config(), and sip_notify().

char notify_usage[] [static]

Initial value:

"Usage: sip notify <type> <peer> [<peer>...]\n"
"       Send a NOTIFY message to a SIP peer or peers\n"
"       Message types are defined in sip_notify.conf\n"

Definition at line 9206 of file chan_sip.c.

int ourport [static]

Definition at line 415 of file chan_sip.c.

struct sockaddr_in outboundproxyip [static]

Definition at line 414 of file chan_sip.c.

Referenced by reload_config().

int pedanticsipchecking = 0 [static]

Extra checking ? Default off

Definition at line 361 of file chan_sip.c.

Referenced by check_user_full(), get_destination(), get_refer_info(), handle_request(), initreqprep(), register_verify(), reload_config(), sip_show_settings(), and sipsock_read().

struct ast_peer_list peerl [static]

The peer list: Peers and Friends ---.

struct ast_codec_pref prefs [static]

Definition at line 448 of file chan_sip.c.

char prune_realtime_usage[] [static]

Initial value:

"Usage: sip prune realtime [peer|user] [<name>|all|like <pattern>]\n"
"       Prunes object(s) from the cache.\n"
"       Optional regular expression pattern is used to filter the objects.\n"

Definition at line 9248 of file chan_sip.c.

int recordhistory = 0 [static]

Record SIP history. Off by default

Definition at line 428 of file chan_sip.c.

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

struct ast_register_list regl [static]

The register list: Other SIP proxys we register with and call ---.

Referenced by delete_users(), load_module(), sip_do_reload(), sip_register(), sip_send_all_registers(), sip_show_objects(), sip_show_registry(), and unload_module().

int regobjs = 0 [static]

Definition at line 382 of file chan_sip.c.

Referenced by sip_send_all_registers(), and sip_show_objects().

int relaxdtmf = 0 [static]

Definition at line 365 of file chan_sip.c.

Referenced by reload_config(), and sip_show_settings().

int rpeerobjs = 0 [static]

Definition at line 380 of file chan_sip.c.

Referenced by build_peer(), and sip_show_objects().

int ruserobjs = 0 [static]

Definition at line 378 of file chan_sip.c.

Referenced by sip_show_objects().

struct sched_context* sched [static]

Definition at line 439 of file chan_sip.c.

char show_channel_usage[] [static]

Initial value:

 
"Usage: sip show channel <channel>\n"
"       Provides detailed status on a given SIP channel.\n"

Definition at line 9230 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 9226 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 9201 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 9234 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 9221 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 9287 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 9243 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 9238 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 9253 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 9291 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 9283 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 9216 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 9211 of file chan_sip.c.

struct ast_custom_function sip_header_function [static]

Definition at line 9337 of file chan_sip.c.

Referenced by load_module(), and unload_module().

enum sipmethod sip_method_list

struct cfsip_methods sip_methods[] [static]

XXX Note that sip_methods[i].id == i must hold or the code breaks

Referenced by __sip_ack(), __sip_pretend_ack(), __sip_semi_ack(), build_reply_digest(), check_auth(), do_proxy_auth(), find_call(), find_sip_method(), get_destination(), handle_request(), handle_request_subscribe(), handle_response(), init_req(), initreqprep(), reqprep(), retrans_pkt(), sip_alloc(), and transmit_register().

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

int sip_reloading = 0 [static]

Definition at line 806 of file chan_sip.c.

Referenced by do_monitor(), and sip_reload().

struct ast_rtp_protocol sip_rtp [static]

sip_rtp: Interface structure with callbacks used to connect to rtp module --

Definition at line 13255 of file chan_sip.c.

Referenced by load_module(), and unload_module().

struct ast_channel_tech sip_tech [static]

Definition of this channel for PBX channel registration.

Definition at line 935 of file chan_sip.c.

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

struct ast_custom_function sipchaninfo_function [static]

Definition at line 9522 of file chan_sip.c.

Referenced by load_module(), and unload_module().

int sipdebug = 0 [static]

Definition at line 419 of file chan_sip.c.

Referenced by add_sip_domain(), build_reply_digest(), check_auth(), handle_request_info(), handle_request_invite(), handle_request_subscribe(), handle_response_register(), 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 9445 of file chan_sip.c.

Referenced by load_module(), and unload_module().

int sipsock = -1 [static]

Definition at line 871 of file chan_sip.c.

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

int speerobjs = 0 [static]

Definition at line 379 of file chan_sip.c.

Referenced by build_peer(), and sip_show_objects().

int srvlookup = 0 [static]

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

Definition at line 359 of file chan_sip.c.

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

struct cfsubscription_types subscription_types[] [static]

Referenced by find_subscription_type(), and subscription_type2str().

int suserobjs = 0 [static]

Definition at line 377 of file chan_sip.c.

Referenced by build_user(), and sip_show_objects().

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

Definition at line 13003 of file chan_sip.c.

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

Definition at line 13008 of file chan_sip.c.

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

Definition at line 13020 of file chan_sip.c.

int tos = 0 [static]

Definition at line 422 of file chan_sip.c.

int usecnt = 0 [static]

Definition at line 389 of file chan_sip.c.

struct ast_user_list userl [static]

The user list: Users and friends ---.

int videosupport = 0 [static]

Definition at line 424 of file chan_sip.c.

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


Generated on Thu May 24 14:21:59 2007 for Asterisk - the Open Source PBX by  doxygen 1.4.7