#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_auth * | add_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_peer * | build_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_user * | build_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_pvt * | find_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_peer * | find_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_auth * | find_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_types * | find_subscription_type (enum subscriptiontype subtype) |
find_subscription_type: Find subscription type in array | |
static struct sip_user * | find_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_pvt * | get_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_peer * | realtime_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_user * | realtime_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_pvt * | sip_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_rtp * | sip_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_rtp * | sip_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_channel * | sip_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_frame * | sip_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_channel * | sip_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_frame * | sip_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_peer * | temp_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_auth * | authl |
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_pvt * | iflist |
sip_pvt: PVT structures are used for each SIP conversation, ie. a call | |
static struct io_context * | io |
static struct ast_ha * | localaddr |
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_config * | notify_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_context * | sched |
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 |
Implementation of RFC 3261 - without S/MIME, TCP and TLS support Configuration file sip.conf
SIP over TLS
Better support of forking
Definition in file chan_sip.c.
#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" |
#define DEBUG_READ 0 |
#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" |
#define DEFAULT_CONTEXT "default" |
#define DEFAULT_DEFAULT_EXPIRY 120 |
#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 |
#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 |
#define DEFAULT_NOTIFYMIME "application/simple-message-summary" |
#define DEFAULT_REALM "asterisk" |
#define DEFAULT_REGISTRATION_TIMEOUT 20 |
#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" |
#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) |
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" |
#define FORMAT "%-30.30s %-12.12s %8d %-20.20s\n" |
#define FORMAT "%-40.40s %-20.20s %-16.16s\n" |
#define FORMAT "%-25.25s %-15.15s %-3.3s %-3.3s %-3.3s %-8d %-10s\n" |
#define FORMAT "%-25.25s %-15.15s %-15.15s %-15.15s %-5.5s%-10.10s\n" |
#define FORMAT "%-25.25s %-15.15s %-15.15s \n" |
#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, | |||
b | ) | ((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 |
#define REG_STATE_NOAUTH 6 |
#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 |
#define REG_STATE_TIMEOUT 5 |
#define REG_STATE_UNREGISTERED 0 |
#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) |
#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 |
#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:
(SIP_PROMISCREDIR | SIP_TRUSTRPID | SIP_SENDRPID | SIP_DTMF | SIP_REINVITE | \ SIP_PROG_INBAND | SIP_OSPAUTH | SIP_USECLIENTCODE | SIP_NAT | \ SIP_USEREQPHONE | SIP_INSECURE_PORT | SIP_INSECURE_INVITE)
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) |
#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 |
#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) |
#define SIP_OSPAUTH_GATEWAY (1 << 26) |
#define SIP_OSPAUTH_NO (0 << 26) |
#define SIP_OSPAUTH_PROXY (2 << 26) |
#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) |
#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) |
#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) |
#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) |
#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" |
#define VIDEO_CODEC_MASK 0x1fc0000 |
enum domain_mode |
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 };
Definition at line 5905 of file chan_sip.c.
05905 { 05906 PARSE_REGISTER_FAILED, 05907 PARSE_REGISTER_UPDATE, 05908 PARSE_REGISTER_QUERY, 05909 };
enum sip_auth_type |
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 |
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 |
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 };
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(®exbuf, 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(®exbuf, 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(®exbuf); 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 }
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 *)®seconds) != 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 }
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.
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] |
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.
req | the SIP request to process |
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; }
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.
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(®l); /* 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.
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(®l, 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(®l, 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(®exbuf, 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(®exbuf, 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(®exbuf, 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(®l, 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(®l, 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), ®l); 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(®l, 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(®exbuf, 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(®exbuf, 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(®exbuf); 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.
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).
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(®l, sip_registry_destroy); 13518 ASTOBJ_CONTAINER_DESTROY(®l); 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.
Definition at line 13528 of file chan_sip.c.
References usecnt.
13529 { 13530 return usecnt; 13531 }
struct in_addr __ourip [static] |
Definition at line 413 of file chan_sip.c.
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] |
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.
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] |
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] |
char externhost[MAXHOSTNAMELEN] = "" [static] |
struct sockaddr_in externip [static] |
int externrefresh = 10 [static] |
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.
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.
Definition at line 879 of file chan_sip.c.
Referenced by ast_sip_ouraddrfor(), reload_config(), and unload_module().
char mandescr_show_peer[] [static] |
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] |
const char notify_config[] = "sip_notify.conf" [static] |
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] |
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] |
int rpeerobjs = 0 [static] |
int ruserobjs = 0 [static] |
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] |
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] |
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] |
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().
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] |
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] |
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().