Index: chan_sip.c =================================================================== RCS file: /usr/cvsroot/asterisk/channels/chan_sip.c,v retrieving revision 1.801 diff -u -r1.801 chan_sip.c --- chan_sip.c 3 Aug 2005 04:32:09 -0000 1.801 +++ chan_sip.c 3 Aug 2005 14:30:39 -0000 @@ -2,7 +2,7 @@ * Asterisk -- A telephony toolkit for Linux. * * Implementation of Session Initiation Protocol - * + * * Copyright (C) 2004 - 2005, Digium, Inc. * * Mark Spencer @@ -70,31 +70,32 @@ #ifndef DEFAULT_USERAGENT #define DEFAULT_USERAGENT "Asterisk PBX" #endif - -#define VIDEO_CODEC_MASK 0x1fc0000 /* Video codecs from H.261 thru AST_FORMAT_MAX_VIDEO */ + +#define VIDEO_CODEC_MASK 0x1fc0000 /* Video codecs from H.261 thru AST_FORMAT_MAX_VIDEO */ #ifndef IPTOS_MINCOST -#define IPTOS_MINCOST 0x02 +#define IPTOS_MINCOST 0x02 #endif /* #define VOCAL_DATA_HACK */ #define SIPDUMPER -#define DEFAULT_DEFAULT_EXPIRY 120 -#define DEFAULT_MAX_EXPIRY 3600 -#define DEFAULT_REGISTRATION_TIMEOUT 20 -#define DEFAULT_REGATTEMPTS_MAX 10 +#define DEFAULT_DEFAULT_EXPIRY 120 +#define DEFAULT_MAX_EXPIRY 3600 +#define DEFAULT_REGISTRATION_TIMEOUT 20 +#define DEFAULT_REGATTEMPTS_MAX 10 +#define DEFAULT_MAX_FORWARDS 70 /* guard limit must be larger than guard secs */ /* guard min must be < 1000, and should be >= 250 */ -#define EXPIRY_GUARD_SECS 15 /* How long before expiry do we reregister */ -#define EXPIRY_GUARD_LIMIT 30 /* Below here, we use EXPIRY_GUARD_PCT instead of - EXPIRY_GUARD_SECS */ -#define EXPIRY_GUARD_MIN 500 /* This is the minimum guard time applied. If - GUARD_PCT turns out to be lower than this, it - will use this time instead. - This is in milliseconds. */ -#define EXPIRY_GUARD_PCT 0.20 /* Percentage of expires timeout to use when - below EXPIRY_GUARD_LIMIT */ +#define EXPIRY_GUARD_SECS 15 /* How long before expiry do we reregister */ +#define EXPIRY_GUARD_LIMIT 30 /* Below here, we use EXPIRY_GUARD_PCT instead + * of EXPIRY_GUARD_SECS */ +#define EXPIRY_GUARD_MIN 500 /* This is the minimum guard time applied. If + * GUARD_PCT turns out to be lower than this, + * it will use this time instead. This is in + * milliseconds. */ +#define EXPIRY_GUARD_PCT 0.20 /* Percentage of expires timeout to use when + * below EXPIRY_GUARD_LIMIT */ static int max_expiry = DEFAULT_MAX_EXPIRY; static int default_expiry = DEFAULT_DEFAULT_EXPIRY; @@ -103,37 +104,32 @@ #define MAX(a,b) ((a) > (b) ? (a) : (b)) #endif -#define CALLERID_UNKNOWN "Unknown" - - - -#define DEFAULT_MAXMS 2000 /* Must be faster than 2 seconds by default */ -#define DEFAULT_FREQ_OK 60 * 1000 /* How often to check for the host to be up */ -#define DEFAULT_FREQ_NOTOK 10 * 1000 /* How often to check, if the host is down... */ +#define CALLERID_UNKNOWN "Unknown" -#define DEFAULT_RETRANS 2000 /* How frequently to retransmit */ -#define MAX_RETRANS 5 /* Try only 5 times for retransmissions */ +#define DEFAULT_MAXMS 2000 /* Must be faster than 2 seconds by default */ +#define DEFAULT_FREQ_OK 60 * 1000 /* How often to check for the host to be up */ +#define DEFAULT_FREQ_NOTOK 10 * 1000 /* How often to check, if the host is down... */ +#define DEFAULT_RETRANS 2000 /* How frequently to retransmit */ +#define MAX_RETRANS 5 /* Try only 5 times for retransmissions */ -#define DEBUG_READ 0 /* Recieved data */ -#define DEBUG_SEND 1 /* Transmit data */ +#define DEBUG_READ 0 /* Recieved data */ +#define DEBUG_SEND 1 /* Transmit data */ static const char desc[] = "Session Initiation Protocol (SIP)"; static const char channeltype[] = "SIP"; static const char config[] = "sip.conf"; static const char notify_config[] = "sip_notify.conf"; -#define RTP 1 -#define NO_RTP 0 +#define RTP 1 +#define NO_RTP 0 /* Do _NOT_ make any changes to this enum, or the array following it; - if you think you are doing the right thing, you are probably - not doing the right thing. If you think there are changes - needed, get someone else to review them first _before_ - submitting a patch. If these two lists do not match properly - bad things will happen. -*/ - + * if you think you are doing the right thing, you are probably not doing the + * right thing. If you think there are changes needed, get someone else to + * review them first _before_ submitting a patch. If these two lists do not + * match properly bad things will happen. + */ enum sipmethod { SIP_UNKNOWN, SIP_RESPONSE, @@ -153,27 +149,27 @@ SIP_PUBLISH, } sip_method_list; -static const struct cfsip_methods { +static const struct cfsip_methods { enum sipmethod id; int need_rtp; /* when this is the 'primary' use for a pvt structure, does it need RTP? */ char * const text; } sip_methods[] = { - { SIP_UNKNOWN, RTP, "-UNKNOWN-" }, - { SIP_RESPONSE, NO_RTP, "SIP/2.0" }, - { SIP_REGISTER, NO_RTP, "REGISTER" }, - { SIP_OPTIONS, NO_RTP, "OPTIONS" }, - { SIP_NOTIFY, NO_RTP, "NOTIFY" }, - { SIP_INVITE, RTP, "INVITE" }, - { SIP_ACK, NO_RTP, "ACK" }, - { SIP_PRACK, NO_RTP, "PRACK" }, - { SIP_BYE, NO_RTP, "BYE" }, - { SIP_REFER, NO_RTP, "REFER" }, + { SIP_UNKNOWN, RTP, "-UNKNOWN-" }, + { SIP_RESPONSE, NO_RTP, "SIP/2.0" }, + { SIP_REGISTER, NO_RTP, "REGISTER" }, + { SIP_OPTIONS, NO_RTP, "OPTIONS" }, + { SIP_NOTIFY, NO_RTP, "NOTIFY" }, + { SIP_INVITE, RTP, "INVITE" }, + { SIP_ACK, NO_RTP, "ACK" }, + { SIP_PRACK, NO_RTP, "PRACK" }, + { SIP_BYE, NO_RTP, "BYE" }, + { SIP_REFER, NO_RTP, "REFER" }, { SIP_SUBSCRIBE, NO_RTP, "SUBSCRIBE" }, - { SIP_MESSAGE, NO_RTP, "MESSAGE" }, - { SIP_UPDATE, NO_RTP, "UPDATE" }, - { SIP_INFO, NO_RTP, "INFO" }, - { SIP_CANCEL, NO_RTP, "CANCEL" }, - { SIP_PUBLISH, NO_RTP, "PUBLISH" } + { SIP_MESSAGE, NO_RTP, "MESSAGE" }, + { SIP_UPDATE, NO_RTP, "UPDATE" }, + { SIP_INFO, NO_RTP, "INFO" }, + { SIP_CANCEL, NO_RTP, "CANCEL" }, + { SIP_PUBLISH, NO_RTP, "PUBLISH" } }; /* Structure for conversion between compressed SIP and "normal" SIP */ @@ -181,96 +177,79 @@ char * const fullname; char * const shortname; } aliases[] = { - { "Content-Type", "c" }, - { "Content-Encoding", "e" }, - { "From", "f" }, - { "Call-ID", "i" }, - { "Contact", "m" }, - { "Content-Length", "l" }, - { "Subject", "s" }, - { "To", "t" }, - { "Supported", "k" }, - { "Refer-To", "r" }, - { "Referred-By", "b" }, - { "Allow-Events", "u" }, - { "Event", "o" }, - { "Via", "v" }, + { "Content-Type", "c" }, + { "Content-Encoding", "e" }, + { "From", "f" }, + { "Call-ID", "i" }, + { "Contact", "m" }, + { "Content-Length", "l" }, + { "Subject", "s" }, + { "To", "t" }, + { "Supported", "k" }, + { "Refer-To", "r" }, + { "Referred-By", "b" }, + { "Allow-Events", "u" }, + { "Event", "o" }, + { "Via", "v" }, }; /* 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 -*/ -#define SUPPORTED 1 -#define NOT_SUPPORTED 0 - -#define SIP_OPT_REPLACES (1 << 0) -#define SIP_OPT_100REL (1 << 1) -#define SIP_OPT_TIMER (1 << 2) -#define SIP_OPT_EARLY_SESSION (1 << 3) -#define SIP_OPT_JOIN (1 << 4) -#define SIP_OPT_PATH (1 << 5) -#define SIP_OPT_PREF (1 << 6) -#define SIP_OPT_PRECONDITION (1 << 7) -#define SIP_OPT_PRIVACY (1 << 8) -#define SIP_OPT_SDP_ANAT (1 << 9) -#define SIP_OPT_SEC_AGREE (1 << 10) -#define SIP_OPT_EVENTLIST (1 << 11) -#define SIP_OPT_GRUU (1 << 12) -#define SIP_OPT_TARGET_DIALOG (1 << 13) +/* 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 + */ +#define SUPPORTED 1 +#define NOT_SUPPORTED 0 + +#define SIP_OPT_REPLACES (1 << 0) +#define SIP_OPT_100REL (1 << 1) +#define SIP_OPT_TIMER (1 << 2) +#define SIP_OPT_EARLY_SESSION (1 << 3) +#define SIP_OPT_JOIN (1 << 4) +#define SIP_OPT_PATH (1 << 5) +#define SIP_OPT_PREF (1 << 6) +#define SIP_OPT_PRECONDITION (1 << 7) +#define SIP_OPT_PRIVACY (1 << 8) +#define SIP_OPT_SDP_ANAT (1 << 9) +#define SIP_OPT_SEC_AGREE (1 << 10) +#define SIP_OPT_EVENTLIST (1 << 11) +#define SIP_OPT_GRUU (1 << 12) +#define SIP_OPT_TARGET_DIALOG (1 << 13) /* List of well-known SIP options. If we get this in a require, - we should check the list and answer accordingly. */ + * we should check the list and answer accordingly. */ static const struct cfsip_options { - int id; /* Bitmap ID */ - int supported; /* Supported by Asterisk ? */ - char * const text; /* Text id, as in standard */ + int id; /* Bitmap ID */ + int supported; /* Supported by Asterisk ? */ + char * const text; /* Text id, as in standard */ } sip_options[] = { - /* Replaces: header for transfer */ - { SIP_OPT_REPLACES, SUPPORTED, "replaces" }, - /* RFC3262: PRACK 100% reliability */ - { SIP_OPT_100REL, NOT_SUPPORTED, "100rel" }, - /* SIP Session Timers */ - { SIP_OPT_TIMER, NOT_SUPPORTED, "timer" }, - /* RFC3959: SIP Early session support */ - { SIP_OPT_EARLY_SESSION, NOT_SUPPORTED, "early-session" }, - /* SIP Join header support */ - { SIP_OPT_JOIN, NOT_SUPPORTED, "join" }, - /* RFC3327: Path support */ - { SIP_OPT_PATH, NOT_SUPPORTED, "path" }, - /* RFC3840: Callee preferences */ - { SIP_OPT_PREF, NOT_SUPPORTED, "pref" }, - /* RFC3312: Precondition support */ - { SIP_OPT_PRECONDITION, NOT_SUPPORTED, "precondition" }, - /* RFC3323: Privacy with proxies*/ - { SIP_OPT_PRIVACY, NOT_SUPPORTED, "privacy" }, - /* Not yet RFC, but registred with IANA */ - { SIP_OPT_SDP_ANAT, NOT_SUPPORTED, "sdp_anat" }, - /* RFC3329: Security agreement mechanism */ - { SIP_OPT_SEC_AGREE, NOT_SUPPORTED, "sec_agree" }, - /* SIMPLE events: draft-ietf-simple-event-list-07.txt */ - { SIP_OPT_EVENTLIST, NOT_SUPPORTED, "eventlist" }, - /* GRUU: Globally Routable User Agent URI's */ - { SIP_OPT_GRUU, NOT_SUPPORTED, "gruu" }, - /* Target-dialog: draft-ietf-sip-target-dialog-00.txt */ - { SIP_OPT_TARGET_DIALOG,NOT_SUPPORTED, "target-dialog" }, + { SIP_OPT_REPLACES, SUPPORTED, "replaces" }, /* Replaces: header for transfer */ + { SIP_OPT_100REL, NOT_SUPPORTED, "100rel" }, /* RFC3262: PRACK 100% reliability */ + { SIP_OPT_TIMER, NOT_SUPPORTED, "timer" }, /* SIP Session Timers */ + { SIP_OPT_EARLY_SESSION, NOT_SUPPORTED, "early-session" }, /* RFC3959: SIP Early session support */ + { SIP_OPT_JOIN, NOT_SUPPORTED, "join" }, /* SIP Join header support */ + { SIP_OPT_PATH, NOT_SUPPORTED, "path" }, /* RFC3327: Path support */ + { SIP_OPT_PREF, NOT_SUPPORTED, "pref" }, /* RFC3840: Callee preferences */ + { SIP_OPT_PRECONDITION, NOT_SUPPORTED, "precondition" }, /* RFC3312: Precondition support */ + { SIP_OPT_PRIVACY, NOT_SUPPORTED, "privacy" }, /* RFC3323: Privacy with proxies*/ + { SIP_OPT_SDP_ANAT, NOT_SUPPORTED, "sdp_anat" }, /* Not yet RFC, but registred with IANA */ + { SIP_OPT_SEC_AGREE, NOT_SUPPORTED, "sec_agree" }, /* RFC3329: Security agreement mechanism */ + { SIP_OPT_EVENTLIST, NOT_SUPPORTED, "eventlist" }, /* SIMPLE events: draft-ietf-simple-event-list-07.txt */ + { SIP_OPT_GRUU, NOT_SUPPORTED, "gruu" }, /* GRUU: Globally Routable User Agent URI's */ + { SIP_OPT_TARGET_DIALOG, NOT_SUPPORTED, "target-dialog" }, /* Target-dialog: draft-ietf-sip-target-dialog-00.txt */ }; - /* SIP Methods we support */ #define ALLOWED_METHODS "INVITE, ACK, CANCEL, OPTIONS, BYE, REFER, NOTIFY" /* SIP Extensions we support */ -#define SUPPORTED_EXTENSIONS "replaces" +#define SUPPORTED_EXTENSIONS "replaces" -#define DEFAULT_SIP_PORT 5060 /* From RFC 3261 (former 2543) */ -#define SIP_MAX_PACKET 4096 /* Also from RFC 3261 (2543), should sub headers tho */ +#define DEFAULT_SIP_PORT 5060 /* From RFC 3261 (former 2543) */ +#define SIP_MAX_PACKET 4096 /* Also from RFC 3261 (2543), should sub headers tho */ static char default_useragent[AST_MAX_EXTENSION] = DEFAULT_USERAGENT; @@ -287,17 +266,16 @@ #define DEFAULT_NOTIFYMIME "application/simple-message-summary" static char default_notifymime[AST_MAX_EXTENSION] = DEFAULT_NOTIFYMIME; +static int default_qualify = 0; /* Default Qualify= setting */ -static int default_qualify = 0; /* Default Qualify= setting */ +static struct ast_flags global_flags = {0}; /* global SIP_ flags */ +static struct ast_flags global_flags_page2 = {0}; /* more global SIP_ flags */ -static struct ast_flags global_flags = {0}; /* global SIP_ flags */ -static struct ast_flags global_flags_page2 = {0}; /* more global SIP_ flags */ +static int srvlookup = 0; /* SRV Lookup on or off. Default is off, RFC behavior is on */ -static int srvlookup = 0; /* SRV Lookup on or off. Default is off, RFC behavior is on */ +static int pedanticsipchecking = 0; /* Extra checking ? Default off */ -static int pedanticsipchecking = 0; /* Extra checking ? Default off */ - -static int autocreatepeer = 0; /* Auto creation of peers at registration? Default off. */ +static int autocreatepeer = 0; /* Auto creation of peers at registration? Default off. */ static int relaxdtmf = 0; @@ -307,7 +285,7 @@ static int global_rtpkeepalive = 0; -static int global_reg_timeout = DEFAULT_REGISTRATION_TIMEOUT; +static int global_reg_timeout = DEFAULT_REGISTRATION_TIMEOUT; static int global_regattempts_max = DEFAULT_REGATTEMPTS_MAX; /* Object counters */ @@ -318,26 +296,25 @@ static int apeerobjs = 0; static int regobjs = 0; -static int global_allowguest = 1; /* allow unauthenticated users/peers to connect? */ +static int global_allowguest = 1; /* allow unauthenticated users/peers to connect? */ #define DEFAULT_MWITIME 10 -static int global_mwitime = DEFAULT_MWITIME; /* Time between MWI checks for peers */ +static int global_mwitime = DEFAULT_MWITIME; /* Time between MWI checks for peers */ -static int usecnt =0; +static int usecnt = 0; AST_MUTEX_DEFINE_STATIC(usecnt_lock); - /* Protect the interface list (of sip_pvt's) */ AST_MUTEX_DEFINE_STATIC(iflock); /* Protect the monitoring thread, so only one process can kill or start it, and not - when it's doing something critical. */ + * when it's doing something critical. */ AST_MUTEX_DEFINE_STATIC(netlock); AST_MUTEX_DEFINE_STATIC(monlock); /* This is the thread for the monitor which checks for input on the channels - which are not currently in use. */ + * which are not currently in use. */ static pthread_t monitor_thread = AST_PTHREADT_NULL; static int restart_monitor(void); @@ -357,14 +334,14 @@ static int videosupport = 0; -static int compactheaders = 0; /* send compact sip headers */ +static int compactheaders = 0; /* send compact sip headers */ -static int recordhistory = 0; /* Record SIP history. Off by default */ +static int recordhistory = 0; /* Record SIP history. Off by default */ -static char global_musicclass[MAX_MUSICCLASS] = ""; /* Global music on hold class */ -#define DEFAULT_REALM "asterisk" -static char global_realm[MAXHOSTNAMELEN] = DEFAULT_REALM; /* Default realm */ -static char regcontext[AST_MAX_CONTEXT] = ""; /* Context for auto-extensions */ +static char global_musicclass[MAX_MUSICCLASS] = ""; /* Global music on hold class */ +#define DEFAULT_REALM "asterisk" +static char global_realm[MAXHOSTNAMELEN] = DEFAULT_REALM; /* Default realm */ +static char regcontext[AST_MAX_CONTEXT] = ""; /* Context for auto-extensions */ /* Expire slowly */ #define DEFAULT_EXPIRY 900 @@ -373,31 +350,29 @@ static struct sched_context *sched; static struct io_context *io; /* The private structures of the sip channels are linked for - selecting outgoing channels */ - -#define SIP_MAX_HEADERS 64 -#define SIP_MAX_LINES 64 - -#define DEC_IN_USE 0 -#define INC_IN_USE 1 -#define DEC_OUT_USE 2 -#define INC_OUT_USE 3 + * selecting outgoing channels */ +#define SIP_MAX_HEADERS 64 +#define SIP_MAX_LINES 64 + +#define DEC_IN_USE 0 +#define INC_IN_USE 1 +#define DEC_OUT_USE 2 +#define INC_OUT_USE 3 static struct ast_codec_pref prefs; - /* sip_request: The data grabbed from the UDP socket */ struct sip_request { - char *rlPart1; /* SIP Method Name or "SIP/2.0" protocol version */ - char *rlPart2; /* The Request URI or Response Status */ - int len; /* Length */ - int headers; /* # of SIP Headers */ - int method; /* Method of this request */ + char *rlPart1; /* SIP Method Name or "SIP/2.0" protocol version */ + char *rlPart2; /* The Request URI or Response Status */ + int len; /* Length */ + int headers; /* # of SIP Headers */ + int method; /* Method of this request */ char *header[SIP_MAX_HEADERS]; - int lines; /* SDP Content */ + int lines; /* SDP Content */ char *line[SIP_MAX_LINES]; char data[SIP_MAX_PACKET]; - int debug; /* Debug flag for this packet */ + int debug; /* Debug flag for this packet */ }; struct sip_pkt; @@ -432,165 +407,165 @@ struct sip_auth *next; /* Next auth structure in list */ }; -#define SIP_ALREADYGONE (1 << 0) /* Whether or not we've already been destroyed by our peer */ -#define SIP_NEEDDESTROY (1 << 1) /* if we need to be destroyed */ -#define SIP_NOVIDEO (1 << 2) /* Didn't get video in invite, don't offer */ -#define SIP_RINGING (1 << 3) /* Have sent 180 ringing */ -#define SIP_PROGRESS_SENT (1 << 4) /* Have sent 183 message progress */ -#define SIP_NEEDREINVITE (1 << 5) /* Do we need to send another reinvite? */ -#define SIP_PENDINGBYE (1 << 6) /* Need to send bye after we ack? */ -#define SIP_GOTREFER (1 << 7) /* Got a refer? */ -#define SIP_PROMISCREDIR (1 << 8) /* Promiscuous redirection */ -#define SIP_TRUSTRPID (1 << 9) /* Trust RPID headers? */ -#define SIP_USEREQPHONE (1 << 10) /* Add user=phone to numeric URI. Default off */ -#define SIP_REALTIME (1 << 11) /* Flag for realtime users */ -#define SIP_USECLIENTCODE (1 << 12) /* Trust X-ClientCode info message */ -#define SIP_OUTGOING (1 << 13) /* Is this an outgoing call? */ -#define SIP_SELFDESTRUCT (1 << 14) -#define SIP_DYNAMIC (1 << 15) /* Is this a dynamic peer? */ +#define SIP_ALREADYGONE (1 << 0) /* Whether or not we've already been destroyed by our peer */ +#define SIP_NEEDDESTROY (1 << 1) /* if we need to be destroyed */ +#define SIP_NOVIDEO (1 << 2) /* Didn't get video in invite, don't offer */ +#define SIP_RINGING (1 << 3) /* Have sent 180 ringing */ +#define SIP_PROGRESS_SENT (1 << 4) /* Have sent 183 message progress */ +#define SIP_NEEDREINVITE (1 << 5) /* Do we need to send another reinvite? */ +#define SIP_PENDINGBYE (1 << 6) /* Need to send bye after we ack? */ +#define SIP_GOTREFER (1 << 7) /* Got a refer? */ +#define SIP_PROMISCREDIR (1 << 8) /* Promiscuous redirection */ +#define SIP_TRUSTRPID (1 << 9) /* Trust RPID headers? */ +#define SIP_USEREQPHONE (1 << 10) /* Add user=phone to numeric URI. Default off */ +#define SIP_REALTIME (1 << 11) /* Flag for realtime users */ +#define SIP_USECLIENTCODE (1 << 12) /* Trust X-ClientCode info message */ +#define SIP_OUTGOING (1 << 13) /* Is this an outgoing call? */ +#define SIP_SELFDESTRUCT (1 << 14) +#define SIP_DYNAMIC (1 << 15) /* Is this a dynamic peer? */ /* --- Choices for DTMF support in SIP channel */ -#define SIP_DTMF (3 << 16) /* three settings, uses two bits */ -#define SIP_DTMF_RFC2833 (0 << 16) /* RTP DTMF */ -#define SIP_DTMF_INBAND (1 << 16) /* Inband audio, only for ULAW/ALAW */ -#define SIP_DTMF_INFO (2 << 16) /* SIP Info messages */ +#define SIP_DTMF (3 << 16) /* three settings, uses two bits */ +#define SIP_DTMF_RFC2833 (0 << 16) /* RTP DTMF */ +#define SIP_DTMF_INBAND (1 << 16) /* Inband audio, only for ULAW/ALAW */ +#define SIP_DTMF_INFO (2 << 16) /* SIP Info messages */ /* NAT settings */ -#define SIP_NAT (3 << 18) /* four settings, uses two bits */ -#define SIP_NAT_NEVER (0 << 18) /* No nat support */ -#define SIP_NAT_RFC3581 (1 << 18) -#define SIP_NAT_ROUTE (2 << 18) -#define SIP_NAT_ALWAYS (3 << 18) +#define SIP_NAT (3 << 18) /* four settings, uses two bits */ +#define SIP_NAT_NEVER (0 << 18) /* No nat support */ +#define SIP_NAT_RFC3581 (1 << 18) +#define SIP_NAT_ROUTE (2 << 18) +#define SIP_NAT_ALWAYS (3 << 18) /* re-INVITE related settings */ -#define SIP_REINVITE (3 << 20) /* two bits used */ -#define SIP_CAN_REINVITE (1 << 20) /* allow peers to be reinvited to send media directly p2p */ -#define SIP_REINVITE_UPDATE (2 << 20) /* use UPDATE (RFC3311) when reinviting this peer */ +#define SIP_REINVITE (3 << 20) /* two bits used */ +#define SIP_CAN_REINVITE (1 << 20) /* allow peers to be reinvited to send media directly p2p */ +#define SIP_REINVITE_UPDATE (2 << 20) /* use UPDATE (RFC3311) when reinviting this peer */ /* "insecure" settings */ -#define SIP_INSECURE_PORT (1 << 22) /* don't require matching port for incoming requests */ -#define SIP_INSECURE_INVITE (1 << 23) /* don't require authentication for incoming INVITEs */ +#define SIP_INSECURE_PORT (1 << 22) /* don't require matching port for incoming requests */ +#define SIP_INSECURE_INVITE (1 << 23) /* don't require authentication for incoming INVITEs */ /* Sending PROGRESS in-band settings */ -#define SIP_PROG_INBAND (3 << 24) /* three settings, uses two bits */ -#define SIP_PROG_INBAND_NEVER (0 << 24) -#define SIP_PROG_INBAND_NO (1 << 24) -#define SIP_PROG_INBAND_YES (2 << 24) +#define SIP_PROG_INBAND (3 << 24) /* three settings, uses two bits */ +#define SIP_PROG_INBAND_NEVER (0 << 24) +#define SIP_PROG_INBAND_NO (1 << 24) +#define SIP_PROG_INBAND_YES (2 << 24) /* Open Settlement Protocol authentication */ -#define SIP_OSPAUTH (3 << 26) /* three settings, uses two bits */ -#define SIP_OSPAUTH_NO (0 << 26) -#define SIP_OSPAUTH_YES (1 << 26) -#define SIP_OSPAUTH_EXCLUSIVE (2 << 26) +#define SIP_OSPAUTH (3 << 26) /* three settings, uses two bits */ +#define SIP_OSPAUTH_NO (0 << 26) +#define SIP_OSPAUTH_YES (1 << 26) +#define SIP_OSPAUTH_EXCLUSIVE (2 << 26) /* Call states */ -#define SIP_CALL_ONHOLD (1 << 28) -#define SIP_CALL_LIMIT (1 << 29) +#define SIP_CALL_ONHOLD (1 << 28) +#define SIP_CALL_LIMIT (1 << 29) /* a new page of flags for peer */ -#define SIP_PAGE2_RTCACHEFRIENDS (1 << 0) -#define SIP_PAGE2_RTNOUPDATE (1 << 1) -#define SIP_PAGE2_RTAUTOCLEAR (1 << 2) -#define SIP_PAGE2_RTIGNOREREGEXPIRE (1 << 3) +#define SIP_PAGE2_RTCACHEFRIENDS (1 << 0) +#define SIP_PAGE2_RTNOUPDATE (1 << 1) +#define SIP_PAGE2_RTAUTOCLEAR (1 << 2) +#define SIP_PAGE2_RTIGNOREREGEXPIRE (1 << 3) static int global_rtautoclear = 120; /* sip_pvt: PVT structures are used for each SIP conversation, ie. a call */ static struct sip_pvt { - ast_mutex_t lock; /* Channel private lock */ - int method; /* SIP method of this packet */ - char callid[80]; /* Global CallID */ - char randdata[80]; /* Random data */ - struct ast_codec_pref prefs; /* codec prefs */ - unsigned int ocseq; /* Current outgoing seqno */ - unsigned int icseq; /* Current incoming seqno */ - ast_group_t callgroup; /* Call group */ - ast_group_t pickupgroup; /* Pickup group */ - int lastinvite; /* Last Cseq of invite */ - unsigned int flags; /* SIP_ flags */ - unsigned int sipoptions; /* Supported SIP sipoptions on the other end */ - int capability; /* Special capability (codec) */ - int jointcapability; /* Supported capability at both ends (codecs ) */ - int peercapability; /* Supported peer capability */ - int prefcodec; /* Preferred codec (outbound only) */ + ast_mutex_t lock; /* Channel private lock */ + int method; /* SIP method of this packet */ + char callid[80]; /* Global CallID */ + char randdata[80]; /* Random data */ + struct ast_codec_pref prefs; /* codec prefs */ + unsigned int ocseq; /* Current outgoing seqno */ + unsigned int icseq; /* Current incoming seqno */ + ast_group_t callgroup; /* Call group */ + ast_group_t pickupgroup; /* Pickup group */ + int lastinvite; /* Last Cseq of invite */ + unsigned int flags; /* SIP_ flags */ + unsigned int sipoptions; /* Supported SIP sipoptions on the other end */ + int capability; /* Special capability (codec) */ + int jointcapability; /* Supported capability at both ends (codecs) */ + int peercapability; /* Supported peer capability */ + int prefcodec; /* Preferred codec (outbound only) */ int noncodeccapability; - int callingpres; /* Calling presentation */ - int authtries; /* Times we've tried to authenticate */ - int expiry; /* How long we take to expire */ - int branch; /* One random number */ - int tag; /* Another random number */ - int sessionid; /* SDP Session ID */ - int sessionversion; /* SDP Session Version */ - struct sockaddr_in sa; /* Our peer */ - struct sockaddr_in redirip; /* Where our RTP should be going if not to us */ - struct sockaddr_in vredirip; /* Where our Video RTP should be going if not to us */ - int redircodecs; /* Redirect codecs */ - struct sockaddr_in recv; /* Received as */ - struct in_addr ourip; /* Our IP */ - struct ast_channel *owner; /* Who owns us */ - char exten[AST_MAX_EXTENSION]; /* Extension where to start */ - char refer_to[AST_MAX_EXTENSION]; /* Place to store REFER-TO extension */ - char referred_by[AST_MAX_EXTENSION]; /* Place to store REFERRED-BY extension */ - char refer_contact[AST_MAX_EXTENSION]; /* Place to store Contact info from a REFER extension */ - struct sip_pvt *refer_call; /* Call we are referring */ - struct sip_route *route; /* Head of linked list of routing steps (fm Record-Route) */ - int route_persistant; /* Is this the "real" route? */ - char from[256]; /* The From: header */ - char useragent[256]; /* User agent in SIP request */ - char context[AST_MAX_CONTEXT]; /* Context for this call */ - char fromdomain[MAXHOSTNAMELEN]; /* Domain to show in the from field */ - char fromuser[AST_MAX_EXTENSION]; /* User to show in the user field */ - char fromname[AST_MAX_EXTENSION]; /* Name to show in the user field */ - char tohost[MAXHOSTNAMELEN]; /* Host we should put in the "to" field */ - char language[MAX_LANGUAGE]; /* Default language for this call */ - char musicclass[MAX_MUSICCLASS]; /* Music on Hold class */ - char rdnis[256]; /* Referring DNIS */ - char theirtag[256]; /* Their tag */ - char username[256]; /* [user] name */ - char peername[256]; /* [peer] name, not set if [user] */ - char authname[256]; /* Who we use for authentication */ - char uri[256]; /* Original requested URI */ - char okcontacturi[256]; /* URI from the 200 OK on INVITE */ - char peersecret[256]; /* Password */ + int callingpres; /* Calling presentation */ + int authtries; /* Times we've tried to authenticate */ + int expiry; /* How long we take to expire */ + int branch; /* One random number */ + int tag; /* Another random number */ + int sessionid; /* SDP Session ID */ + int sessionversion; /* SDP Session Version */ + struct sockaddr_in sa; /* Our peer */ + struct sockaddr_in redirip; /* Where our RTP should be going if not to us */ + struct sockaddr_in vredirip; /* Where our Video RTP should be going if not to us */ + int redircodecs; /* Redirect codecs */ + struct sockaddr_in recv; /* Received as */ + struct in_addr ourip; /* Our IP */ + struct ast_channel *owner; /* Who owns us */ + char exten[AST_MAX_EXTENSION]; /* Extension where to start */ + char refer_to[AST_MAX_EXTENSION]; /* Place to store REFER-TO extension */ + char referred_by[AST_MAX_EXTENSION]; /* Place to store REFERRED-BY extension */ + char refer_contact[AST_MAX_EXTENSION]; /* Place to store Contact info from a REFER extension */ + struct sip_pvt *refer_call; /* Call we are referring */ + struct sip_route *route; /* Head of linked list of routing steps (fm Record-Route) */ + int route_persistant; /* Is this the "real" route? */ + char from[256]; /* The From: header */ + char useragent[256]; /* User agent in SIP request */ + char context[AST_MAX_CONTEXT]; /* Context for this call */ + char fromdomain[MAXHOSTNAMELEN]; /* Domain to show in the from field */ + char fromuser[AST_MAX_EXTENSION]; /* User to show in the user field */ + char fromname[AST_MAX_EXTENSION]; /* Name to show in the user field */ + char tohost[MAXHOSTNAMELEN]; /* Host we should put in the "to" field */ + char language[MAX_LANGUAGE]; /* Default language for this call */ + char musicclass[MAX_MUSICCLASS]; /* Music on Hold class */ + char rdnis[256]; /* Referring DNIS */ + char theirtag[256]; /* Their tag */ + char username[256]; /* [user] name */ + char peername[256]; /* [peer] name, not set if [user] */ + char authname[256]; /* Who we use for authentication */ + char uri[256]; /* Original requested URI */ + char okcontacturi[256]; /* URI from the 200 OK on INVITE */ + char peersecret[256]; /* Password */ char peermd5secret[256]; - struct sip_auth *peerauth; /* Realm authentication */ - char cid_num[256]; /* Caller*ID */ - char cid_name[256]; /* Caller*ID */ - char via[256]; /* Via: header */ - char fullcontact[128]; /* The Contact: that the UA registers with us */ + struct sip_auth *peerauth; /* Realm authentication */ + char cid_num[256]; /* Caller*ID */ + char cid_name[256]; /* Caller*ID */ + char via[256]; /* Via: header */ + char fullcontact[128]; /* The Contact: that the UA registers with us */ char accountcode[AST_MAX_ACCOUNT_CODE]; /* Account code */ - char our_contact[256]; /* Our contact header */ - char realm[MAXHOSTNAMELEN]; /* Authorization realm */ - char nonce[256]; /* Authorization nonce */ - char opaque[256]; /* Opaque nonsense */ - char qop[80]; /* Quality of Protection, since SIP wasn't complicated enough yet. */ - char domain[MAXHOSTNAMELEN]; /* Authorization domain */ - char lastmsg[256]; /* Last Message sent/received */ - int amaflags; /* AMA Flags */ - int pendinginvite; /* Any pending invite */ + char our_contact[256]; /* Our contact header */ + char realm[MAXHOSTNAMELEN]; /* Authorization realm */ + char nonce[256]; /* Authorization nonce */ + char opaque[256]; /* Opaque nonsense */ + char qop[80]; /* Quality of Protection, since SIP wasn't complicated enough yet. */ + char domain[MAXHOSTNAMELEN]; /* Authorization domain */ + char lastmsg[256]; /* Last Message sent/received */ + int amaflags; /* AMA Flags */ + int pendinginvite; /* Any pending invite */ #ifdef OSP_SUPPORT - int osphandle; /* OSP Handle for call */ - time_t ospstart; /* OSP Start time */ + int osphandle; /* OSP Handle for call */ + time_t ospstart; /* OSP Start time */ #endif - struct sip_request initreq; /* Initial request */ - - int maxtime; /* Max time for first response */ - int maxforwards; /* keep the max-forwards info */ - int initid; /* Auto-congest ID if appropriate */ - int autokillid; /* Auto-kill ID */ - time_t lastrtprx; /* Last RTP received */ - time_t lastrtptx; /* Last RTP sent */ - int rtptimeout; /* RTP timeout time */ - int rtpholdtimeout; /* RTP timeout when on hold */ - int rtpkeepalive; /* Send RTP packets for keepalive */ + struct sip_request initreq; /* Initial request */ - int subscribed; /* Is this call a subscription? */ + int maxtime; /* Max time for first response */ + int maxforwards; /* keep the max-forwards info */ + int initid; /* Auto-congest ID if appropriate */ + int autokillid; /* Auto-kill ID */ + time_t lastrtprx; /* Last RTP received */ + time_t lastrtptx; /* Last RTP sent */ + int rtptimeout; /* RTP timeout time */ + int rtpholdtimeout; /* RTP timeout when on hold */ + int rtpkeepalive; /* Send RTP packets for keepalive */ + + int subscribed; /* Is this call a subscription? */ int stateid; int dialogver; - - struct ast_dsp *vad; /* Voice Activation Detection dsp */ - - struct sip_peer *peerpoke; /* If this calls is to poke a peer, which one */ - struct sip_registry *registry; /* If this is a REGISTER call, to which registry */ - struct ast_rtp *rtp; /* RTP Session */ - struct ast_rtp *vrtp; /* Video RTP session */ - struct sip_pkt *packets; /* Packets scheduled for re-transmission */ - struct sip_history *history; /* History of this SIP dialog */ - struct ast_variable *chanvars; /* Channel variables to set for call */ - struct sip_pvt *next; /* Next call in chain */ + + struct ast_dsp *vad; /* Voice Activation Detection dsp */ + + struct sip_peer *peerpoke; /* If this calls is to poke a peer, which one */ + struct sip_registry *registry; /* If this is a REGISTER call, to which registry */ + struct ast_rtp *rtp; /* RTP Session */ + struct ast_rtp *vrtp; /* Video RTP session */ + struct sip_pkt *packets; /* Packets scheduled for re-transmission */ + struct sip_history *history; /* History of this SIP dialog */ + struct ast_variable *chanvars; /* Channel variables to set for call */ + struct sip_pvt *next; /* Next call in chain */ } *iflist = NULL; #define FLAG_RESPONSE (1 << 0) @@ -598,102 +573,102 @@ /* sip packet - read in sipsock_read, transmitted in send_request */ struct sip_pkt { - struct sip_pkt *next; /* Next packet */ - int retrans; /* Retransmission number */ - int method; /* SIP method for this packet */ - int seqno; /* Sequence number */ - unsigned int flags; /* non-zero if this is a response packet (e.g. 200 OK) */ - struct sip_pvt *owner; /* Owner call */ - int retransid; /* Retransmission ID */ - int packetlen; /* Length of packet */ + struct sip_pkt *next; /* Next packet */ + int retrans; /* Retransmission number */ + int method; /* SIP method for this packet */ + int seqno; /* Sequence number */ + unsigned int flags; /* non-zero if this is a response packet (e.g. 200 OK) */ + struct sip_pvt *owner; /* Owner call */ + int retransid; /* Retransmission ID */ + int packetlen; /* Length of packet */ char data[0]; -}; +}; /* Structure for SIP user data. User's place calls to us */ struct sip_user { /* Users who can access various contexts */ ASTOBJ_COMPONENTS(struct sip_user); - char secret[80]; /* Password */ - char md5secret[80]; /* Password in md5 */ - char context[AST_MAX_CONTEXT]; /* Default context for incoming calls */ - char cid_num[80]; /* Caller ID num */ - char cid_name[80]; /* Caller ID name */ + char secret[80]; /* Password */ + char md5secret[80]; /* Password in md5 */ + char context[AST_MAX_CONTEXT]; /* Default context for incoming calls */ + char cid_num[80]; /* Caller ID num */ + char cid_name[80]; /* Caller ID name */ char accountcode[AST_MAX_ACCOUNT_CODE]; /* Account code */ - char language[MAX_LANGUAGE]; /* Default language for this user */ - char musicclass[MAX_MUSICCLASS];/* Music on Hold class */ - char useragent[256]; /* User agent in SIP request */ - struct ast_codec_pref prefs; /* codec prefs */ - ast_group_t callgroup; /* Call group */ - ast_group_t pickupgroup; /* Pickup Group */ - unsigned int flags; /* SIP flags */ - unsigned int sipoptions; /* Supported SIP options */ - struct ast_flags flags_page2; /* SIP_PAGE2 flags */ - int amaflags; /* AMA flags for billing */ - int callingpres; /* Calling id presentation */ - int capability; /* Codec capability */ - int inUse; /* Number of calls in use */ - int incominglimit; /* Limit of incoming calls */ - int outUse; /* disabled */ - int outgoinglimit; /* disabled */ - struct ast_ha *ha; /* ACL setting */ - struct ast_variable *chanvars; /* Variables to set for channel created by user */ + char language[MAX_LANGUAGE]; /* Default language for this user */ + char musicclass[MAX_MUSICCLASS]; /* Music on Hold class */ + char useragent[256]; /* User agent in SIP request */ + struct ast_codec_pref prefs; /* codec prefs */ + ast_group_t callgroup; /* Call group */ + ast_group_t pickupgroup; /* Pickup Group */ + unsigned int flags; /* SIP flags */ + unsigned int sipoptions; /* Supported SIP options */ + struct ast_flags flags_page2; /* SIP_PAGE2 flags */ + int amaflags; /* AMA flags for billing */ + int callingpres; /* Calling id presentation */ + int capability; /* Codec capability */ + int inUse; /* Number of calls in use */ + int incominglimit; /* Limit of incoming calls */ + int outUse; /* disabled */ + int outgoinglimit; /* disabled */ + struct ast_ha *ha; /* ACL setting */ + struct ast_variable *chanvars; /* Variables to set for channel created by user */ }; /* Structure for SIP peer data, we place calls to peers if registred or fixed IP address (host) */ struct sip_peer { - ASTOBJ_COMPONENTS(struct sip_peer); /* name, refcount, objflags, object pointers */ - /* peer->name is the unique name of this object */ - char secret[80]; /* Password */ - char md5secret[80]; /* Password in MD5 */ - struct sip_auth *auth; /* Realm authentication list */ - char context[AST_MAX_CONTEXT]; /* Default context for incoming calls */ - char username[80]; /* Temporary username until registration */ + ASTOBJ_COMPONENTS(struct sip_peer); /* name, refcount, objflags, object pointers + peer->name is the unique name of this object */ + char secret[80]; /* Password */ + char md5secret[80]; /* Password in MD5 */ + struct sip_auth *auth; /* Realm authentication list */ + char context[AST_MAX_CONTEXT]; /* Default context for incoming calls */ + char username[80]; /* Temporary username until registration */ char accountcode[AST_MAX_ACCOUNT_CODE]; /* Account code */ - int amaflags; /* AMA Flags (for billing) */ - char tohost[MAXHOSTNAMELEN]; /* If not dynamic, IP address */ - char regexten[AST_MAX_EXTENSION]; /* Extension to register (if regcontext is used) */ - char fromuser[80]; /* From: user when calling this peer */ - char fromdomain[MAXHOSTNAMELEN]; /* From: domain when calling this peer */ - char fullcontact[256]; /* Contact registred with us (not in sip.conf) */ - char cid_num[80]; /* Caller ID num */ - char cid_name[80]; /* Caller ID name */ - int callingpres; /* Calling id presentation */ - int inUse; /* Number of calls in use */ - int incominglimit; /* Limit of incoming calls */ - int outUse; /* disabled */ - int outgoinglimit; /* disabled */ - char mailbox[AST_MAX_EXTENSION]; /* Mailbox setting for MWI checks */ - char language[MAX_LANGUAGE]; /* Default language for prompts */ - char musicclass[MAX_MUSICCLASS];/* Music on Hold class */ - char useragent[256]; /* User agent in SIP request (saved from registration) */ - struct ast_codec_pref prefs; /* codec prefs */ + int amaflags; /* AMA Flags (for billing) */ + char tohost[MAXHOSTNAMELEN]; /* If not dynamic, IP address */ + char regexten[AST_MAX_EXTENSION]; /* Extension to register (if regcontext is used) */ + char fromuser[80]; /* From: user when calling this peer */ + char fromdomain[MAXHOSTNAMELEN]; /* From: domain when calling this peer */ + char fullcontact[256]; /* Contact registred with us (not in sip.conf) */ + char cid_num[80]; /* Caller ID num */ + char cid_name[80]; /* Caller ID name */ + int callingpres; /* Calling id presentation */ + int inUse; /* Number of calls in use */ + int incominglimit; /* Limit of incoming calls */ + int outUse; /* disabled */ + int outgoinglimit; /* disabled */ + char mailbox[AST_MAX_EXTENSION]; /* Mailbox setting for MWI checks */ + char language[MAX_LANGUAGE]; /* Default language for prompts */ + char musicclass[MAX_MUSICCLASS]; /* Music on Hold class */ + char useragent[256]; /* User agent in SIP request (saved from registration) */ + struct ast_codec_pref prefs; /* codec prefs */ int lastmsgssent; - time_t lastmsgcheck; /* Last time we checked for MWI */ - unsigned int flags; /* SIP flags */ - unsigned int sipoptions; /* Supported SIP options */ - struct ast_flags flags_page2; /* SIP_PAGE2 flags */ - int expire; /* When to expire this peer registration */ - int expiry; /* Duration of registration */ - int capability; /* Codec capability */ - int rtptimeout; /* RTP timeout */ - int rtpholdtimeout; /* RTP Hold Timeout */ - int rtpkeepalive; /* Send RTP packets for keepalive */ - ast_group_t callgroup; /* Call group */ - ast_group_t pickupgroup; /* Pickup group */ - struct ast_dnsmgr_entry *dnsmgr;/* DNS refresh manager for peer */ - struct sockaddr_in addr; /* IP address of peer */ + time_t lastmsgcheck; /* Last time we checked for MWI */ + unsigned int flags; /* SIP flags */ + unsigned int sipoptions; /* Supported SIP options */ + struct ast_flags flags_page2; /* SIP_PAGE2 flags */ + int expire; /* When to expire this peer registration */ + int expiry; /* Duration of registration */ + int capability; /* Codec capability */ + int rtptimeout; /* RTP timeout */ + int rtpholdtimeout; /* RTP Hold Timeout */ + int rtpkeepalive; /* Send RTP packets for keepalive */ + ast_group_t callgroup; /* Call group */ + ast_group_t pickupgroup; /* Pickup group */ + struct ast_dnsmgr_entry *dnsmgr; /* DNS refresh manager for peer */ + struct sockaddr_in addr; /* IP address of peer */ struct in_addr mask; /* Qualification */ - struct sip_pvt *call; /* Call pointer */ - int pokeexpire; /* When to expire poke (qualify= checking) */ - int lastms; /* How long last response took (in ms), or -1 for no response */ - int maxms; /* Max ms we will accept for the host to be up, 0 to not monitor */ - struct timeval ps; /* Ping send time */ - - struct sockaddr_in defaddr; /* Default IP address, used until registration */ - struct ast_ha *ha; /* Access control list */ - struct ast_variable *chanvars; /* Variables to set for channel created by user */ + struct sip_pvt *call; /* Call pointer */ + int pokeexpire; /* When to expire poke (qualify= checking) */ + int lastms; /* How long last response took (in ms), or -1 for no response */ + int maxms; /* Max ms we will accept for the host to be up, 0 to not monitor */ + struct timeval ps; /* Ping send time */ + + struct sockaddr_in defaddr; /* Default IP address, used until registration */ + struct ast_ha *ha; /* Access control list */ + struct ast_variable *chanvars; /* Variables to set for channel created by user */ int lastmsg; }; @@ -701,46 +676,45 @@ static int sip_reloading = 0; /* States for outbound registrations (with register= lines in sip.conf */ -#define REG_STATE_UNREGISTERED 0 -#define REG_STATE_REGSENT 1 -#define REG_STATE_AUTHSENT 2 -#define REG_STATE_REGISTERED 3 -#define REG_STATE_REJECTED 4 -#define REG_STATE_TIMEOUT 5 -#define REG_STATE_NOAUTH 6 -#define REG_STATE_FAILED 7 - +#define REG_STATE_UNREGISTERED 0 +#define REG_STATE_REGSENT 1 +#define REG_STATE_AUTHSENT 2 +#define REG_STATE_REGISTERED 3 +#define REG_STATE_REJECTED 4 +#define REG_STATE_TIMEOUT 5 +#define REG_STATE_NOAUTH 6 +#define REG_STATE_FAILED 7 /* sip_registry: Registrations with other SIP proxies */ struct sip_registry { - ASTOBJ_COMPONENTS_FULL(struct sip_registry,1,1); - int portno; /* Optional port override */ - char username[80]; /* Who we are registering as */ - char authuser[80]; /* Who we *authenticate* as */ - char hostname[MAXHOSTNAMELEN]; /* Domain or host we register to */ - char secret[80]; /* Password or key name in []'s */ + ASTOBJ_COMPONENTS_FULL(struct sip_registry, 1, 1); + int portno; /* Optional port override */ + char username[80]; /* Who we are registering as */ + char authuser[80]; /* Who we *authenticate* as */ + char hostname[MAXHOSTNAMELEN]; /* Domain or host we register to */ + char secret[80]; /* Password or key name in []'s */ char md5secret[80]; - char contact[256]; /* Contact extension */ + char contact[256]; /* Contact extension */ char random[80]; - int expire; /* Sched ID of expiration */ - int regattempts; /* Number of attempts (since the last success) */ - int timeout; /* sched id of sip_reg_timeout */ - int refresh; /* How often to refresh */ - struct sip_pvt *call; /* create a sip_pvt structure for each outbound "registration call" in progress */ - int regstate; /* Registration state (see above) */ - int callid_valid; /* 0 means we haven't chosen callid for this registry yet. */ - char callid[80]; /* Global CallID for this registry */ - unsigned int ocseq; /* Sequence number we got to for REGISTERs for this registry */ - struct sockaddr_in us; /* Who the server thinks we are */ - - /* Saved headers */ - char realm[MAXHOSTNAMELEN]; /* Authorization realm */ - char nonce[256]; /* Authorization nonce */ - char domain[MAXHOSTNAMELEN]; /* Authorization domain */ - char opaque[256]; /* Opaque nonsense */ - char qop[80]; /* Quality of Protection. */ - - char lastmsg[256]; /* Last Message sent/received */ + int expire; /* Sched ID of expiration */ + int regattempts; /* Number of attempts (since the last success) */ + int timeout; /* sched id of sip_reg_timeout */ + int refresh; /* How often to refresh */ + struct sip_pvt *call; /* create a sip_pvt structure for each outbound "registration call" in progress */ + int regstate; /* Registration state (see above) */ + int callid_valid; /* 0 means we haven't chosen callid for this registry yet. */ + char callid[80]; /* Global CallID for this registry */ + unsigned int ocseq; /* Sequence number we got to for REGISTERs for this registry */ + struct sockaddr_in us; /* Who the server thinks we are */ + + /* Saved headers */ + char realm[MAXHOSTNAMELEN]; /* Authorization realm */ + char nonce[256]; /* Authorization nonce */ + char domain[MAXHOSTNAMELEN]; /* Authorization domain */ + char opaque[256]; /* Opaque nonsense */ + char qop[80]; /* Quality of Protection. */ + + char lastmsg[256]; /* Last Message sent/received */ }; /*--- The user list: Users and friends ---*/ @@ -759,11 +733,7 @@ int recheck; } regl; - -static int __sip_do_register(struct sip_registry *r); - -static int sipsock = -1; - +static int sipsock = -1; static struct sockaddr_in bindaddr; static struct sockaddr_in externip; @@ -771,13 +741,15 @@ static time_t externexpire = 0; static int externrefresh = 10; static struct ast_ha *localaddr; +static int callevents = 0; /* The list of manual NOTIFY types we know how to send */ struct ast_config *notify_types; -static struct sip_auth *authl; /* Authentication list */ - +static struct sip_auth *authl; /* Authentication list */ +/* forward declarations */ +static int __sip_do_register(struct sip_registry *r); static struct ast_frame *sip_read(struct ast_channel *ast); static int transmit_response(struct sip_pvt *p, char *msg, struct sip_request *req); static int transmit_response_with_sdp(struct sip_pvt *p, char *msg, struct sip_request *req, int retrans); @@ -800,8 +772,6 @@ static struct sip_user *build_user(const char *name, struct ast_variable *v, int realtime); static int sip_do_reload(void); static int expire_register(void *data); -static int callevents = 0; - static struct ast_channel *sip_request_call(const char *type, int format, void *data, int *cause); static int sip_devicestate(void *data); static int sip_sendtext(struct ast_channel *ast, const char *text); @@ -814,11 +784,21 @@ static int sip_transfer(struct ast_channel *ast, const char *dest); static int sip_fixup(struct ast_channel *oldchan, struct ast_channel *newchan); static int sip_senddigit(struct ast_channel *ast, char digit); -static int clear_realm_authentication(struct sip_auth *authlist); /* Clear realm authentication list (at reload) */ -static struct sip_auth *add_realm_authentication(struct sip_auth *authlist, char *configuration, int lineno); /* Add realm authentication in list */ -static struct sip_auth *find_realm_authentication(struct sip_auth *authlist, char *realm); /* Find authentication for a specific realm */ -static void append_date(struct sip_request *req); /* Append date to SIP packet */ +static int clear_realm_authentication(struct sip_auth *authlist); /* Clear realm authentication list (at reload) */ +static struct sip_auth *add_realm_authentication(struct sip_auth *authlist, char *configuration, int lineno); /* Add realm authentication in list */ +static struct sip_auth *find_realm_authentication(struct sip_auth *authlist, char *realm); /* Find authentication for a specific realm */ +static void append_date(struct sip_request *req); /* Append date to SIP packet */ static int determine_firstline_parts(struct sip_request *req); +static void sip_destroy(struct sip_pvt *p); +static void parse_request(struct sip_request *req); +static char *get_header(struct sip_request *req, char *name); +static void copy_request(struct sip_request *dst, struct sip_request *src); +static int transmit_response_reliable(struct sip_pvt *p, char *msg, struct sip_request *req, int fatal); +static int sip_poke_peer(struct sip_peer *peer); +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[]); +static int reply_digest(struct sip_pvt *p, struct sip_request *req, char *header, int sipmethod, char *digest, int digest_len); +static int transmit_register(struct sip_registry *r, int sipmethod, char *auth, char *authheader); /* Definition of this channel for channel registration */ static const struct ast_channel_tech sip_tech = { @@ -846,15 +826,16 @@ int find_sip_method(char *msg) { int i, res = 0; - + if (!msg || ast_strlen_zero(msg)) return 0; /* 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 */ for (i = 1; (i < (sizeof(sip_methods) / sizeof(sip_methods[0]))) && !res; i++) { - if (!strcasecmp(sip_methods[i].text, msg)) + if (!strcasecmp(sip_methods[i].text, msg)) { res = sip_methods[i].id; + } } return res; } @@ -868,7 +849,7 @@ int i; unsigned int profile = 0; - if (!supported || ast_strlen_zero(supported) ) + if (!supported || ast_strlen_zero(supported)) return 0; if (option_debug > 2 && sipdebug) @@ -876,8 +857,8 @@ next = temp; while (next) { - char res=0; - if ( (sep = strchr(next, ',')) != NULL) { + char res = 0; + if ((sep = strchr(next, ',')) != NULL) { *sep = '\0'; sep++; } @@ -885,7 +866,7 @@ next++; if (option_debug > 2 && sipdebug) ast_log(LOG_DEBUG, "Found SIP option: -%s-\n", next); - for (i=0; (i < (sizeof(sip_options) / sizeof(sip_options[0]))) && !res; i++) { + for (i = 0; (i < (sizeof(sip_options) / sizeof(sip_options[0]))) && !res; i++) { if (!strcasecmp(next, sip_options[i].text)) { profile |= sip_options[i].id; res = 1; @@ -893,20 +874,20 @@ ast_log(LOG_DEBUG, "Matched SIP option: %s\n", next); } } - if (!res) + if (!res) if (option_debug > 2 && sipdebug) ast_log(LOG_DEBUG, "Found no match for SIP option: %s (Please file bug report!)\n", next); next = sep; } if (pvt) pvt->sipoptions = profile; - + ast_log(LOG_DEBUG, "* SIP extension value: %d for call %s\n", profile, pvt->callid); return profile; } /*--- sip_debug_test_addr: See if we pass debug IP filter */ -static inline int sip_debug_test_addr(struct sockaddr_in *addr) +static inline int sip_debug_test_addr(struct sockaddr_in *addr) { if (sipdebug == 0) return 0; @@ -920,45 +901,44 @@ } /*--- sip_debug_test_pvt: Test PVT for debugging output */ -static inline int sip_debug_test_pvt(struct sip_pvt *p) +static inline int sip_debug_test_pvt(struct sip_pvt *p) { if (sipdebug == 0) return 0; return sip_debug_test_addr(((ast_test_flag(p, SIP_NAT) & SIP_NAT_ROUTE) ? &p->recv : &p->sa)); } - /*--- __sip_xmit: Transmit SIP message ---*/ static int __sip_xmit(struct sip_pvt *p, char *data, int len) { int res; char iabuf[INET_ADDRSTRLEN]; - if (ast_test_flag(p, SIP_NAT) & SIP_NAT_ROUTE) - res=sendto(sipsock, data, len, 0, (struct sockaddr *)&p->recv, sizeof(struct sockaddr_in)); - else - res=sendto(sipsock, data, len, 0, (struct sockaddr *)&p->sa, sizeof(struct sockaddr_in)); + if (ast_test_flag(p, SIP_NAT) & SIP_NAT_ROUTE) { + res = sendto(sipsock, data, len, 0, (struct sockaddr *)&p->recv, sizeof(struct sockaddr_in)); + } else { + res = sendto(sipsock, data, len, 0, (struct sockaddr *)&p->sa, sizeof(struct sockaddr_in)); + } if (res != len) { ast_log(LOG_WARNING, "sip_xmit of %p (len %d) to %s returned %d: %s\n", data, len, ast_inet_ntoa(iabuf, sizeof(iabuf), p->sa.sin_addr), res, strerror(errno)); } return res; } -static void sip_destroy(struct sip_pvt *p); - /*--- build_via: Build a Via header for a request ---*/ static void build_via(struct sip_pvt *p, char *buf, int len) { char iabuf[INET_ADDRSTRLEN]; /* z9hG4bK is a magic cookie. See RFC 3261 section 8.1.1.7 */ - if (ast_test_flag(p, SIP_NAT) & SIP_NAT_RFC3581) + if (ast_test_flag(p, SIP_NAT) & SIP_NAT_RFC3581) { snprintf(buf, len, "SIP/2.0/UDP %s:%d;branch=z9hG4bK%08x;rport", ast_inet_ntoa(iabuf, sizeof(iabuf), p->ourip), ourport, p->branch); - else /* Work around buggy UNIDEN UIP200 firmware */ + } else { /* Work around buggy UNIDEN UIP200 firmware */ snprintf(buf, len, "SIP/2.0/UDP %s:%d;branch=z9hG4bK%08x", ast_inet_ntoa(iabuf, sizeof(iabuf), p->ourip), ourport, p->branch); + } } -/*--- ast_sip_ouraddrfor: NAT fix - decide which IP address to use for ASterisk server? ---*/ +/*--- ast_sip_ouraddrfor: NAT fix - decide which IP address to use for Asterisk server? ---*/ /* Only used for outbound registrations */ static int ast_sip_ouraddrfor(struct in_addr *them, struct in_addr *us) { @@ -970,7 +950,7 @@ struct sockaddr_in theirs; theirs.sin_addr = *them; if (localaddr && externip.sin_addr.s_addr && - ast_apply_ha(localaddr, &theirs)) { + ast_apply_ha(localaddr, &theirs)) { char iabuf[INET_ADDRSTRLEN]; if (externexpire && (time(NULL) >= externexpire)) { struct ast_hostent ahp; @@ -1002,7 +982,7 @@ if (!recordhistory) return 0; - if(!(hist = malloc(sizeof(struct sip_history)))) { + if (!(hist = malloc(sizeof(struct sip_history)))) { ast_log(LOG_WARNING, "Can't allocate memory for history"); return 0; } @@ -1010,7 +990,7 @@ snprintf(hist->event, sizeof(hist->event), "%-15s %s", event, data); /* Trim up nicely */ c = hist->event; - while(*c) { + while (*c) { if ((*c == '\r') || (*c == '\n')) { *c = '\0'; break; @@ -1020,7 +1000,7 @@ /* Enqueue into history */ prev = p->history; if (prev) { - while(prev->next) + while (prev->next) prev = prev->next; prev->next = hist; } else { @@ -1032,7 +1012,7 @@ /*--- retrans_pkt: Retransmit SIP message if no answer ---*/ static int retrans_pkt(void *data) { - struct sip_pkt *pkt=data, *prev, *cur; + struct sip_pkt *pkt = data, *prev, *cur; int res = 0; char iabuf[INET_ADDRSTRLEN]; ast_mutex_lock(&pkt->owner->lock); @@ -1052,7 +1032,7 @@ append_history(pkt->owner, "MaxRetries", (ast_test_flag(pkt, FLAG_FATAL)) ? "(Critical)" : "(Non-critical)"); pkt->retransid = -1; if (ast_test_flag(pkt, FLAG_FATAL)) { - while(pkt->owner->owner && ast_mutex_trylock(&pkt->owner->owner->lock)) { + while (pkt->owner->owner && ast_mutex_trylock(&pkt->owner->owner->lock)) { ast_mutex_unlock(&pkt->owner->lock); usleep(1); ast_mutex_lock(&pkt->owner->lock); @@ -1063,13 +1043,13 @@ ast_mutex_unlock(&pkt->owner->owner->lock); } else { /* If no owner, destroy now */ - ast_set_flag(pkt->owner, SIP_NEEDDESTROY); + ast_set_flag(pkt->owner, SIP_NEEDDESTROY); } } /* In any case, go ahead and remove the packet */ prev = NULL; cur = pkt->owner->packets; - while(cur) { + while (cur) { if (cur == pkt) break; prev = cur; @@ -1177,10 +1157,10 @@ msg = sip_methods[sipmethod].text; cur = p->packets; - while(cur) { + while (cur) { if ((cur->seqno == seqno) && ((ast_test_flag(cur, FLAG_RESPONSE)) == resp) && - ((ast_test_flag(cur, FLAG_RESPONSE)) || - (!strncasecmp(msg, cur->data, strlen(msg)) && (cur->data[strlen(msg)] < 33)))) { + ((ast_test_flag(cur, FLAG_RESPONSE)) || + (!strncasecmp(msg, cur->data, strlen(msg)) && (cur->data[strlen(msg)] < 33)))) { if (!resp && (seqno == p->pendinginvite)) { ast_log(LOG_DEBUG, "Acked pending invite %d\n", p->pendinginvite); p->pendinginvite = 0; @@ -1207,9 +1187,9 @@ /* Pretend to ack all packets */ static int __sip_pretend_ack(struct sip_pvt *p) { - struct sip_pkt *cur=NULL; + struct sip_pkt *cur = NULL; - while(p->packets) { + while (p->packets) { if (cur == p->packets) { ast_log(LOG_WARNING, "Have a packet that doesn't want to give up!\n"); return -1; @@ -1219,7 +1199,7 @@ __sip_ack(p, p->packets->seqno, (ast_test_flag(p->packets, FLAG_RESPONSE)), cur->method); else { /* Unknown packet type */ char *c; - char method[128]=""; + char method[128] = ""; ast_copy_string(method, p->packets->data, sizeof(method)); c = ast_skip_blanks(method); /* XXX what ? */ *c = '\0'; @@ -1237,10 +1217,10 @@ char *msg = sip_methods[sipmethod].text; cur = p->packets; - while(cur) { + while (cur) { if ((cur->seqno == seqno) && ((ast_test_flag(cur, FLAG_RESPONSE)) == resp) && - ((ast_test_flag(cur, FLAG_RESPONSE)) || - (!strncasecmp(msg, cur->data, strlen(msg)) && (cur->data[strlen(msg)] < 33)))) { + ((ast_test_flag(cur, FLAG_RESPONSE)) || + (!strncasecmp(msg, cur->data, strlen(msg)) && (cur->data[strlen(msg)] < 33)))) { /* this is our baby */ if (cur->retransid > -1) ast_sched_del(sched, cur->retransid); @@ -1254,10 +1234,6 @@ return res; } -static void parse_request(struct sip_request *req); -static char *get_header(struct sip_request *req, char *name); -static void copy_request(struct sip_request *dst,struct sip_request *src); - /*--- parse_copy: Copy SIP request, parse it */ static void parse_copy(struct sip_request *dst, struct sip_request *src) { @@ -1334,7 +1310,7 @@ } /*--- url_decode: Decode SIP URL (overwrite the string) ---*/ -static void url_decode(char *s) +static void url_decode(char *s) { char *o; unsigned int tmp; @@ -1397,7 +1373,7 @@ static int sip_sendtext(struct ast_channel *ast, const char *text) { struct sip_pvt *p = ast->tech_pvt; - int debug=sip_debug_test_pvt(p); + int debug = sip_debug_test_pvt(p); if (debug) ast_verbose("Sending text %s on %s\n", text, ast->name); @@ -1408,20 +1384,20 @@ if (debug) ast_verbose("Really sending text %s on %s\n", text, ast->name); transmit_message_with_text(p, text); - return 0; + return 0; } /*--- realtime_update_peer: Update peer object in realtime storage ---*/ -static void realtime_update_peer(const char *peername, struct sockaddr_in *sin, const char *username, int expirey) +static void realtime_update_peer(const char *peername, struct sockaddr_in *sin, const char *username, int expiry) { char port[10] = ""; char ipaddr[20] = ""; char regseconds[20] = "0"; - - if (expirey) { /* Registration */ + + if (expiry) { /* Registration */ time_t nowtime; time(&nowtime); - nowtime += expirey; + nowtime += expiry; snprintf(regseconds, sizeof(regseconds), "%ld", nowtime); /* Expiration time */ ast_inet_ntoa(ipaddr, sizeof(ipaddr), sin->sin_addr); snprintf(port, sizeof(port), "%d", ntohs(sin->sin_port)); @@ -1432,12 +1408,12 @@ /*--- register_peer_exten: Automatically add peer extension to dial plan ---*/ static void register_peer_exten(struct sip_peer *peer, int onoff) { - char multi[256]=""; + char multi[256] = ""; char *stringp, *ext; if (!ast_strlen_zero(regcontext)) { ast_copy_string(multi, ast_strlen_zero(peer->regexten) ? peer->name : peer->regexten, sizeof(multi)); stringp = multi; - while((ext = strsep(&stringp, "&"))) { + while ((ext = strsep(&stringp, "&"))) { if (onoff) ast_add_extension(regcontext, 1, ext, 1, NULL, NULL, "Noop", strdup(peer->name), free, channeltype); else @@ -1478,26 +1454,25 @@ /*--- update_peer: Update peer data in database (if used) ---*/ static void update_peer(struct sip_peer *p, int expiry) { - if (!ast_test_flag((&global_flags_page2), SIP_PAGE2_RTNOUPDATE) && - (ast_test_flag(p, SIP_REALTIME) || + if (!ast_test_flag((&global_flags_page2), SIP_PAGE2_RTNOUPDATE) && + (ast_test_flag(p, SIP_REALTIME) || ast_test_flag(&(p->flags_page2), SIP_PAGE2_RTCACHEFRIENDS))) { realtime_update_peer(p->name, &p->addr, p->username, expiry); } } - /*--- realtime_peer: Get peer from realtime storage ---*/ /* Checks the "sippeers" realtime family from extconfig.conf */ static struct sip_peer *realtime_peer(const char *peername, struct sockaddr_in *sin) { - struct sip_peer *peer=NULL; + struct sip_peer *peer = NULL; struct ast_variable *var; struct ast_variable *tmp; char *newpeername = (char *) peername; char iabuf[80] = ""; /* First check on peer name */ - if (newpeername) + if (newpeername) var = ast_load_realtime("sippeers", "name", peername, NULL); else if (sin) { /* Then check on IP address */ ast_inet_ntoa(iabuf, sizeof(iabuf), sin->sin_addr); @@ -1510,7 +1485,7 @@ tmp = var; /* If this is type=user, then skip this object. */ - while(tmp) { + while (tmp) { if (!strcasecmp(tmp->name, "type") && !strcasecmp(tmp->value, "user")) { ast_variables_destroy(var); @@ -1520,13 +1495,13 @@ } tmp = tmp->next; } - + if (!newpeername) { /* Did not find peer in realtime */ ast_log(LOG_WARNING, "Cannot Determine peer name ip=%s\n", iabuf); ast_variables_destroy(var); return (struct sip_peer *) NULL; } - + /* Peer found in realtime, now build it in memory */ peer = build_peer(newpeername, var, !ast_test_flag((&global_flags_page2), SIP_PAGE2_RTCACHEFRIENDS)); @@ -1536,14 +1511,14 @@ } if (ast_test_flag((&global_flags_page2), SIP_PAGE2_RTCACHEFRIENDS)) { /* Cache peer */ - ast_copy_flags((&peer->flags_page2),(&global_flags_page2), SIP_PAGE2_RTAUTOCLEAR|SIP_PAGE2_RTCACHEFRIENDS); + ast_copy_flags((&peer->flags_page2), (&global_flags_page2), SIP_PAGE2_RTAUTOCLEAR|SIP_PAGE2_RTCACHEFRIENDS); if (ast_test_flag((&global_flags_page2), SIP_PAGE2_RTAUTOCLEAR)) { if (peer->expire > -1) { ast_sched_del(sched, peer->expire); } peer->expire = ast_sched_add(sched, (global_rtautoclear) * 1000, expire_register, (void *)peer); } - ASTOBJ_CONTAINER_LINK(&peerl,peer); + ASTOBJ_CONTAINER_LINK(&peerl, peer); } else { ast_set_flag(peer, SIP_REALTIME); } @@ -1556,9 +1531,9 @@ { /* We know name is the first field, so we can cast */ struct sip_peer *p = (struct sip_peer *)name; - return !(!inaddrcmp(&p->addr, sin) || - (ast_test_flag(p, SIP_INSECURE_PORT) && - (p->addr.sin_addr.s_addr == sin->sin_addr.s_addr))); + return !(!inaddrcmp(&p->addr, sin) || + (ast_test_flag(p, SIP_INSECURE_PORT) && + (p->addr.sin_addr.s_addr == sin->sin_addr.s_addr))); } /*--- find_peer: Locate peer by name or ip address */ @@ -1569,9 +1544,9 @@ struct sip_peer *p = NULL; if (peer) - p = ASTOBJ_CONTAINER_FIND(&peerl,peer); + p = ASTOBJ_CONTAINER_FIND(&peerl, peer); else - p = ASTOBJ_CONTAINER_FIND_FULL(&peerl,sin,name,sip_addr_hashfunc,1,sip_addrcmp); + p = ASTOBJ_CONTAINER_FIND_FULL(&peerl, sin, name, sip_addr_hashfunc, 1, sip_addrcmp); if (!p && realtime) { p = realtime_peer(peer, sin); @@ -1618,11 +1593,9 @@ } tmp = tmp->next; } - - user = build_user(username, var, !ast_test_flag((&global_flags_page2), SIP_PAGE2_RTCACHEFRIENDS)); - + if (!user) { /* No user found */ ast_variables_destroy(var); return NULL; @@ -1631,7 +1604,7 @@ if (ast_test_flag((&global_flags_page2), SIP_PAGE2_RTCACHEFRIENDS)) { ast_set_flag((&user->flags_page2), SIP_PAGE2_RTCACHEFRIENDS); suserobjs++; - ASTOBJ_CONTAINER_LINK(&userl,user); + ASTOBJ_CONTAINER_LINK(&userl, user); } else { /* Move counter from s to r... */ suserobjs--; @@ -1644,12 +1617,12 @@ /*--- 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 + from in-memory list (static configuration) then from realtime storage (defined in extconfig.conf) */ static struct sip_user *find_user(const char *name, int realtime) { struct sip_user *u = NULL; - u = ASTOBJ_CONTAINER_FIND(&userl,name); + u = ASTOBJ_CONTAINER_FIND(&userl, name); if (!u && realtime) { u = realtime_user(name); } @@ -1677,9 +1650,8 @@ return -1; } - ast_copy_flags(r, peer, - SIP_PROMISCREDIR | SIP_USEREQPHONE | SIP_DTMF | SIP_NAT | SIP_REINVITE | - SIP_INSECURE_PORT | SIP_INSECURE_INVITE); + ast_copy_flags(r, peer, SIP_PROMISCREDIR | SIP_USEREQPHONE | SIP_DTMF | SIP_NAT | + SIP_REINVITE | SIP_INSECURE_PORT | SIP_INSECURE_INVITE); r->capability = peer->capability; if (r->rtp) { ast_log(LOG_DEBUG, "Setting NAT on RTP to %d\n", (ast_test_flag(r, SIP_NAT) & SIP_NAT_ROUTE)); @@ -1718,7 +1690,7 @@ r->noncodeccapability |= AST_RTP_DTMF; else r->noncodeccapability &= ~AST_RTP_DTMF; - ast_copy_string(r->context, peer->context,sizeof(r->context)); + ast_copy_string(r->context, peer->context, sizeof(r->context)); r->rtptimeout = peer->rtptimeout; r->rtpholdtimeout = peer->rtpholdtimeout; r->rtpkeepalive = peer->rtpkeepalive; @@ -1734,11 +1706,11 @@ struct hostent *hp; struct ast_hostent ahp; struct sip_peer *p; - int found=0; + int found = 0; char *port; int portno; char host[MAXHOSTNAMELEN], *hostn; - char peer[256]=""; + char peer[256] = ""; ast_copy_string(peer, opeer, sizeof(peer)); port = strchr(peer, ':'); @@ -1808,9 +1780,6 @@ return 0; } - - - /*--- sip_call: Initiate SIP call from PBX ---*/ /* used from the dial() application */ static int sip_call(struct ast_channel *ast, char *dest, int timeout) @@ -1819,13 +1788,13 @@ struct sip_pvt *p; #ifdef OSP_SUPPORT char *osphandle = NULL; -#endif +#endif struct varshead *headp; struct ast_var_t *current; struct sip_invite_param options; memset(&options, 0, sizeof(struct sip_invite_param)); - + p = ast->tech_pvt; if ((ast->_state != AST_STATE_DOWN) && (ast->_state != AST_STATE_RESERVED)) { ast_log(LOG_WARNING, "sip_call called on %s, neither down nor reserved\n", ast->name); @@ -1833,20 +1802,19 @@ } /* Check whether there is vxml_url, distinctive ring variables */ - headp=&ast->varshead; - AST_LIST_TRAVERSE(headp,current,entries) { + headp = &ast->varshead; + AST_LIST_TRAVERSE(headp, current, entries) { /* Check whether there is a VXML_URL variable */ - if (!options.vxml_url && !strcasecmp(ast_var_name(current),"VXML_URL")) { + if (!options.vxml_url && !strcasecmp(ast_var_name(current), "VXML_URL")) { options.vxml_url = ast_var_value(current); - } else if (!options.distinctive_ring && !strcasecmp(ast_var_name(current),"ALERT_INFO")) { + } else if (!options.distinctive_ring && !strcasecmp(ast_var_name(current), "ALERT_INFO")) { /* Check whether there is a ALERT_INFO variable */ options.distinctive_ring = ast_var_value(current); - } else if (!options.addsipheaders && !strncasecmp(ast_var_name(current),"SIPADDHEADER",strlen("SIPADDHEADER"))) { + } else if (!options.addsipheaders && !strncasecmp(ast_var_name(current), "SIPADDHEADER", strlen("SIPADDHEADER"))) { /* Check whether there is a variable with a name starting with SIPADDHEADER */ options.addsipheaders = 1; } - #ifdef OSP_SUPPORT else if (!options.osptoken && !strcasecmp(ast_var_name(current), "OSPTOKEN")) { options.osptoken = ast_var_value(current); @@ -1855,7 +1823,7 @@ } #endif } - + res = 0; ast_set_flag(p, SIP_OUTGOING); #ifdef OSP_SUPPORT @@ -1868,8 +1836,8 @@ } #endif ast_log(LOG_DEBUG, "Outgoing Call for %s\n", p->username); - res = update_user_counter(p,INC_OUT_USE); - if ( res != -1 ) { + res = update_user_counter(p, INC_OUT_USE); + if (res != -1) { p->callingpres = ast->cid.cid_pres; p->jointcapability = p->capability; transmit_invite(p, SIP_INVITE, 1, &options, 1); @@ -1887,8 +1855,8 @@ { /* Really delete */ if (reg->call) { - /* Clear registry before destroying to ensure - we don't get reentered trying to grab the registry lock */ + /* Clear registry before destroying to ensure we don't get reentered + * trying to grab the registry lock */ reg->call->registry = NULL; sip_destroy(reg->call); } @@ -1898,7 +1866,6 @@ ast_sched_del(sched, reg->timeout); regobjs--; free(reg); - } /*--- __sip_destroy: Execute destrucion of call structure, release memory---*/ @@ -1930,7 +1897,7 @@ if (p->registry) { if (p->registry->call == p) p->registry->call = NULL; - ASTOBJ_UNREF(p->registry,sip_registry_destroy); + ASTOBJ_UNREF(p->registry, sip_registry_destroy); } /* Unlink us from the owner if we have one */ if (p->owner) { @@ -1942,13 +1909,13 @@ ast_mutex_unlock(&p->owner->lock); } /* Clear history */ - while(p->history) { + while (p->history) { hist = p->history; p->history = p->history->next; free(hist); } cur = iflist; - while(cur) { + while (cur) { if (cur == p) { if (prev) prev->next = cur->next; @@ -1962,10 +1929,10 @@ if (!cur) { ast_log(LOG_WARNING, "Trying to destroy \"%s\", not found in dialog list?!?! \n", p->callid); return; - } + } if (p->initid > -1) ast_sched_del(sched, p->initid); - while((cp = p->packets)) { + while ((cp = p->packets)) { p->packets = p->packets->next; if (cp->retransid > -1) ast_sched_del(sched, cp->retransid); @@ -1989,8 +1956,8 @@ struct sip_peer *p; int *inuse, *incominglimit; - /* Test if we need to check call limits, in order to avoid - realtime lookups if we do not need it */ + /* Test if we need to check call limits, in order to avoid + * realtime lookups if we do not need it */ if (!ast_test_flag(fup, SIP_CALL_LIMIT)) return 0; @@ -2015,65 +1982,63 @@ return 0; } } - switch(event) { - /* incoming and outgoing affects the inUse counter */ - case DEC_OUT_USE: - case DEC_IN_USE: - if ( *inuse > 0 ) { - (*inuse)--; - } else { - *inuse = 0; - } - break; - case INC_IN_USE: - case INC_OUT_USE: - if (*incominglimit > 0 ) { - if (*inuse >= *incominglimit) { - ast_log(LOG_ERROR, "Call from %s '%s' rejected due to usage limit of %d\n", u?"user":"peer", name, *incominglimit); - /* inc inUse as well */ - if ( event == INC_OUT_USE ) { - (*inuse)++; - } - if (u) - ASTOBJ_UNREF(u,sip_destroy_user); - else - ASTOBJ_UNREF(p,sip_destroy_peer); - return -1; + switch (event) { /* incoming and outgoing affects the inUse counter */ + case DEC_OUT_USE: + case DEC_IN_USE: + if (*inuse > 0) { + (*inuse)--; + } else { + *inuse = 0; + } + break; + case INC_IN_USE: + case INC_OUT_USE: + if (*incominglimit > 0) { + if (*inuse >= *incominglimit) { + ast_log(LOG_ERROR, "Call from %s '%s' rejected due to usage limit of %d\n", u?"user":"peer", name, *incominglimit); + /* inc inUse as well */ + if (event == INC_OUT_USE) + (*inuse)++; + if (u) { + ASTOBJ_UNREF(u, sip_destroy_user); + } else { + ASTOBJ_UNREF(p, sip_destroy_peer); } + return -1; } - (*inuse)++; - ast_log(LOG_DEBUG, "Call from %s '%s' is %d out of %d\n", u?"user":"peer", name, *inuse, *incominglimit); - break; + } + (*inuse)++; + ast_log(LOG_DEBUG, "Call from %s '%s' is %d out of %d\n", u?"user":"peer", name, *inuse, *incominglimit); + break; #ifdef DISABLED_CODE /* we don't use these anymore */ - case DEC_OUT_USE: - if ( u->outUse > 0 ) { - u->outUse--; - } else { - u->outUse = 0; - } - break; - case INC_OUT_USE: - if ( u->outgoinglimit > 0 ) { - if ( u->outUse >= u->outgoinglimit ) { - ast_log(LOG_ERROR, "Outgoing call from user '%s' rejected due to usage limit of %d\n", u->name, u->outgoinglimit); - ast_mutex_unlock(&userl.lock); - if (u->temponly) { - destroy_user(u); - } - return -1; - } + case DEC_OUT_USE: + if (u->outUse > 0) { + u->outUse--; + } else { + u->outUse = 0; + } + break; + case INC_OUT_USE: + if (u->outgoinglimit > 0) { + if (u->outUse >= u->outgoinglimit) { + ast_log(LOG_ERROR, "Outgoing call from user '%s' rejected due to usage limit of %d\n", u->name, u->outgoinglimit); + ast_mutex_unlock(&userl.lock); + if (u->temponly) + destroy_user(u); + return -1; } - u->outUse++; - break; + } + u->outUse++; + break; #endif - default: - ast_log(LOG_ERROR, "update_user_counter(%s,%d) called with no event!\n",name,event); + default: + ast_log(LOG_ERROR, "update_user_counter(%s,%d) called with no event!\n", name, event); } if (u) - ASTOBJ_UNREF(u,sip_destroy_user); + ASTOBJ_UNREF(u, sip_destroy_user); else - ASTOBJ_UNREF(p,sip_destroy_peer); + ASTOBJ_UNREF(p, sip_destroy_peer); return 0; } @@ -2085,123 +2050,116 @@ ast_mutex_unlock(&iflock); } - -static int transmit_response_reliable(struct sip_pvt *p, char *msg, struct sip_request *req, int fatal); - /*--- hangup_sip2cause: Convert SIP hangup causes to Asterisk hangup causes ---*/ static int hangup_sip2cause(int cause) { /* Possible values taken from causes.h */ - switch(cause) { - case 403: /* Not found */ - return AST_CAUSE_CALL_REJECTED; - case 404: /* Not found */ - return AST_CAUSE_UNALLOCATED; - case 408: /* No reaction */ - return AST_CAUSE_NO_USER_RESPONSE; - case 480: /* No answer */ - return AST_CAUSE_FAILURE; - case 483: /* Too many hops */ - return AST_CAUSE_NO_ANSWER; - case 486: /* Busy everywhere */ - return AST_CAUSE_BUSY; - case 488: /* No codecs approved */ - return AST_CAUSE_BEARERCAPABILITY_NOTAVAIL; - case 500: /* Server internal failure */ - return AST_CAUSE_FAILURE; - case 501: /* Call rejected */ - return AST_CAUSE_FACILITY_REJECTED; - case 502: - return AST_CAUSE_DESTINATION_OUT_OF_ORDER; - case 503: /* Service unavailable */ - return AST_CAUSE_CONGESTION; - default: - return AST_CAUSE_NORMAL; + switch (cause) { + case 403: /* Not found */ + return AST_CAUSE_CALL_REJECTED; + case 404: /* Not found */ + return AST_CAUSE_UNALLOCATED; + case 408: /* No reaction */ + return AST_CAUSE_NO_USER_RESPONSE; + case 480: /* No answer */ + return AST_CAUSE_FAILURE; + case 483: /* Too many hops */ + return AST_CAUSE_NO_ANSWER; + case 486: /* Busy everywhere */ + return AST_CAUSE_BUSY; + case 488: /* No codecs approved */ + return AST_CAUSE_BEARERCAPABILITY_NOTAVAIL; + case 500: /* Server internal failure */ + return AST_CAUSE_FAILURE; + case 501: /* Call rejected */ + return AST_CAUSE_FACILITY_REJECTED; + case 502: + return AST_CAUSE_DESTINATION_OUT_OF_ORDER; + case 503: /* Service unavailable */ + return AST_CAUSE_CONGESTION; + default: + return AST_CAUSE_NORMAL; } /* Never reached */ return 0; } - /*--- 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 -*/ + * 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 + */ static char *hangup_cause2sip(int cause) { - switch(cause) - { - case AST_CAUSE_UNALLOCATED: /* 1 */ - case AST_CAUSE_NO_ROUTE_DESTINATION: /* 3 IAX2: Can't find extension in context */ - case AST_CAUSE_NO_ROUTE_TRANSIT_NET: /* 2 */ - return "404 Not Found"; - case AST_CAUSE_CONGESTION: /* 34 */ - case AST_CAUSE_SWITCH_CONGESTION: /* 42 */ - return "503 Service Unavailable"; - case AST_CAUSE_NO_USER_RESPONSE: /* 18 */ - return "408 Request Timeout"; - case AST_CAUSE_NO_ANSWER: /* 19 */ - return "480 Temporarily unavailable"; - case AST_CAUSE_CALL_REJECTED: /* 21 */ - return "403 Forbidden"; - case AST_CAUSE_NUMBER_CHANGED: /* 22 */ - return "410 Gone"; - case AST_CAUSE_NORMAL_UNSPECIFIED: /* 31 */ - return "480 Temporarily unavailable"; - case AST_CAUSE_INVALID_NUMBER_FORMAT: - return "484 Address incomplete"; - case AST_CAUSE_USER_BUSY: - return "486 Busy here"; - case AST_CAUSE_FAILURE: - return "500 Server internal failure"; - case AST_CAUSE_FACILITY_REJECTED: /* 29 */ - return "501 Not Implemented"; - case AST_CAUSE_CHAN_NOT_IMPLEMENTED: - return "503 Service Unavailable"; - /* Used in chan_iax2 */ - case AST_CAUSE_DESTINATION_OUT_OF_ORDER: - return "502 Bad Gateway"; - case AST_CAUSE_BEARERCAPABILITY_NOTAVAIL: /* Can't find codec to connect to host */ - return "488 Not Acceptable Here"; - - case AST_CAUSE_NOTDEFINED: - default: - ast_log(LOG_DEBUG, "AST hangup cause %d (no match found in SIP)\n", cause); - return NULL; + switch (cause) { + case AST_CAUSE_UNALLOCATED: /* 1 */ + case AST_CAUSE_NO_ROUTE_DESTINATION: /* 3 IAX2: Can't find extension in context */ + case AST_CAUSE_NO_ROUTE_TRANSIT_NET: /* 2 */ + return "404 Not Found"; + case AST_CAUSE_CONGESTION: /* 34 */ + case AST_CAUSE_SWITCH_CONGESTION: /* 42 */ + return "503 Service Unavailable"; + case AST_CAUSE_NO_USER_RESPONSE: /* 18 */ + return "408 Request Timeout"; + case AST_CAUSE_NO_ANSWER: /* 19 */ + return "480 Temporarily unavailable"; + case AST_CAUSE_CALL_REJECTED: /* 21 */ + return "403 Forbidden"; + case AST_CAUSE_NUMBER_CHANGED: /* 22 */ + return "410 Gone"; + case AST_CAUSE_NORMAL_UNSPECIFIED: /* 31 */ + return "480 Temporarily unavailable"; + case AST_CAUSE_INVALID_NUMBER_FORMAT: + return "484 Address incomplete"; + case AST_CAUSE_USER_BUSY: + return "486 Busy here"; + case AST_CAUSE_FAILURE: + return "500 Server internal failure"; + case AST_CAUSE_FACILITY_REJECTED: /* 29 */ + return "501 Not Implemented"; + case AST_CAUSE_CHAN_NOT_IMPLEMENTED: + return "503 Service Unavailable"; + /* Used in chan_iax2 */ + case AST_CAUSE_DESTINATION_OUT_OF_ORDER: + return "502 Bad Gateway"; + case AST_CAUSE_BEARERCAPABILITY_NOTAVAIL: /* Can't find codec to connect to host */ + return "488 Not Acceptable Here"; + case AST_CAUSE_NOTDEFINED: + default: + ast_log(LOG_DEBUG, "AST hangup cause %d (no match found in SIP)\n", cause); + return NULL; } /* Never reached */ return 0; } - /*--- sip_hangup: Hangup SIP call ---*/ /* Part of PBX interface */ static int sip_hangup(struct ast_channel *ast) @@ -2222,7 +2180,7 @@ if ((p->osphandle > -1) && (ast->_state == AST_STATE_UP)) { ast_osp_terminate(p->osphandle, AST_CAUSE_NORMAL, p->ospstart, time(NULL) - p->ospstart); } -#endif +#endif if (ast_test_flag(p, SIP_OUTGOING)) { ast_log(LOG_DEBUG, "update_user_counter(%s) - decrement outUse counter\n", p->username); update_user_counter(p, DEC_OUT_USE); @@ -2253,24 +2211,23 @@ ast_mutex_unlock(&usecnt_lock); ast_update_use_count(); - ast_set_flag(&locflags, SIP_NEEDDESTROY); + ast_set_flag(&locflags, SIP_NEEDDESTROY); /* Start the process if it's not already started */ if (!ast_test_flag(p, SIP_ALREADYGONE) && !ast_strlen_zero(p->initreq.data)) { if (needcancel) { /* Outgoing call, not up */ if (ast_test_flag(p, SIP_OUTGOING)) { transmit_request_with_auth(p, SIP_CANCEL, p->ocseq, 1, 0); - /* Actually don't destroy us yet, wait for the 487 on our original - INVITE, but do set an autodestruct just in case we never get it. */ + /* Actually don't destroy us yet, wait for the 487 on our original + * INVITE, but do set an autodestruct just in case we never get it. */ ast_clear_flag(&locflags, SIP_NEEDDESTROY); sip_scheddestroy(p, 15000); - if ( p->initid != -1 ) { - /* channel still up - reverse dec of inUse counter - only if the channel is not auto-congested */ + if (p->initid != -1) { + /* channel still up - reverse dec of inUse counter only if + * the channel is not auto-congested */ if (ast_test_flag(p, SIP_OUTGOING)) { update_user_counter(p, INC_OUT_USE); - } - else { + } else { update_user_counter(p, INC_IN_USE); } } @@ -2278,22 +2235,23 @@ char *res; if (ast->hangupcause && ((res = hangup_cause2sip(ast->hangupcause)))) { transmit_response_reliable(p, res, &p->initreq, 1); - } else + } else { transmit_response_reliable(p, "403 Forbidden", &p->initreq, 1); + } } } else { /* Call is in UP state, send BYE */ if (!p->pendinginvite) { /* Send a hangup */ transmit_request_with_auth(p, SIP_BYE, 0, 1, 1); } else { - /* Note we will need a BYE when this all settles out - but we can't send one while we have "INVITE" outstanding. */ - ast_set_flag(p, SIP_PENDINGBYE); - ast_clear_flag(p, SIP_NEEDREINVITE); + /* Note we will need a BYE when this all settles out but we + * can't send one while we have "INVITE" outstanding. */ + ast_set_flag(p, SIP_PENDINGBYE); + ast_clear_flag(p, SIP_NEEDREINVITE); } } } - ast_copy_flags(p, (&locflags), SIP_NEEDDESTROY); + ast_copy_flags(p, (&locflags), SIP_NEEDDESTROY); ast_mutex_unlock(&p->lock); return 0; } @@ -2302,27 +2260,27 @@ /* Part of PBX interface */ static int sip_answer(struct ast_channel *ast) { - int res = 0,fmt; + int res = 0, fmt; char *codec; struct sip_pvt *p = ast->tech_pvt; ast_mutex_lock(&p->lock); if (ast->_state != AST_STATE_UP) { -#ifdef OSP_SUPPORT +#ifdef OSP_SUPPORT time(&p->ospstart); #endif - - codec=pbx_builtin_getvar_helper(p->owner,"SIP_CODEC"); + + codec = pbx_builtin_getvar_helper(p->owner, "SIP_CODEC"); if (codec) { - fmt=ast_getformatbyname(codec); + fmt = ast_getformatbyname(codec); if (fmt) { - ast_log(LOG_NOTICE, "Changing codec to '%s' for this call because of ${SIP_CODEC) variable\n",codec); + ast_log(LOG_NOTICE, "Changing codec to '%s' for this call because of ${SIP_CODEC) variable\n", codec); if (p->jointcapability & fmt) { p->jointcapability &= fmt; p->capability &= fmt; } else ast_log(LOG_NOTICE, "Ignoring ${SIP_CODEC} variable because it is not shared by both ends.\n"); - } else ast_log(LOG_NOTICE, "Ignoring ${SIP_CODEC} variable because of unrecognized/not configured codec (check allow/disallow in sip.conf): %s\n",codec); + } else ast_log(LOG_NOTICE, "Ignoring ${SIP_CODEC} variable because of unrecognized/not configured codec (check allow/disallow in sip.conf): %s\n", codec); } ast_setstate(ast, AST_STATE_UP); @@ -2352,7 +2310,7 @@ /* If channel is not up, activate early media session */ if ((ast->_state != AST_STATE_UP) && !ast_test_flag(p, SIP_PROGRESS_SENT) && !ast_test_flag(p, SIP_OUTGOING)) { transmit_response_with_sdp(p, "183 Session Progress", &p->initreq, 0); - ast_set_flag(p, SIP_PROGRESS_SENT); + ast_set_flag(p, SIP_PROGRESS_SENT); } time(&p->lastrtptx); res = ast_rtp_write(p->rtp, frame); @@ -2367,7 +2325,7 @@ /* Activate video early media */ if ((ast->_state != AST_STATE_UP) && !ast_test_flag(p, SIP_PROGRESS_SENT) && !ast_test_flag(p, SIP_OUTGOING)) { transmit_response_with_sdp(p, "183 Session Progress", &p->initreq, 0); - ast_set_flag(p, SIP_PROGRESS_SENT); + ast_set_flag(p, SIP_PROGRESS_SENT); } time(&p->lastrtptx); res = ast_rtp_write(p->vrtp, frame); @@ -2378,11 +2336,10 @@ case AST_FRAME_IMAGE: return 0; break; - default: + default: ast_log(LOG_WARNING, "Can't send %d type frames with SIP write\n", frame->frametype); return 0; } - return res; } @@ -2425,9 +2382,6 @@ return res; } -#define DEFAULT_MAX_FORWARDS 70 - - /*--- sip_transfer: Transfer SIP call */ static int sip_transfer(struct ast_channel *ast, const char *dest) { @@ -2452,7 +2406,7 @@ int res = 0; ast_mutex_lock(&p->lock); - switch(condition) { + switch (condition) { case AST_CONTROL_RINGING: if (ast->_state == AST_STATE_RING) { if (!ast_test_flag(p, SIP_PROGRESS_SENT) || @@ -2471,7 +2425,7 @@ case AST_CONTROL_BUSY: if (ast->_state != AST_STATE_UP) { transmit_response(p, "486 Busy Here", &p->initreq); - ast_set_flag(p, SIP_ALREADYGONE); + ast_set_flag(p, SIP_ALREADYGONE); ast_softhangup_nolock(ast, AST_SOFTHANGUP_DEV); break; } @@ -2480,7 +2434,7 @@ case AST_CONTROL_CONGESTION: if (ast->_state != AST_STATE_UP) { transmit_response(p, "503 Service Unavailable", &p->initreq); - ast_set_flag(p, SIP_ALREADYGONE); + ast_set_flag(p, SIP_ALREADYGONE); ast_softhangup_nolock(ast, AST_SOFTHANGUP_DEV); break; } @@ -2490,25 +2444,22 @@ case AST_CONTROL_PROCEEDING: if ((ast->_state != AST_STATE_UP) && !ast_test_flag(p, SIP_PROGRESS_SENT) && !ast_test_flag(p, SIP_OUTGOING)) { transmit_response_with_sdp(p, "183 Session Progress", &p->initreq, 0); - ast_set_flag(p, SIP_PROGRESS_SENT); + ast_set_flag(p, SIP_PROGRESS_SENT); break; } res = -1; break; case AST_CONTROL_HOLD: /* We are put on hold */ - /* The PBX is providing us with onhold music, but - should we clear the RTP stream with the other - end? Guess we could do that if there's no - musiconhold class defined for this channel - */ + /* The PBX is providing us with onhold music, but should we clear the + * RTP stream with the other end? Guess we could do that if there's no + * musiconhold class defined for this channel.*/ if (sipdebug) ast_log(LOG_DEBUG, "SIP dialog on hold: %s\n", p->callid); res = -1; ast_set_flag(p, SIP_CALL_ONHOLD); break; case AST_CONTROL_UNHOLD: /* We are back from hold */ - /* Open RTP stream if we decide to close it - */ + /* Open RTP stream if we decide to close it */ if (sipdebug) ast_log(LOG_DEBUG, "SIP dialog off hold: %s\n", p->callid); res = -1; @@ -2526,16 +2477,14 @@ return res; } - - /*--- sip_new: Initiate a call in the SIP channel */ -/* called from sip_request_call (calls from the pbx ) */ +/* called from sip_request_call (calls from the pbx) */ static struct ast_channel *sip_new(struct sip_pvt *i, int state, char *title) { struct ast_channel *tmp; struct ast_variable *v = NULL; int fmt; - + ast_mutex_unlock(&i->lock); /* Don't hold a sip pvt lock while we allocate a channel */ tmp = ast_channel_alloc(1); @@ -2559,8 +2508,8 @@ if (title) snprintf(tmp->name, sizeof(tmp->name), "SIP/%s-%04x", title, rand() & 0xffff); - else if (strchr(i->fromdomain,':')) - snprintf(tmp->name, sizeof(tmp->name), "SIP/%s-%08x", strchr(i->fromdomain,':')+1, (int)(long)(i)); + else if (strchr(i->fromdomain, ':')) + snprintf(tmp->name, sizeof(tmp->name), "SIP/%s-%08x", strchr(i->fromdomain, ':')+1, (int)(long)(i)); else snprintf(tmp->name, sizeof(tmp->name), "SIP/%s-%08x", i->fromdomain, (int)(long)(i)); @@ -2603,14 +2552,18 @@ ast_mutex_unlock(&usecnt_lock); ast_copy_string(tmp->context, i->context, sizeof(tmp->context)); ast_copy_string(tmp->exten, i->exten, sizeof(tmp->exten)); - if (!ast_strlen_zero(i->cid_num)) + if (!ast_strlen_zero(i->cid_num)) { tmp->cid.cid_num = strdup(i->cid_num); - if (!ast_strlen_zero(i->cid_name)) + } + if (!ast_strlen_zero(i->cid_name)) { tmp->cid.cid_name = strdup(i->cid_name); - if (!ast_strlen_zero(i->rdnis)) + } + if (!ast_strlen_zero(i->rdnis)) { tmp->cid.cid_rdnis = strdup(i->rdnis); - if (!ast_strlen_zero(i->exten) && strcmp(i->exten, "s")) + } + if (!ast_strlen_zero(i->exten) && strcmp(i->exten, "s")) { tmp->cid.cid_dnid = strdup(i->exten); + } tmp->priority = 1; if (!ast_strlen_zero(i->uri)) { pbx_builtin_setvar_helper(tmp, "SIPURI", i->uri); @@ -2633,9 +2586,9 @@ } } /* Set channel variables for this call from configuration */ - for (v = i->chanvars ; v ; v = v->next) - pbx_builtin_setvar_helper(tmp,v->name,v->value); - + for (v = i->chanvars ; v ; v = v->next) { + pbx_builtin_setvar_helper(tmp, v->name, v->value); + } return tmp; } @@ -2650,13 +2603,13 @@ /*--- get_sdp: Gets all kind of SIP message bodies, including SDP, but the name wrongly applies _only_ sdp */ -static char *get_sdp(struct sip_request *req, char *name) +static char *get_sdp(struct sip_request *req, char *name) { int x; int len = strlen(name); char *r; - for (x=0; xlines; x++) { + for (x = 0; xlines; x++) { r = get_sdp_by_line(req->line[x], name, len); if (r[0] != '\0') return r; @@ -2664,14 +2617,12 @@ return ""; } - -static void sdpLineNum_iterator_init(int* iterator) +static void sdpLineNum_iterator_init(int* iterator) { *iterator = 0; } -static char* get_sdp_iterate(int* iterator, - struct sip_request *req, char *name) +static char* get_sdp_iterate(int* iterator, struct sip_request *req, char *name) { int len = strlen(name); char *r; @@ -2687,9 +2638,11 @@ static char *find_alias(const char *name, char *_default) { int x; - for (x=0;xheaders; x++) { + for (x = *start; xheaders; x++) { if (!strncasecmp(req->header[x], name, len)) { char *r = req->header[x] + len; /* skip name */ if (pedanticsipchecking) @@ -2741,7 +2692,7 @@ /* Retrieve audio/etc from channel. Assumes p->lock is already held. */ struct ast_frame *f; static struct ast_frame null_frame = { AST_FRAME_NULL, }; - switch(ast->fdno) { + switch (ast->fdno) { case 0: f = ast_rtp_read(p->rtp); /* RTP Audio */ break; @@ -2771,8 +2722,9 @@ } if ((ast_test_flag(p, SIP_DTMF) == SIP_DTMF_INBAND) && p->vad) { f = ast_dsp_process(p->owner, p->vad, f); - if (f && (f->frametype == AST_FRAME_DTMF)) + if (f && (f->frametype == AST_FRAME_DTMF)) { ast_log(LOG_DEBUG, "* Detected inband DTMF '%c'\n", f->subclass); + } } } } @@ -2798,7 +2750,7 @@ int val; int x; char iabuf[INET_ADDRSTRLEN]; - for (x=0; x<4; x++) { + for (x = 0; x<4; x++) { val = rand(); res = snprintf(callid, len, "%08x", val); len -= res; @@ -2830,16 +2782,16 @@ p->prefs = prefs; #ifdef OSP_SUPPORT p->osphandle = -1; -#endif +#endif if (sin) { memcpy(&p->sa, sin, sizeof(p->sa)); - if (ast_sip_ouraddrfor(&p->sa.sin_addr,&p->ourip)) + if (ast_sip_ouraddrfor(&p->sa.sin_addr, &p->ourip)) memcpy(&p->ourip, &__ourip, sizeof(p->ourip)); } else { memcpy(&p->ourip, &__ourip, sizeof(p->ourip)); } - p->branch = rand(); + p->branch = rand(); p->tag = rand(); /* Start with 101 instead of 1 */ p->ocseq = 101; @@ -2901,8 +2853,8 @@ return p; } -/*--- find_call: Connect incoming SIP message to current dialog or create new dialog structure */ -/* Called by handle_request ,sipsock_read */ +/*--- find_call: Connect incoming SIP message to current dialog or create new + * dialog structure. Called by handle_request ,sipsock_read */ static struct sip_pvt *find_call(struct sip_request *req, struct sockaddr_in *sin, const int intended_method) { struct sip_pvt *p; @@ -2913,12 +2865,11 @@ callid = get_header(req, "Call-ID"); if (pedanticsipchecking) { - /* In principle Call-ID's uniquely identify a call, but with a forking SIP proxy - we need more to identify a branch - so we have to check branch, from - and to tags to identify a call leg. - For Asterisk to behave correctly, you need to turn on pedanticsipchecking - in sip.conf - */ + /* In principle Call-ID's uniquely identify a call, but with a forking + * SIP proxy we need more to identify a branch - so we have to check + * branch, from and to tags to identify a call leg. For Asterisk to + * behave correctly, you need to turn on pedanticsipcheckingin sip.conf + */ if (req->method == SIP_RESPONSE) ast_copy_string(tmp, get_header(req, "To"), sizeof(tmp)); else @@ -2930,18 +2881,18 @@ if (c) *c = '\0'; } - } - + ast_mutex_lock(&iflock); p = iflist; - while(p) { + while (p) { int found = 0; - if (req->method == SIP_REGISTER) + if (req->method == SIP_REGISTER) { found = (!strcmp(p->callid, callid)); - else - found = (!strcmp(p->callid, callid) && - (!pedanticsipchecking || !tag || ast_strlen_zero(p->theirtag) || !strcmp(p->theirtag, tag))) ; + } else { + found = (!strcmp(p->callid, callid) && + (!pedanticsipchecking || !tag || ast_strlen_zero(p->theirtag) || !strcmp(p->theirtag, tag))); + } if (found) { /* Found the call */ ast_mutex_lock(&p->lock); @@ -2962,15 +2913,15 @@ { struct sip_registry *reg; char copy[256] = ""; - char *username=NULL, *hostname=NULL, *secret=NULL, *authuser=NULL; - char *porta=NULL; - char *contact=NULL; - char *stringp=NULL; - + char *username = NULL, *hostname = NULL, *secret = NULL, *authuser = NULL; + char *porta = NULL; + char *contact = NULL; + char *stringp = NULL; + if (!value) return -1; ast_copy_string(copy, value, sizeof(copy)); - stringp=copy; + stringp = copy; username = stringp; hostname = strrchr(stringp, '@'); if (hostname) { @@ -2981,23 +2932,26 @@ ast_log(LOG_WARNING, "Format for registration is user[:secret[:authuser]]@host[:port][/contact] at line %d\n", lineno); return -1; } - stringp=username; + stringp = username; username = strsep(&stringp, ":"); if (username) { secret = strsep(&stringp, ":"); - if (secret) + if (secret) { authuser = strsep(&stringp, ":"); + } } stringp = hostname; hostname = strsep(&stringp, "/"); - if (hostname) + if (hostname) { contact = strsep(&stringp, "/"); - if (!contact || ast_strlen_zero(contact)) + } + if (!contact || ast_strlen_zero(contact)) { contact = "s"; - stringp=hostname; + } + stringp = hostname; hostname = strsep(&stringp, ":"); porta = strsep(&stringp, ":"); - + if (porta && !atoi(porta)) { ast_log(LOG_WARNING, "%s is not a valid port number at line %d\n", porta, lineno); return -1; @@ -3026,54 +2980,56 @@ reg->callid_valid = 0; reg->ocseq = 101; ASTOBJ_CONTAINER_LINK(®l, reg); - ASTOBJ_UNREF(reg,sip_registry_destroy); + ASTOBJ_UNREF(reg, sip_registry_destroy); return 0; } /*--- lws2sws: Parse multiline SIP headers into one header */ /* This is enabled if pedanticsipchecking is enabled */ -static int lws2sws(char *msgbuf, int len) -{ - int h = 0, t = 0; - int lws = 0; - - for (; h < len;) { - /* Eliminate all CRs */ - if (msgbuf[h] == '\r') { - h++; - continue; - } - /* Check for end-of-line */ - if (msgbuf[h] == '\n') { - /* Check for end-of-message */ - if (h + 1 == len) - break; - /* Check for a continuation line */ - if (msgbuf[h + 1] == ' ' || msgbuf[h + 1] == '\t') { - /* Merge continuation line */ - h++; - continue; - } - /* Propagate LF and start new line */ - msgbuf[t++] = msgbuf[h++]; +static int lws2sws(char *msgbuf, int len) +{ + int h = 0, t = 0; + int lws = 0; + + for (; h < len;) { + /* Eliminate all CRs */ + if (msgbuf[h] == '\r') { + h++; + continue; + } + /* Check for end-of-line */ + if (msgbuf[h] == '\n') { + /* Check for end-of-message */ + if (h + 1 == len) { + break; + } + /* Check for a continuation line */ + if (msgbuf[h + 1] == ' ' || msgbuf[h + 1] == '\t') { + /* Merge continuation line */ + h++; + continue; + } + /* Propagate LF and start new line */ + msgbuf[t++] = msgbuf[h++]; + lws = 0; + continue; + } + if (msgbuf[h] == ' ' || msgbuf[h] == '\t') { + if (lws) { + h++; + continue; + } + msgbuf[t++] = msgbuf[h++]; + lws = 1; + continue; + } + msgbuf[t++] = msgbuf[h++]; + if (lws) { lws = 0; - continue; - } - if (msgbuf[h] == ' ' || msgbuf[h] == '\t') { - if (lws) { - h++; - continue; - } - msgbuf[t++] = msgbuf[h++]; - lws = 1; - continue; - } - msgbuf[t++] = msgbuf[h++]; - if (lws) - lws = 0; - } - msgbuf[t] = '\0'; - return t; + } + } + msgbuf[t] = '\0'; + return t; } /*--- parse_request: Parse a SIP message ----*/ @@ -3087,7 +3043,7 @@ /* First header starts immediately */ req->header[f] = c; - while(*c) { + while (*c) { if (*c == '\n') { /* We've got a new header */ *c = 0; @@ -3111,13 +3067,14 @@ c++; } /* Check for last header */ - if (!ast_strlen_zero(req->header[f])) + if (!ast_strlen_zero(req->header[f])) { f++; + } req->headers = f; /* Now we process any mime content */ f = 0; req->line[f] = c; - while(*c) { + while (*c) { if (*c == '\n') { /* We've got a new line */ *c = 0; @@ -3135,11 +3092,13 @@ c++; } /* Check for last line */ - if (!ast_strlen_zero(req->line[f])) + if (!ast_strlen_zero(req->line[f])) { f++; + } req->lines = f; - if (*c) + if (*c) { ast_log(LOG_WARNING, "Odd content, extra stuff left over ('%s')\n", c); + } /* Split up the first line parts */ determine_firstline_parts(req); } @@ -3156,7 +3115,7 @@ int portno = -1; int vportno = -1; int peercapability, peernoncodeccapability; - int vpeercapability=0, vpeernoncodeccapability=0; + int vpeercapability = 0, vpeernoncodeccapability = 0; struct sockaddr_in sin; char *codecs; struct hostent *hp; @@ -3165,8 +3124,8 @@ int destiterator = 0; int iterator; int sendonly = 0; - int x,y; - int debug=sip_debug_test_pvt(p); + int x, y; + int debug = sip_debug_test_pvt(p); struct ast_channel *bridgepeer = NULL; /* Update our last rtprx when we receive an SDP, too */ @@ -3196,7 +3155,7 @@ return -1; } sdpLineNum_iterator_init(&iterator); - ast_set_flag(p, SIP_NOVIDEO); + ast_set_flag(p, SIP_NOVIDEO); while ((m = get_sdp_iterate(&iterator, req, "m"))[0] != '\0') { int found = 0; if ((sscanf(m, "audio %d RTP/AVP %n", &x, &len) == 1) || @@ -3206,7 +3165,7 @@ /* Scan through the RTP payload types specified in a "m=" line: */ ast_rtp_pt_clear(p->rtp); codecs = m + len; - while(!ast_strlen_zero(codecs)) { + while (!ast_strlen_zero(codecs)) { if (sscanf(codecs, "%d%n", &codec, &len) != 1) { ast_log(LOG_WARNING, "Error in codec string '%s'\n", codecs); return -1; @@ -3222,11 +3181,11 @@ if (p->vrtp && (sscanf(m, "video %d RTP/AVP %n", &x, &len) == 1)) { found = 1; - ast_clear_flag(p, SIP_NOVIDEO); + ast_clear_flag(p, SIP_NOVIDEO); vportno = x; /* Scan through the RTP payload types specified in a "m=" line: */ codecs = m + len; - while(!ast_strlen_zero(codecs)) { + while (!ast_strlen_zero(codecs)) { if (sscanf(codecs, "%d%n", &codec, &len) != 1) { ast_log(LOG_WARNING, "Error in codec string '%s'\n", codecs); return -1; @@ -3237,7 +3196,7 @@ codecs = ast_skip_blanks(codecs + len); } } - if (!found ) + if (!found) ast_log(LOG_WARNING, "Unknown SDP media type in offer: %s\n", m); } if (portno == -1 && vportno == -1) { @@ -3268,8 +3227,8 @@ if (p->rtp && sin.sin_port) { ast_rtp_set_peer(p->rtp, &sin); if (debug) { - ast_verbose("Peer audio RTP is at port %s:%d\n", ast_inet_ntoa(iabuf,sizeof(iabuf), sin.sin_addr), ntohs(sin.sin_port)); - 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)); + ast_verbose("Peer audio RTP is at port %s:%d\n", ast_inet_ntoa(iabuf, sizeof(iabuf), sin.sin_addr), ntohs(sin.sin_port)); + 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)); } } /* Check for Media-description-level-address for video */ @@ -3292,8 +3251,8 @@ if (p->vrtp && sin.sin_port) { ast_rtp_set_peer(p->vrtp, &sin); if (debug) { - ast_verbose("Peer video RTP is at port %s:%d\n", ast_inet_ntoa(iabuf,sizeof(iabuf), sin.sin_addr), ntohs(sin.sin_port)); - 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)); + ast_verbose("Peer video RTP is at port %s:%d\n", ast_inet_ntoa(iabuf, sizeof(iabuf), sin.sin_addr), ntohs(sin.sin_port)); + 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)); } } @@ -3304,11 +3263,11 @@ while ((a = get_sdp_iterate(&iterator, req, "a"))[0] != '\0') { char* mimeSubtype = ast_strdupa(a); /* ensures we have enough space */ if (!strcasecmp(a, "sendonly")) { - sendonly=1; + sendonly = 1; continue; } if (!strcasecmp(a, "sendrecv")) { - sendonly=0; + sendonly = 0; } if (sscanf(a, "rtpmap: %u %[^/]/", &codec, mimeSubtype) != 2) continue; if (debug) @@ -3328,10 +3287,10 @@ p->jointcapability = p->capability & (peercapability | vpeercapability); p->peercapability = (peercapability | vpeercapability); p->noncodeccapability = noncodeccapability & peernoncodeccapability; - + if (debug) { /* shame on whoever coded this.... */ - const unsigned slen=512; + const unsigned slen = 512; char s1[slen], s2[slen], s3[slen], s4[slen]; ast_verbose("Capabilities: us - %s, peer - audio=%s/video=%s, combined - %s\n", @@ -3350,20 +3309,21 @@ return -1; } - if (!p->owner) /* There's no open channel owning us */ + if (!p->owner) { /* There's no open channel owning us */ return 0; + } if (!(p->owner->nativeformats & p->jointcapability)) { - const unsigned slen=512; + const unsigned slen = 512; char s1[slen], s2[slen]; - ast_log(LOG_DEBUG, "Oooh, we need to change our formats since our peer supports only %s and not %s\n", - ast_getformatname_multiple(s1, slen, p->jointcapability), - ast_getformatname_multiple(s2, slen, p->owner->nativeformats)); + ast_log(LOG_DEBUG, "Oooh, we need to change our formats since our peer supports only %s and not %s\n", + ast_getformatname_multiple(s1, slen, p->jointcapability), + ast_getformatname_multiple(s2, slen, p->owner->nativeformats)); p->owner->nativeformats = ast_codec_choose(&p->prefs, p->jointcapability, 1); ast_set_read_format(p->owner, p->owner->readformat); ast_set_write_format(p->owner, p->owner->writeformat); } - if ((bridgepeer=ast_bridged_channel(p->owner))) { + if ((bridgepeer = ast_bridged_channel(p->owner))) { /* We have a bridge */ /* Turn on/off music on hold if we are holding/unholding */ if (sin.sin_addr.s_addr && !sendonly) { @@ -3373,34 +3333,28 @@ append_history(p, "Unhold", req->data); if (callevents && ast_test_flag(p, SIP_CALL_ONHOLD)) { manager_event(EVENT_FLAG_CALL, "Unhold", - "Channel: %s\r\n" - "Uniqueid: %s\r\n", - p->owner->name, - p->owner->uniqueid); + "Channel: %s\r\n" + "Uniqueid: %s\r\n", + p->owner->name, + p->owner->uniqueid); } ast_clear_flag(p, SIP_CALL_ONHOLD); /* Somehow, we need to check if we need to re-invite here */ - /* If this call had a external native bridge, it's broken - now and we need to start all over again. - The bridged peer, if SIP, now listens - to RTP from Asterisk instead of from - the peer - - So IF we had a native bridge before - the HOLD, we need to somehow re-invite - into a NATIVE bridge afterwards... - - */ - + /* If this call had a external native bridge, it's broken now and we + * need to start all over again. The bridged peer, if SIP, now + * listens to RTP from Asterisk instead of from the peer + * So IF we had a native bridge before the HOLD, we need to somehow + * re-invite into a NATIVE bridge afterwards... + */ } else { /* No address for RTP, we're on hold */ append_history(p, "Hold", req->data); if (callevents && !ast_test_flag(p, SIP_CALL_ONHOLD)) { manager_event(EVENT_FLAG_CALL, "Hold", - "Channel: %s\r\n" - "Uniqueid: %s\r\n", - p->owner->name, - p->owner->uniqueid); + "Channel: %s\r\n" + "Uniqueid: %s\r\n", + p->owner->name, + p->owner->uniqueid); } ast_set_flag(p, SIP_CALL_ONHOLD); /* Indicate HOLD status to the other channel */ @@ -3445,7 +3399,7 @@ req->len += strlen(req->header[req->headers]); req->headers++; - return 0; + return 0; } /*--- add_header_contentLen: Add 'Content-Length' header to SIP message */ @@ -3476,7 +3430,7 @@ snprintf(req->header[req->headers], sizeof(req->data) - req->len, "\r\n"); req->len += strlen(req->header[req->headers]); req->headers++; - return 0; + return 0; } /*--- add_line: Add content (not header) to SIP message */ @@ -3499,7 +3453,7 @@ snprintf(req->line[req->lines], sizeof(req->data) - req->len, "%s", line); req->len += strlen(req->line[req->lines]); req->lines++; - return 0; + return 0; } /*--- copy_header: Copy one header field from one request to another */ @@ -3536,7 +3490,7 @@ /*--- copy_via_headers: Copy SIP VIA Headers from one request to another ---*/ static int copy_via_headers(struct sip_pvt *p, struct sip_request *req, struct sip_request *orig, char *field) { - char tmp[256]="", *oh, *end; + char tmp[256] = "", *oh, *end; int start = 0; int copied = 0; char new[256]; @@ -3555,9 +3509,9 @@ *oh = '\0'; } if (!copied && (ast_test_flag(p, SIP_NAT) == SIP_NAT_ALWAYS)) { - /* Whoo hoo! Now we can indicate port address translation too! Just - another RFC (RFC3581). I'll leave the original comments in for - posterity. */ + /* Whoo hoo! Now we can indicate port address translation too! + * Just another RFC (RFC3581). I'll leave the original comments + * in for posterity. */ 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)); add_header(req, field, new); } else { @@ -3609,7 +3563,7 @@ int port, hn; struct hostent *hp; struct ast_hostent ahp; - int debug=sip_debug_test_pvt(p); + int debug = sip_debug_test_pvt(p); /* Parse uri to h (host) and port - uri is already just the part inside the <> */ /* general form we are expecting is sip[s]:username[:password]@host[:port][;...] */ @@ -3650,7 +3604,7 @@ if (hn > sizeof(hostname)) hn = sizeof(hostname); ast_copy_string(hostname, maddr, hn); } - + hp = ast_gethostbyname(hostname, &ahp); if (hp == NULL) { ast_log(LOG_WARNING, "Can't find address for host '%s'\n", hostname); @@ -3695,7 +3649,6 @@ return 0; } - /*--- respprep: Prepare SIP response packet ---*/ static int respprep(struct sip_request *resp, struct sip_pvt *p, char *msg, struct sip_request *req) { @@ -3709,8 +3662,8 @@ copy_header(resp, req, "From"); ot = get_header(req, "To"); if (!strcasestr(ot, "tag=") && strncmp(msg, "100", 3)) { - /* Add the proper tag if we don't have it already. If they have specified - their tag, use it. Otherwise, use our own tag */ + /* Add the proper tag if we don't have it already. If they have + * specified their tag, use it. Otherwise, use our own tag */ if (!ast_strlen_zero(p->theirtag) && ast_test_flag(p, SIP_OUTGOING)) snprintf(newto, sizeof(newto), "%s;tag=%s", ot, p->theirtag); else if (p->tag && !ast_test_flag(p, SIP_OUTGOING)) @@ -3727,8 +3680,7 @@ add_header(resp, "User-Agent", default_useragent); add_header(resp, "Allow", ALLOWED_METHODS); if (p->expiry) { - /* For registration responses, we also need expiry and - contact info */ + /* For registration responses, we also need expiry and contact info */ char contact[256]; char tmp[256]; @@ -3751,21 +3703,21 @@ static int reqprep(struct sip_request *req, struct sip_pvt *p, int sipmethod, int seqno, int newbranch) { struct sip_request *orig = &p->initreq; - char stripped[80] =""; + char stripped[80] = ""; char tmp[80]; char newto[256]; char *c, *n; char *ot, *of; memset(req, 0, sizeof(struct sip_request)); - + snprintf(p->lastmsg, sizeof(p->lastmsg), "Tx: %s", sip_methods[sipmethod].text); - + if (!seqno) { p->ocseq++; seqno = p->ocseq; } - + if (newbranch) { p->branch ^= rand(); build_via(p, p->via, sizeof(p->via)); @@ -3773,8 +3725,8 @@ if (sipmethod == SIP_CANCEL) { c = p->initreq.rlPart2; /* Use original URI */ } else if (sipmethod == SIP_ACK) { - /* Use URI from Contact: in 200 OK (if INVITE) - (we only have the contacturi on INVITEs) */ + /* Use URI from Contact: in 200 OK (if INVITE) + * (we only have the contacturi on INVITEs) */ if (!ast_strlen_zero(p->okcontacturi)) c = p->okcontacturi; else @@ -3791,7 +3743,7 @@ n = strchr(c, ';'); if (n) *n = '\0'; - } + } init_req(req, sipmethod, c); snprintf(tmp, sizeof(tmp), "%d %s", seqno, sip_methods[sipmethod].text); @@ -3805,11 +3757,12 @@ ot = get_header(orig, "To"); of = get_header(orig, "From"); - /* Add tag *unless* this is a CANCEL, in which case we need to send it exactly - as our original request, including tag (or presumably lack thereof) */ + /* Add tag *unless* this is a CANCEL, in which case we need to send it + * exactly as our original request, including tag (or presumably lack + * thereof) */ if (!strcasestr(ot, "tag=") && sipmethod != SIP_CANCEL) { - /* Add the proper tag if we don't have it already. If they have specified - their tag, use it. Otherwise, use our own tag */ + /* Add the proper tag if we don't have it already. If they have + * specified their tag, use it. Otherwise, use our own tag */ if (ast_test_flag(p, SIP_OUTGOING) && !ast_strlen_zero(p->theirtag)) snprintf(newto, sizeof(newto), "%s;tag=%s", ot, p->theirtag); else if (!ast_test_flag(p, SIP_OUTGOING)) @@ -3855,13 +3808,13 @@ } /*--- transmit_response: Transmit response, no retransmits */ -static int transmit_response(struct sip_pvt *p, char *msg, struct sip_request *req) +static int transmit_response(struct sip_pvt *p, char *msg, struct sip_request *req) { return __transmit_response(p, msg, req, 0); } /*--- transmit_response_with_unsupported: Transmit response, no retransmits */ -static int transmit_response_with_unsupported(struct sip_pvt *p, char *msg, struct sip_request *req, char *unsupported) +static int transmit_response_with_unsupported(struct sip_pvt *p, char *msg, struct sip_request *req, char *unsupported) { struct sip_request resp; respprep(&resp, p, msg, req); @@ -3922,8 +3875,8 @@ ast_log(LOG_WARNING, "Unable to determine sequence number from '%s'\n", get_header(req, "CSeq")); return -1; } - /* Stale means that they sent us correct authentication, but - based it on an old challenge (nonce) */ + /* Stale means that they sent us correct authentication, but + * based it on an old challenge (nonce) */ snprintf(tmp, sizeof(tmp), "Digest realm=\"%s\", nonce=\"%s\" %s", global_realm, randdata, stale ? ", stale=true" : ""); respprep(&resp, p, msg, req); add_header(&resp, header, tmp); @@ -3979,19 +3932,17 @@ int capability = 0 ; struct sockaddr_in dest; struct sockaddr_in vdest = { 0, }; - int debug=0; - - debug = sip_debug_test_pvt(p); + int debug = sip_debug_test_pvt(p); /* XXX We break with the "recommendation" and send our IP, in order that our - peer doesn't have to ast_gethostbyname() us XXX */ + * peer doesn't have to ast_gethostbyname() us XXX */ len = 0; if (!p->rtp) { ast_log(LOG_WARNING, "No way to add SDP without an RTP structure\n"); return -1; } capability = p->capability; - + if (!p->sessionid) { p->sessionid = getpid(); p->sessionversion = p->sessionid; @@ -4022,9 +3973,9 @@ } } if (debug){ - ast_verbose("We're at %s port %d\n", ast_inet_ntoa(iabuf, sizeof(iabuf), p->ourip), ntohs(sin.sin_port)); + ast_verbose("We're at %s port %d\n", ast_inet_ntoa(iabuf, sizeof(iabuf), p->ourip), ntohs(sin.sin_port)); if (p->vrtp) - ast_verbose("Video is at %s port %d\n", ast_inet_ntoa(iabuf, sizeof(iabuf), p->ourip), ntohs(vsin.sin_port)); + ast_verbose("Video is at %s port %d\n", ast_inet_ntoa(iabuf, sizeof(iabuf), p->ourip), ntohs(vsin.sin_port)); } snprintf(v, sizeof(v), "v=0\r\n"); 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)); @@ -4054,8 +4005,8 @@ } /* Start by sending our preferred codecs */ for (x = 0 ; x < 32 ; x++) { - if (!(pref_codec = ast_codec_pref_index(&p->prefs,x))) - break; + if (!(pref_codec = ast_codec_pref_index(&p->prefs, x))) + break; if ((capability & pref_codec) && !(alreadysent & pref_codec)) { if (debug) ast_verbose("Answering with preferred capability 0x%x (%s)\n", pref_codec, ast_getformatname(pref_codec)); @@ -4107,10 +4058,9 @@ snprintf(costr, sizeof(costr), "a=rtpmap:%d %s/8000\r\n", codec, ast_rtp_lookup_mime_subtype(0, x)); strncat(a, costr, sizeof(a) - strlen(a) - 1); if (x == AST_RTP_DTMF) { - /* Indicate we support DTMF and FLASH... */ - snprintf(costr, sizeof costr, "a=fmtp:%d 0-16\r\n", - codec); - strncat(a, costr, sizeof(a) - strlen(a) - 1); + /* Indicate we support DTMF and FLASH... */ + snprintf(costr, sizeof costr, "a=fmtp:%d 0-16\r\n", codec); + strncat(a, costr, sizeof(a) - strlen(a) - 1); } } } @@ -4153,10 +4103,12 @@ /* First copy stuff */ memcpy(dst, src, sizeof(*dst)); /* Now fix pointer arithmetic */ - for (x=0; x < src->headers; x++) + for (x = 0; x < src->headers; x++) { dst->header[x] += offset; - for (x=0; x < src->lines; x++) + } + for (x = 0; x < src->lines; x++) { dst->line[x] += offset; + } } /*--- transmit_response_with_sdp: Used for 200 OK and 183 early media ---*/ @@ -4175,11 +4127,11 @@ } /*--- determine_firstline_parts: parse first line of incoming SIP request */ -static int determine_firstline_parts( struct sip_request *req ) +static int determine_firstline_parts(struct sip_request *req) { char *e, *cmd; int len; - + cmd = ast_skip_blanks(req->header[0]); if (!*cmd) return -1; @@ -4189,32 +4141,33 @@ if (*e) *e++ = '\0'; e = ast_skip_blanks(e); - if ( !*e ) + if (!*e) { return -1; + } - if ( !strcasecmp(cmd, "SIP/2.0") ) { + if (!strcasecmp(cmd, "SIP/2.0")) { /* We have a response */ req->rlPart2 = e; - len = strlen( req->rlPart2 ); - if ( len < 2 ) { + len = strlen(req->rlPart2); + if (len < 2) { return -1; } ast_trim_blanks(e); } else { /* We have a request */ - if ( *e == '<' ) { + if (*e == '<') { e++; - if ( !*e ) { - return -1; - } + if (!*e) { + return -1; + } } req->rlPart2 = e; /* URI */ - if ( ( e= strrchr( req->rlPart2, 'S' ) ) == NULL ) { + if ((e= strrchr(req->rlPart2, 'S')) == NULL) { return -1; } /* XXX maybe trim_blanks() ? */ - while( isspace( *(--e) ) ) {} - if ( *e == '>' ) { + while (isspace(*(--e))) {} + if (*e == '>') { *e = '\0'; } else { *(++e)= '\0'; @@ -4224,19 +4177,19 @@ } /*--- transmit_reinvite_with_sdp: Transmit reinvite with SDP :-) ---*/ -/* A re-invite is basically a new INVITE with the same CALL-ID and TAG as the - INVITE that opened the SIP dialogue - We reinvite so that the audio stream (RTP) go directly between - the SIP UAs. SIP Signalling stays with * in the path. -*/ +/* A re-invite is basically a new INVITE with the same CALL-ID and TAG as the + * INVITE that opened the SIP dialogue + * We reinvite so that the audio stream (RTP) go directly between + * the SIP UAs. SIP Signalling stays with * in the path. + */ static int transmit_reinvite_with_sdp(struct sip_pvt *p) { struct sip_request req; - if (ast_test_flag(p, SIP_REINVITE_UPDATE)) + if (ast_test_flag(p, SIP_REINVITE_UPDATE)) { reqprep(&req, p, SIP_UPDATE, 0, 1); - else + } else { reqprep(&req, p, SIP_INVITE, 0, 1); - + } add_header(&req, "Allow", ALLOWED_METHODS); ast_rtp_offered_from_local(p->rtp, 1); add_sdp(&req, p); @@ -4253,7 +4206,7 @@ /*--- extract_uri: Check Contact: URI of SIP message ---*/ static void extract_uri(struct sip_pvt *p, struct sip_request *req) { - char stripped[256]=""; + char stripped[256] = ""; char *c, *n; ast_copy_string(stripped, get_header(req, "Contact"), sizeof(stripped)); c = get_in_brackets(stripped); @@ -4279,71 +4232,73 @@ /*--- initreqprep: Initiate SIP request to peer/user ---*/ static void initreqprep(struct sip_request *req, struct sip_pvt *p, int sipmethod, char *vxml_url) { - char invite[256]=""; + char invite[256] = ""; char from[256]; char to[256]; char tmp[80]; char iabuf[INET_ADDRSTRLEN]; - char *l = default_callerid, *n=NULL; + char *l = default_callerid, *n = NULL; int x; - char urioptions[256]=""; + char urioptions[256] = ""; if (ast_test_flag(p, SIP_USEREQPHONE)) { - char onlydigits = 1; - x=0; - + char onlydigits = 1; + x = 0; /* Test p->username against allowed characters in AST_DIGIT_ANY - If it matches the allowed characters list, then sipuser = ";user=phone" - If not, then sipuser = "" - */ - /* + is allowed in first position in a tel: uri */ - if (p->username && p->username[0] == '+') - x=1; + * If it matches the allowed characters list, then sipuser = ";user=phone" + * If not, then sipuser = "" + * + is allowed in first position in a tel: uri */ + if (p->username && p->username[0] == '+') + x = 1; - for (; xusername); x++) { + for ( ; x < strlen(p->username); x++) { if (!strchr(AST_DIGIT_ANYNUM, p->username[x])) { - onlydigits = 0; + onlydigits = 0; break; } - } + } /* If we have only digits, add ;user=phone to the uri */ - if (onlydigits) + if (onlydigits) { strcpy(urioptions, ";user=phone"); + } } - snprintf(p->lastmsg, sizeof(p->lastmsg), "Init: %s", sip_methods[sipmethod].text); if (p->owner) { l = p->owner->cid.cid_num; n = p->owner->cid.cid_name; } - if (!l || (!ast_isphonenumber(l) && default_callerid[0])) - l = default_callerid; + if (!l || (!ast_isphonenumber(l) && default_callerid[0])) { + l = default_callerid; + } /* if user want's his callerid restricted */ if ((p->callingpres & AST_PRES_RESTRICTION) != AST_PRES_ALLOWED) { l = CALLERID_UNKNOWN; n = l; } - if (!n || ast_strlen_zero(n)) + if (!n || ast_strlen_zero(n)) { n = l; + } /* Allow user to be overridden */ - if (!ast_strlen_zero(p->fromuser)) + if (!ast_strlen_zero(p->fromuser)) { l = p->fromuser; - else /* Save for any further attempts */ + } else { /* Save for any further attempts */ ast_copy_string(p->fromuser, l, sizeof(p->fromuser)); - + } /* Allow user to be overridden */ - if (!ast_strlen_zero(p->fromname)) + if (!ast_strlen_zero(p->fromname)) { n = p->fromname; - else /* Save for any further attempts */ + } else { /* Save for any further attempts */ ast_copy_string(p->fromname, n, sizeof(p->fromname)); + } - if ((ourport != 5060) && ast_strlen_zero(p->fromdomain)) /* Needs to be 5060 */ + if ((ourport != 5060) && ast_strlen_zero(p->fromdomain)) { /* Needs to be 5060 */ snprintf(from, sizeof(from), "\"%s\" ;tag=as%08x", n, l, ast_strlen_zero(p->fromdomain) ? ast_inet_ntoa(iabuf, sizeof(iabuf), p->ourip) : p->fromdomain, ourport, p->tag); - else + } else { snprintf(from, sizeof(from), "\"%s\" ;tag=as%08x", n, l, ast_strlen_zero(p->fromdomain) ? ast_inet_ntoa(iabuf, sizeof(iabuf), p->ourip) : p->fromdomain, p->tag); + } /* If we're calling a registred SIP peer, use the fullcontact to dial to the peer */ if (!ast_strlen_zero(p->fullcontact)) { @@ -4351,10 +4306,10 @@ ast_copy_string(invite, p->fullcontact, sizeof(invite)); /* Otherwise, use the username while waiting for registration */ } else if (!ast_strlen_zero(p->username)) { - if (ntohs(p->sa.sin_port) != 5060) { /* Needs to be 5060 */ - snprintf(invite, sizeof(invite), "sip:%s@%s:%d%s",p->username, p->tohost, ntohs(p->sa.sin_port), urioptions); + if (ntohs(p->sa.sin_port) != 5060) { /* Needs to be 5060 */ + snprintf(invite, sizeof(invite), "sip:%s@%s:%d%s", p->username, p->tohost, ntohs(p->sa.sin_port), urioptions); } else { - snprintf(invite, sizeof(invite), "sip:%s@%s%s",p->username, p->tohost, urioptions); + snprintf(invite, sizeof(invite), "sip:%s@%s%s", p->username, p->tohost, urioptions); } } else if (ntohs(p->sa.sin_port) != 5060) { /* Needs to be 5060 */ snprintf(invite, sizeof(invite), "sip:%s:%d%s", p->tohost, ntohs(p->sa.sin_port), urioptions); @@ -4363,8 +4318,7 @@ } ast_copy_string(p->uri, invite, sizeof(p->uri)); /* If there is a VXML URL append it to the SIP URL */ - if (vxml_url) - { + if (vxml_url) { snprintf(to, sizeof(to), "<%s>;%s", invite, vxml_url); } else { snprintf(to, sizeof(to), "<%s>", invite); @@ -4390,16 +4344,16 @@ static int transmit_invite(struct sip_pvt *p, int sipmethod, int sdp, struct sip_invite_param *options, int init) { struct sip_request req; - + req.method = sipmethod; if (init) { /* Bump branch even on initial requests */ p->branch ^= rand(); build_via(p, p->via, sizeof(p->via)); initreqprep(&req, p, sipmethod, options ? options->vxml_url : (char *) NULL); - } else + } else { reqprep(&req, p, sipmethod, 0, 1); - + } if (options && options->auth) add_header(&req, options->authheader, options->auth); append_date(&req); @@ -4411,10 +4365,10 @@ } #ifdef OSP_SUPPORT if (options && options->osptoken && !ast_strlen_zero(options->osptoken)) { - ast_log(LOG_DEBUG,"Adding OSP Token: %s\n", options->osptoken); + ast_log(LOG_DEBUG, "Adding OSP Token: %s\n", options->osptoken); add_header(&req, "P-OSP-Auth-Token", options->osptoken); } else { - ast_log(LOG_DEBUG,"NOT Adding OSP Token\n"); + ast_log(LOG_DEBUG, "NOT Adding OSP Token\n"); } #endif if (options && options->distinctive_ring && !ast_strlen_zero(options->distinctive_ring)) @@ -4432,28 +4386,30 @@ ast = p->owner; /* The owner channel */ if (ast) { - headp=&ast->varshead; - if (!headp) - ast_log(LOG_WARNING,"No Headp for the channel...ooops!\n"); - else { - AST_LIST_TRAVERSE(headp,current,entries) { - /* SIPADDHEADER: Add SIP header to outgoing call */ - if (!strncasecmp(ast_var_name(current),"SIPADDHEADER",strlen("SIPADDHEADER"))) { + headp = &ast->varshead; + if (!headp) { + ast_log(LOG_WARNING, "No Headp for the channel...ooops!\n"); + } else { + AST_LIST_TRAVERSE(headp, current, entries) { + /* SIPADDHEADER: Add SIP header to outgoing call */ + if (!strncasecmp(ast_var_name(current), "SIPADDHEADER", strlen("SIPADDHEADER"))) { header = ast_var_value(current); /* Strip of the starting " (if it's there) */ - if (*header == '"') - header++; + if (*header == '"') { + header++; + } if ((content = strchr(header, ':'))) { *content = '\0'; content++; /* Move pointer ahead */ /* Skip white space */ - while (*content == ' ') - content++; + while (*content == ' ') { + content++; + } /* Strip the ending " (if it's there) */ - end = content + strlen(content) -1; - if (*end == '"') + end = content + strlen(content) -1; + if (*end == '"') { *end = '\0'; - + } add_header(&req, header, content); if (sipdebug) ast_log(LOG_DEBUG, "Adding SIP Header \"%s\" with content :%s: \n", header, content); @@ -4523,9 +4479,9 @@ add_header(&req, "Subscription-State", "active"); add_header(&req, "Content-Type", "application/xpidf+xml"); - if ((state==AST_EXTENSION_UNAVAILABLE) || (state==AST_EXTENSION_BUSY)) + if ((state == AST_EXTENSION_UNAVAILABLE) || (state == AST_EXTENSION_BUSY)) state = 2; - else if (state==AST_EXTENSION_INUSE) + else if (state == AST_EXTENSION_INUSE) state = 1; else state = 0; @@ -4536,8 +4492,8 @@ ast_build_string(&t, &maxbytes, "\n", mfrom); ast_build_string(&t, &maxbytes, "\n", p->exten); ast_build_string(&t, &maxbytes, "
\n", mto); - ast_build_string(&t, &maxbytes, "\n", !state ? "open" : (state==1) ? "inuse" : "closed"); - ast_build_string(&t, &maxbytes, "\n", !state ? "online" : (state==1) ? "onthephone" : "offline"); + ast_build_string(&t, &maxbytes, "\n", !state ? "open" : (state == 1) ? "inuse" : "closed"); + ast_build_string(&t, &maxbytes, "\n", !state ? "online" : (state == 1) ? "onthephone" : "offline"); ast_build_string(&t, &maxbytes, "
\n
\n\n"); } else { add_header(&req, "Event", "dialog"); @@ -4546,7 +4502,7 @@ ast_build_string(&t, &maxbytes, "\n", p->dialogver++, full ? "full":"partial", mfrom); ast_build_string(&t, &maxbytes, "\n", p->exten); ast_build_string(&t, &maxbytes, "%s\n", state ? "confirmed" : "terminated"); - ast_build_string(&t, &maxbytes, "\n\n"); + ast_build_string(&t, &maxbytes, "\n\n"); } if (t > tmp + sizeof(tmp)) ast_log(LOG_WARNING, "Buffer overflow detected!! (Please file a bug report)\n"); @@ -4595,7 +4551,7 @@ } /*--- transmit_sip_request: Transmit SIP request */ -static int transmit_sip_request(struct sip_pvt *p,struct sip_request *req) +static int transmit_sip_request(struct sip_pvt *p, struct sip_request *req) { if (!p->initreq.headers) { /* Use this as the basis */ @@ -4612,8 +4568,7 @@ /*--- transmit_notify_with_sipfrag: Notify a transferring party of the status of trasnfer ---*/ /* Apparently the draft SIP REFER structure was too simple, so it was decided that the * status of transfers also needed to be sent via NOTIFY instead of just the 202 Accepted - * that had worked heretofore. - */ + * that had worked heretofore. */ static int transmit_notify_with_sipfrag(struct sip_pvt *p, int cseq) { struct sip_request req; @@ -4642,7 +4597,7 @@ static char *regstate2str(int regstate) { - switch(regstate) { + switch (regstate) { case REG_STATE_FAILED: return "Failed"; case REG_STATE_UNREGISTERED: @@ -4664,10 +4619,8 @@ } } -static int transmit_register(struct sip_registry *r, int sipmethod, char *auth, char *authheader); - /*--- sip_reregister: Update registration with SIP Proxy---*/ -static int sip_reregister(void *data) +static int sip_reregister(void *data) { /* if we are here, we know that we need to reregister. */ struct sip_registry *r= ASTOBJ_REF((struct sip_registry *) data); @@ -4677,22 +4630,20 @@ return 0; /* Since registry's are only added/removed by the the monitor thread, this - may be overkill to reference/dereference at all here */ + * may be overkill to reference/dereference at all here. */ if (sipdebug) ast_log(LOG_NOTICE, " -- Re-registration for %s@%s\n", r->username, r->hostname); r->expire = -1; __sip_do_register(r); - ASTOBJ_UNREF(r,sip_registry_destroy); + ASTOBJ_UNREF(r, sip_registry_destroy); return 0; } /*--- __sip_do_register: Register with SIP proxy ---*/ static int __sip_do_register(struct sip_registry *r) { - int res; - res=transmit_register(r, SIP_REGISTER, NULL, NULL); - return res; + return transmit_register(r, SIP_REGISTER, NULL, NULL); } /*--- sip_reg_timeout: Registration timeout, register again */ @@ -4708,33 +4659,32 @@ if (!r) return 0; - ast_log(LOG_NOTICE, " -- Registration for '%s@%s' timed out, trying again (Attempt #%d)\n", r->username, r->hostname, r->regattempts); + ast_log(LOG_NOTICE, " -- Registration for '%s@%s' timed out, trying again (Attempt #%d)\n", r->username, r->hostname, r->regattempts); if (r->call) { - /* Unlink us, destroy old call. Locking is not relevant here because all this happens - in the single SIP manager thread. */ + /* Unlink us, destroy old call. Locking is not relevant here because + * all this happens in the single SIP manager thread. */ p = r->call; if (p->registry) ASTOBJ_UNREF(p->registry, sip_registry_destroy); r->call = NULL; - ast_set_flag(p, SIP_NEEDDESTROY); + ast_set_flag(p, SIP_NEEDDESTROY); /* Pretend to ACK anything just in case */ /* OEJ: Ack what??? */ __sip_pretend_ack(p); } /* If we have a limit, stop registration and give up */ if (global_regattempts_max && r->regattempts > global_regattempts_max) { - /* Ok, enough is enough. Don't try any more */ - /* We could add an external notification here... - steal it from app_voicemail :-) */ + /* Ok, enough is enough. Don't try any more. We could add an external + * notification here... steal it from app_voicemail :-) */ ast_log(LOG_NOTICE, " -- Giving up forever trying to register '%s@%s'\n", r->username, r->hostname); - r->regstate=REG_STATE_FAILED; + r->regstate = REG_STATE_FAILED; } else { - r->regstate=REG_STATE_UNREGISTERED; + r->regstate = REG_STATE_UNREGISTERED; r->timeout = -1; - res=transmit_register(r, SIP_REGISTER, NULL, NULL); + res = transmit_register(r, SIP_REGISTER, NULL, NULL); } manager_event(EVENT_FLAG_SYSTEM, "Registry", "Channel: SIP\r\nUser: %s\r\nDomain: %s\r\nStatus: %s\r\n", r->username, r->hostname, regstate2str(r->regstate)); - ASTOBJ_UNREF(r,sip_registry_destroy); + ASTOBJ_UNREF(r, sip_registry_destroy); return 0; } @@ -4750,7 +4700,7 @@ struct sip_pvt *p; /* exit if we are already in process with this registrar ?*/ - if ( r == NULL || ((auth==NULL) && (r->regstate==REG_STATE_REGSENT || r->regstate==REG_STATE_AUTHSENT))) { + if (r == NULL || ((auth == NULL) && (r->regstate == REG_STATE_REGSENT || r->regstate == REG_STATE_AUTHSENT))) { ast_log(LOG_NOTICE, "Strange, trying to register %s@%s when registration already pending\n", r->username, r->hostname); return 0; } @@ -4762,7 +4712,7 @@ } else { p = r->call; p->tag = rand(); /* create a new local tag for every register attempt */ - p->theirtag[0]='\0'; /* forget their old tag, so we don't match tags when getting response */ + p->theirtag[0] = '\0'; /* forget their old tag, so we don't match tags when getting response */ } } else { /* Build callid for registration if we haven't registred before */ @@ -4771,13 +4721,13 @@ r->callid_valid = 1; } /* Allocate SIP packet for registration */ - p=sip_alloc( r->callid, NULL, 0, SIP_REGISTER); + p = sip_alloc(r->callid, NULL, 0, SIP_REGISTER); if (!p) { ast_log(LOG_WARNING, "Unable to allocate registration call\n"); return 0; } /* Find address to hostname */ - if (create_addr(p,r->hostname)) { + if (create_addr(p, r->hostname)) { /* we have what we hope is a temporary network error, * probably DNS. We need to reschedule a registration try */ sip_destroy(p); @@ -4797,15 +4747,15 @@ if (r->portno) p->sa.sin_port = htons(r->portno); ast_set_flag(p, SIP_OUTGOING); /* Registration is outgoing call */ - r->call=p; /* Save pointer to SIP packet */ - p->registry=ASTOBJ_REF(r); /* Add pointer to registry in packet */ + r->call = p; /* Save pointer to SIP packet */ + p->registry = ASTOBJ_REF(r); /* Add pointer to registry in packet */ if (!ast_strlen_zero(r->secret)) /* Secret (password) */ ast_copy_string(p->peersecret, r->secret, sizeof(p->peersecret)); if (!ast_strlen_zero(r->md5secret)) ast_copy_string(p->peermd5secret, r->md5secret, sizeof(p->peermd5secret)); - /* User name in this realm - - if authuser is set, use that, otherwise use username */ - if (!ast_strlen_zero(r->authuser)) { + /* User name in this realm + * - if authuser is set, use that, otherwise use username */ + if (!ast_strlen_zero(r->authuser)) { ast_copy_string(p->peername, r->authuser, sizeof(p->peername)); ast_copy_string(p->authname, r->authuser, sizeof(p->authname)); } else { @@ -4820,11 +4770,9 @@ /* Save extension in packet */ ast_copy_string(p->exten, r->contact, sizeof(p->exten)); - /* - check which address we should use in our contact header - based on whether the remote host is on the external or - internal network so we can register through nat - */ + /* check which address we should use in our contact header based on + * whether the remote host is on the external or internal network so we + * can register through nat */ if (ast_sip_ouraddrfor(&p->sa.sin_addr, &p->ourip)) memcpy(&p->ourip, &bindaddr.sin_addr, sizeof(p->ourip)); build_contact(p); @@ -4853,9 +4801,9 @@ else snprintf(to, sizeof(to), "", r->username, p->tohost); } - - /* Fromdomain is what we are registering to, regardless of actual - host name from SRV */ + + /* Fromdomain is what we are registering to, regardless of actualhost name + * from SRV */ if (p->fromdomain && !ast_strlen_zero(p->fromdomain)) snprintf(addr, sizeof(addr), "sip:%s", p->fromdomain); else @@ -4879,10 +4827,9 @@ add_header(&req, "CSeq", tmp); add_header(&req, "User-Agent", default_useragent); - - if (auth) /* Add auth header */ + if (auth) { /* Add auth header */ add_header(&req, authheader, auth); - else if ( !ast_strlen_zero(r->nonce) ) { + } else if (!ast_strlen_zero(r->nonce)) { char digest[1024]; /* We have auth data to reuse, build a digest header! */ @@ -4894,10 +4841,9 @@ ast_copy_string(p->opaque, r->opaque, sizeof(p->opaque)); ast_copy_string(p->qop, r->qop, sizeof(p->qop)); - memset(digest,0,sizeof(digest)); + memset(digest, 0, sizeof(digest)); build_reply_digest(p, sipmethod, digest, sizeof(digest)); add_header(&req, "Authorization", digest); - } snprintf(tmp, sizeof(tmp), "%d", default_expiry); @@ -4912,7 +4858,7 @@ ast_verbose("REGISTER %d headers, %d lines\n", p->initreq.headers, p->initreq.lines); } determine_firstline_parts(&p->initreq); - r->regstate=auth?REG_STATE_AUTHSENT:REG_STATE_REGSENT; + r->regstate = auth?REG_STATE_AUTHSENT:REG_STATE_REGSENT; r->regattempts++; /* Another attempt */ if (option_debug > 3) ast_verbose("REGISTER attempt %d to %s@%s\n", r->regattempts, r->username, r->hostname); @@ -4937,13 +4883,14 @@ char referto[256]; char tmp[80]; - if (ast_test_flag(p, SIP_OUTGOING)) + if (ast_test_flag(p, SIP_OUTGOING)) { of = get_header(&p->initreq, "To"); - else + } else { of = get_header(&p->initreq, "From"); + } ast_copy_string(from, of, sizeof(from)); of = get_in_brackets(from); - ast_copy_string(p->from,of,sizeof(p->from)); + ast_copy_string(p->from, of, sizeof(p->from)); if (strncmp(of, "sip:", 4)) { ast_log(LOG_NOTICE, "From address missing 'sip:', using it anyway\n"); } else @@ -4965,7 +4912,7 @@ if (strlen(tmp) && atoi(tmp)) { p->maxforwards = atoi(tmp) - 1; } else { - p->maxforwards = DEFAULT_MAX_FORWARDS - 1; + p->maxforwards = DEFAULT_MAX_FORWARDS - 1; } if (p->maxforwards > -1) { /* save in case we get 407 challenge */ @@ -5026,7 +4973,7 @@ add_header_contentLength(&resp, 0); add_blank_header(&resp); - return send_request(p, &resp, reliable, seqno ? seqno : p->ocseq); + return send_request(p, &resp, reliable, seqno ? seqno : p->ocseq); } /*--- expire_register: Expire registration of SIP peer ---*/ @@ -5048,8 +4995,6 @@ return 0; } -static int sip_poke_peer(struct sip_peer *peer); - static int sip_poke_peer_s(void *data) { struct sip_peer *peer = data; @@ -5098,7 +5043,7 @@ if (option_verbose > 2) ast_verbose(VERBOSE_PREFIX_3 "SIP Seeding peer from astdb: '%s' at %s@%s:%d for %d\n", - peer->name, peer->username, ast_inet_ntoa(iabuf, sizeof(iabuf), in), port, expiry); + peer->name, peer->username, ast_inet_ntoa(iabuf, sizeof(iabuf), in), port, expiry); memset(&peer->addr, 0, sizeof(peer->addr)); peer->addr.sin_family = AF_INET; @@ -5120,7 +5065,7 @@ /*--- parse_ok_contact: Parse contact header for 200 OK on INVITE ---*/ static int parse_ok_contact(struct sip_pvt *pvt, struct sip_request *req) { - char contact[250]= ""; + char contact[250]= ""; char *c, *n, *pt; int port; struct hostent *hp; @@ -5132,11 +5077,11 @@ c = get_in_brackets(contact); /* Save full contact to call pvt for later bye or re-invite */ - ast_copy_string(pvt->fullcontact, c, sizeof(pvt->fullcontact)); + ast_copy_string(pvt->fullcontact, c, sizeof(pvt->fullcontact)); /* Save URI for later ACKs, BYE or RE-invites */ ast_copy_string(pvt->okcontacturi, c, sizeof(pvt->okcontacturi)); - + /* Make sure it's a SIP URL */ if (strncasecmp(c, "sip:", 4)) { ast_log(LOG_NOTICE, "'%s' is not a valid SIP contact (missing sip:) trying to use anyway\n", c); @@ -5145,9 +5090,9 @@ /* Ditch arguments */ n = strchr(c, ';'); - if (n) + if (n) { *n = '\0'; - + } /* Grab host */ n = strchr(c, '@'); if (!n) { @@ -5179,18 +5124,16 @@ memcpy(&pvt->sa.sin_addr, hp->h_addr, sizeof(pvt->sa.sin_addr)); pvt->sa.sin_port = htons(port); } else { - /* Don't trust the contact field. Just use what they came to us - with. */ + /* Don't trust the contact field. Just use what they came to us with. */ memcpy(&pvt->sa, &pvt->recv, sizeof(pvt->sa)); } return 0; } - /*--- parse_contact: Parse contact header and save registration ---*/ static int parse_contact(struct sip_pvt *pvt, struct sip_peer *p, struct sip_request *req) { - char contact[80]= ""; + char contact[80]= ""; char data[256]; char iabuf[INET_ADDRSTRLEN]; char *expires = get_header(req, "Expires"); @@ -5275,8 +5218,7 @@ memcpy(&p->addr.sin_addr, hp->h_addr, sizeof(p->addr.sin_addr)); p->addr.sin_port = htons(port); } else { - /* Don't trust the contact field. Just use what they came to us - with */ + /* Don't trust the contact field. Just use what they came to us with */ memcpy(&p->addr, &pvt->recv, sizeof(p->addr)); } @@ -5304,7 +5246,7 @@ 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); register_peer_exten(p, 1); } - + /* Save SIP options profile */ p->sipoptions = pvt->sipoptions; @@ -5313,7 +5255,7 @@ if (useragent && strcasecmp(useragent, p->useragent)) { ast_copy_string(p->useragent, useragent, sizeof(p->useragent)); if (option_verbose > 3) { - ast_verbose(VERBOSE_PREFIX_3 "Saved useragent \"%s\" for peer %s\n",p->useragent,p->name); + ast_verbose(VERBOSE_PREFIX_3 "Saved useragent \"%s\" for peer %s\n", p->useragent, p->name); } } return 0; @@ -5361,9 +5303,9 @@ free_old_route(p->route); p->route = NULL; } - + p->route_persistant = backwards; - + /* We build up head, then assign it to p->route when we're done */ head = NULL; tail = head; /* 1st we pass through all the hops in any Record-Route headers */ @@ -5459,12 +5401,13 @@ && !ast_test_flag(p, SIP_OSPAUTH) && global_allowguest != 2 #endif - ) + ) return 0; if (sipmethod == SIP_REGISTER) { - /* On a REGISTER, we have to use 401 and its family of headers instead of 407 and its family - of headers -- GO SIP! Whoo hoo! Two things that do the same thing but are used in - different circumstances! What a surprise. */ + /* On a REGISTER, we have to use 401 and its family of headers instead + * of 407 and its family of headers -- GO SIP! Whoo hoo! Two things + * that do the same thing but are used in different circumstances! What + * a surprise. */ response = "401 Unauthorized"; reqheader = "Authorization"; respheader = "WWW-Authenticate"; @@ -5479,25 +5422,24 @@ /* Validate token */ if (ast_osp_validate(NULL, osptoken, &p->osphandle, &osptimelimit, p->cid_num, p->sa.sin_addr, p->exten) < 1) return -1; - + snprintf(tmp, sizeof(tmp), "%d", p->osphandle); pbx_builtin_setvar_helper(p->owner, "_OSPHANDLE", tmp); - /* If ospauth is 'exclusive' don't require further authentication */ if ((ast_test_flag(p, SIP_OSPAUTH) == SIP_OSPAUTH_EXCLUSIVE) || (ast_strlen_zero(secret) && ast_strlen_zero(md5secret))) return 0; } -#endif - authtoken = get_header(req, reqheader); +#endif + authtoken = get_header(req, reqheader); if (ignore && !ast_strlen_zero(randdata) && ast_strlen_zero(authtoken)) { - /* This is a retransmitted invite/register/etc, don't reconstruct authentication - information */ + /* This is a retransmitted invite/register/etc, don't reconstruct + * authentication information */ if (!ast_strlen_zero(randdata)) { if (!reliable) { - /* Resend message if this was NOT a reliable delivery. Otherwise the - retransmission should get it */ + /* Resend message if this was NOT a reliable delivery. Otherwise + * the retransmission should get it */ transmit_response_with_auth(p, response, req, randdata, reliable, respheader, 0); /* Schedule auto destroy in 15 seconds */ sip_scheddestroy(p, 15000); @@ -5511,19 +5453,20 @@ sip_scheddestroy(p, 15000); res = 1; } else { - /* Whoever came up with the authentication section of SIP can suck my %&#$&* for not putting - an example in the spec of just what it is you're doing a hash on. */ + /* Whoever came up with the authentication section of SIP can suck my + * %&#$&* for not putting an example in the spec of just what it is + * you're doing a hash on. */ char a1[256]; char a2[256]; char a1_hash[256]; char a2_hash[256]; char resp[256]; - char resp_hash[256]=""; + char resp_hash[256] = ""; char tmp[256] = ""; char *c; char *z; - char *ua_hash =""; - char *resp_uri =""; + char *ua_hash = ""; + char *resp_uri = ""; char *nonce = ""; char *digestusername = ""; int wrongnonce = 0; @@ -5533,60 +5476,60 @@ ast_copy_string(tmp, authtoken, sizeof(tmp)); c = tmp; - while(c) { + while (c) { c = ast_skip_blanks(c); if (!*c) break; if (!strncasecmp(c, "response=", strlen("response="))) { c+= strlen("response="); if ((*c == '\"')) { - ua_hash=++c; - if ((c = strchr(c,'\"'))) + ua_hash = ++c; + if ((c = strchr(c, '\"'))) *c = '\0'; } else { - ua_hash=c; - if ((c = strchr(c,','))) + ua_hash = c; + if ((c = strchr(c, ','))) *c = '\0'; } - } else if (!strncasecmp(c, "uri=", strlen("uri="))) { c+= strlen("uri="); if ((*c == '\"')) { - resp_uri=++c; - if ((c = strchr(c,'\"'))) + resp_uri = ++c; + if ((c = strchr(c, '\"'))) *c = '\0'; } else { - resp_uri=c; - if ((c = strchr(c,','))) + resp_uri = c; + if ((c = strchr(c, ','))) *c = '\0'; } - } else if (!strncasecmp(c, "username=", strlen("username="))) { c+= strlen("username="); if ((*c == '\"')) { - digestusername=++c; - if((c = strchr(c,'\"'))) + digestusername = ++c; + if ((c = strchr(c, '\"'))) *c = '\0'; } else { - digestusername=c; - if((c = strchr(c,','))) + digestusername = c; + if ((c = strchr(c, ','))) *c = '\0'; } } else if (!strncasecmp(c, "nonce=", strlen("nonce="))) { c+= strlen("nonce="); if ((*c == '\"')) { - nonce=++c; - if ((c = strchr(c,'\"'))) + nonce = ++c; + if ((c = strchr(c, '\"'))) *c = '\0'; } else { - nonce=c; - if ((c = strchr(c,','))) + nonce = c; + if ((c = strchr(c, ','))) *c = '\0'; } - - } else - if ((z = strchr(c,' ')) || (z = strchr(c,','))) c=z; + } else { + if ((z = strchr(c, ' ')) || (z = strchr(c, ','))) { + c = z; + } + } if (c) c++; } @@ -5634,7 +5577,7 @@ /* Schedule auto destroy in 15 seconds */ sip_scheddestroy(p, 15000); return 1; - } + } /* resp_hash now has the expected response, compare the two */ if (ua_hash && !strncasecmp(ua_hash, resp_hash, strlen(resp_hash))) { /* Auth is OK */ @@ -5645,7 +5588,7 @@ return res; } -/*--- cb_extensionstate: Part of thte SUBSCRIBE support subsystem ---*/ +/*--- cb_extensionstate: Part of the SUBSCRIBE support subsystem ---*/ static int cb_extensionstate(char *context, char* exten, int state, void *data) { struct sip_pvt *p = data; @@ -5654,7 +5597,7 @@ p->stateid = -1; return 0; } - + transmit_state_notify(p, state, 1); if (option_debug > 1) @@ -5673,10 +5616,10 @@ char *t; /* Terminate URI */ t = uri; - while(*t && (*t > 32) && (*t != ';')) + while (*t && (*t > 32) && (*t != ';')) t++; *t = '\0'; - + ast_copy_string(tmp, get_header(req, "To"), sizeof(tmp)); c = get_in_brackets(tmp); /* Ditch ;user=phone */ @@ -5692,14 +5635,15 @@ } /* Strip off the domain name */ c = strchr(name, '@'); - if (c) + if (c) { *c = '\0'; + } ast_copy_string(p->exten, name, sizeof(p->exten)); build_contact(p); peer = find_peer(name, NULL, 1); if (!(peer && ast_apply_ha(peer->ha, sin))) { if (peer) - ASTOBJ_UNREF(peer,sip_destroy_peer); + ASTOBJ_UNREF(peer, sip_destroy_peer); } if (peer) { if (!ast_test_flag(peer, SIP_DYNAMIC)) { @@ -5718,7 +5662,7 @@ peer->lastmsgssent = -1; res = 0; } - } + } } } if (!peer && autocreatepeer) { @@ -5749,16 +5693,16 @@ transmit_response(p, "403 Forbidden", &p->initreq); break; case -2: - /* Username and digest username does not match. - Asterisk uses the From: username for authentication. We need the - users to use the same authentication user name until we support - proper authentication by digest auth name */ + /* Username and digest username does not match. + * Asterisk uses the From: username for authentication. We need the + * users to use the same authentication user name until we support + * proper authentication by digest auth name */ transmit_response(p, "403 Authentication user name does not match account name", &p->initreq); break; } } if (peer) - ASTOBJ_UNREF(peer,sip_destroy_peer); + ASTOBJ_UNREF(peer, sip_destroy_peer); return res; } @@ -5767,7 +5711,7 @@ { char tmp[256] = "", *c, *a; struct sip_request *req; - + req = oreq; if (!req) req = &p->initreq; @@ -5796,17 +5740,17 @@ char tmp[256] = "", *c, *a; char tmpf[256]= "", *fr; struct sip_request *req; - + req = oreq; if (!req) req = &p->initreq; if (req->rlPart2) ast_copy_string(tmp, req->rlPart2, sizeof(tmp)); c = get_in_brackets(tmp); - + ast_copy_string(tmpf, get_header(req, "From"), sizeof(tmpf)); fr = get_in_brackets(tmpf); - + if (strncmp(c, "sip:", 4)) { ast_log(LOG_WARNING, "Huh? Not a SIP header (%s)?\n", c); return -1; @@ -5849,27 +5793,27 @@ } if (ast_canmatch_extension(NULL, p->context, c, 1, fr) || - !strncmp(c, ast_pickup_ext(),strlen(c))) { + !strncmp(c, ast_pickup_ext(), strlen(c))) { return 1; } - + return -1; } /*--- get_sip_pvt_byid_locked: Lock interface lock and find matching pvt lock ---*/ -static struct sip_pvt *get_sip_pvt_byid_locked(char *callid) +static struct sip_pvt *get_sip_pvt_byid_locked(char *callid) { struct sip_pvt *sip_pvt_ptr = NULL; - + /* Search interfaces and find the match */ ast_mutex_lock(&iflock); sip_pvt_ptr = iflist; - while(sip_pvt_ptr) { + while (sip_pvt_ptr) { if (!strcmp(sip_pvt_ptr->callid, callid)) { /* Go ahead and lock it (and its owner) before returning */ ast_mutex_lock(&sip_pvt_ptr->lock); if (sip_pvt_ptr->owner) { - while(ast_mutex_trylock(&sip_pvt_ptr->owner->lock)) { + while (ast_mutex_trylock(&sip_pvt_ptr->owner->lock)) { ast_mutex_unlock(&sip_pvt_ptr->lock); usleep(1); ast_mutex_lock(&sip_pvt_ptr->lock); @@ -5900,22 +5844,22 @@ if (!req) { req = &sip_pvt->initreq; } - - if (!( (p_refer_to = get_header(req, "Refer-To")) && (h_refer_to = ast_strdupa(p_refer_to)) )) { + + if (!((p_refer_to = get_header(req, "Refer-To")) && (h_refer_to = ast_strdupa(p_refer_to)))) { ast_log(LOG_WARNING, "No Refer-To Header That's illegal\n"); return -1; } refer_to = get_in_brackets(h_refer_to); - if (!( (p_referred_by = get_header(req, "Referred-By")) && (h_referred_by = ast_strdupa(p_referred_by)) )) { + if (!((p_referred_by = get_header(req, "Referred-By")) && (h_referred_by = ast_strdupa(p_referred_by)))) { ast_log(LOG_WARNING, "No Referrred-By Header That's not illegal\n"); return -1; } else { referred_by = get_in_brackets(h_referred_by); } h_contact = get_header(req, "Contact"); - + if (strncmp(refer_to, "sip:", 4)) { ast_log(LOG_WARNING, "Refer-to: Huh? Not a SIP header (%s)?\n", refer_to); return -1; @@ -5931,7 +5875,7 @@ if (referred_by) referred_by += 4; - + if ((ptr = strchr(refer_to, '?'))) { /* Search for arguments */ *ptr = '\0'; @@ -5940,42 +5884,47 @@ char *p; replace_callid = ast_strdupa(ptr + 9); /* someday soon to support invite/replaces properly! - replaces_header = ast_strdupa(replace_callid); - -anthm - */ + * replaces_header = ast_strdupa(replace_callid); + * -anthm */ url_decode(replace_callid); - if ((ptr = strchr(replace_callid, '%'))) + if ((ptr = strchr(replace_callid, '%'))) { *ptr = '\0'; - if ((ptr = strchr(replace_callid, ';'))) + } + if ((ptr = strchr(replace_callid, ';'))) { *ptr = '\0'; + } /* Skip leading whitespace XXX memmove behaviour with overlaps ? */ p = ast_skip_blanks(replace_callid); if (p != replace_callid) memmove(replace_callid, p, strlen(p)); } } - - if ((ptr = strchr(refer_to, '@'))) /* Skip domain (should be saved in SIPDOMAIN) */ + + if ((ptr = strchr(refer_to, '@'))) { /* Skip domain (should be saved in SIPDOMAIN) */ *ptr = '\0'; - if ((ptr = strchr(refer_to, ';'))) + } + if ((ptr = strchr(refer_to, ';'))) { *ptr = '\0'; - + } + if (referred_by) { - if ((ptr = strchr(referred_by, '@'))) + if ((ptr = strchr(referred_by, '@'))) { *ptr = '\0'; - if ((ptr = strchr(referred_by, ';'))) + } + if ((ptr = strchr(referred_by, ';'))) { *ptr = '\0'; + } } - + if (sip_debug_test_pvt(sip_pvt)) { ast_verbose("Transfer to %s in %s\n", refer_to, sip_pvt->context); if (referred_by) ast_verbose("Transfer from %s in %s\n", referred_by, sip_pvt->context); } - if (!ast_strlen_zero(replace_callid)) { + if (!ast_strlen_zero(replace_callid)) { /* This is a supervised transfer */ - ast_log(LOG_DEBUG,"Assigning Replace-Call-ID Info %s to REPLACE_CALL_ID\n",replace_callid); - + ast_log(LOG_DEBUG, "Assigning Replace-Call-ID Info %s to REPLACE_CALL_ID\n", replace_callid); + ast_copy_string(sip_pvt->refer_to, "", sizeof(sip_pvt->refer_to)); ast_copy_string(sip_pvt->referred_by, "", sizeof(sip_pvt->referred_by)); ast_copy_string(sip_pvt->refer_contact, "", sizeof(sip_pvt->refer_contact)); @@ -5989,17 +5938,17 @@ return 0; } else { 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); - /* XXX The refer_to could contain a call on an entirely different machine, requiring an - INVITE with a replaces header -anthm XXX */ + /* XXX The refer_to could contain a call on an entirely different machine, requiring an + * INVITE with a replaces header -anthm XXX */ /* The only way to find out is to use the dialplan - oej */ } } else if (ast_exists_extension(NULL, sip_pvt->context, refer_to, 1, NULL) || !strcmp(refer_to, ast_parking_ext())) { /* This is an unsupervised transfer (blind transfer) */ - - ast_log(LOG_DEBUG,"Unsupervised transfer to (Refer-To): %s\n", refer_to); + + ast_log(LOG_DEBUG, "Unsupervised transfer to (Refer-To): %s\n", refer_to); if (referred_by) - ast_log(LOG_DEBUG,"Transferred by (Referred-by: ) %s \n", referred_by); - ast_log(LOG_DEBUG,"Transfer Contact Info %s (REFER_CONTACT)\n", h_contact); + ast_log(LOG_DEBUG, "Transferred by (Referred-by: ) %s \n", referred_by); + ast_log(LOG_DEBUG, "Transfer Contact Info %s (REFER_CONTACT)\n", h_contact); ast_copy_string(sip_pvt->refer_to, refer_to, sizeof(sip_pvt->refer_to)); if (referred_by) ast_copy_string(sip_pvt->referred_by, referred_by, sizeof(sip_pvt->referred_by)); @@ -6024,31 +5973,32 @@ { char tmp[256] = "", *c, *a; struct sip_request *req; - + req = oreq; if (!req) req = &p->initreq; ast_copy_string(tmp, get_header(req, "Also"), sizeof(tmp)); - + c = get_in_brackets(tmp); - - + if (strncmp(c, "sip:", 4)) { ast_log(LOG_WARNING, "Huh? Not a SIP header (%s)?\n", c); return -1; } c += 4; - if ((a = strchr(c, '@'))) + if ((a = strchr(c, '@'))) { *a = '\0'; - if ((a = strchr(c, ';'))) + } + if ((a = strchr(c, ';'))) { *a = '\0'; - + } + if (sip_debug_test_pvt(p)) { ast_verbose("Looking for %s in %s\n", c, p->context); } if (ast_exists_extension(NULL, p->context, c, 1, NULL)) { /* This is an unsupervised transfer */ - ast_log(LOG_DEBUG,"Assigning Extension %s to REFER-TO\n", c); + ast_log(LOG_DEBUG, "Assigning Extension %s to REFER-TO\n", c); ast_copy_string(p->refer_to, c, sizeof(p->refer_to)); ast_copy_string(p->referred_by, "", sizeof(p->referred_by)); ast_copy_string(p->refer_contact, "", sizeof(p->refer_contact)); @@ -6073,8 +6023,9 @@ memset(via, 0, sizeof(via)); ast_copy_string(via, get_header(req, "Via"), sizeof(via)); c = strchr(via, ';'); - if (c) + if (c) { *c = '\0'; + } c = strchr(via, ' '); if (c) { *c = '\0'; @@ -6109,8 +6060,8 @@ /*--- get_calleridname: Get caller id name from SIP headers ---*/ static char *get_calleridname(char *input, char *output, size_t outputsize) { - char *end = strchr(input,'<'); - char *tmp = strchr(input,'\"'); + char *end = strchr(input, '<'); + char *tmp = strchr(input, '\"'); int bytes = 0; int maxbytes = outputsize - 1; @@ -6131,7 +6082,7 @@ /* clear the empty characters in the begining*/ input = ast_skip_blanks(input); /* clear the empty characters in the end */ - while(*end && (*end < 33) && end > input) + while (*end && (*end < 33) && end > input) end--; if (end >= input) { bytes = (int) (end - input) + 2; @@ -6147,16 +6098,15 @@ return output; } -/*--- 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 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 int get_rpid_num(char *input, char *output, int maxlen) { char *start; char *end; - start = strchr(input,':'); + start = strchr(input, ':'); if (!start) { output[0] = '\0'; return 0; @@ -6164,49 +6114,49 @@ start++; /* we found "number" */ - ast_copy_string(output,start,maxlen); + ast_copy_string(output, start, maxlen); output[maxlen-1] = '\0'; - end = strchr(output,'@'); + end = strchr(output, '@'); if (end) *end = '\0'; else output[0] = '\0'; - if (strstr(input,"privacy=full") || strstr(input,"privacy=uri")) + if (strstr(input, "privacy=full") || strstr(input, "privacy=uri")) return AST_PRES_PROHIB_USER_NUMBER_NOT_SCREENED; return 0; } - /*--- check_user: Check if matching user or peer is defined ---*/ 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) { struct sip_user *user; struct sip_peer *peer; char *of, from[256] = "", *c; - char *rpid,rpid_num[50]; + char *rpid, rpid_num[50]; char iabuf[INET_ADDRSTRLEN]; int res = 0; char *t; char calleridname[50]; - int debug=sip_debug_test_addr(sin); + int debug = sip_debug_test_addr(sin); struct ast_variable *tmpvar = NULL, *v = NULL; /* Terminate URI */ t = uri; - while(*t && (*t > 32) && (*t != ';')) + while (*t && (*t > 32) && (*t != ';')) t++; *t = '\0'; of = get_header(req, "From"); ast_copy_string(from, of, sizeof(from)); - memset(calleridname,0,sizeof(calleridname)); + memset(calleridname, 0, sizeof(calleridname)); get_calleridname(from, calleridname, sizeof(calleridname)); rpid = get_header(req, "Remote-Party-ID"); - memset(rpid_num,0,sizeof(rpid_num)); - if (!ast_strlen_zero(rpid)) - p->callingpres = get_rpid_num(rpid,rpid_num, sizeof(rpid_num)); + memset(rpid_num, 0, sizeof(rpid_num)); + if (!ast_strlen_zero(rpid)) { + p->callingpres = get_rpid_num(rpid, rpid_num, sizeof(rpid_num)); + } of = get_in_brackets(from); if (ast_strlen_zero(p->exten)) { @@ -6243,7 +6193,7 @@ /* copy channel vars */ for (v = user->chanvars ; v ; v = v->next) { if ((tmpvar = ast_variable_new(v->name, v->value))) { - tmpvar->next = p->chanvars; + tmpvar->next = p->chanvars; p->chanvars = tmpvar; } } @@ -6276,12 +6226,13 @@ ast_set_flag(p, SIP_CALL_LIMIT); if (!ast_strlen_zero(user->context)) ast_copy_string(p->context, user->context, sizeof(p->context)); - if (!ast_strlen_zero(user->cid_num) && !ast_strlen_zero(p->cid_num)) { + if (!ast_strlen_zero(user->cid_num) && !ast_strlen_zero(p->cid_num)) { ast_copy_string(p->cid_num, user->cid_num, sizeof(p->cid_num)); ast_shrink_phone_number(p->cid_num); } - if (!ast_strlen_zero(user->cid_name) && !ast_strlen_zero(p->cid_num)) + if (!ast_strlen_zero(user->cid_name) && !ast_strlen_zero(p->cid_num)) { ast_copy_string(p->cid_name, user->cid_name, sizeof(p->cid_name)); + } ast_copy_string(p->username, user->name, sizeof(p->username)); ast_copy_string(p->peersecret, user->secret, sizeof(p->peersecret)); ast_copy_string(p->peermd5secret, user->md5secret, sizeof(p->peermd5secret)); @@ -6307,17 +6258,16 @@ if (user) { if (!mailbox && debug) ast_verbose("Found user '%s', but fails host access\n", user->name); - ASTOBJ_UNREF(user,sip_destroy_user); + ASTOBJ_UNREF(user, sip_destroy_user); } user = NULL; } if (!user) { - /* If we didn't find a user match, check for peers */ - /* Look for peer based on the IP address we received data from */ - /* If peer is registred from this IP address or have this as a default - IP address, this call is from the peer - */ + /* If we didn't find a user match, check for peers. + * Look for peer based on the IP address we received data from. + * If peer is registred from this IP address or have this as a default + * IP address, this call is from the peer */ peer = find_peer(NULL, &p->recv, 1); if (peer) { if (debug) @@ -6364,7 +6314,7 @@ /* copy channel vars */ for (v = peer->chanvars ; v ; v = v->next) { if ((tmpvar = ast_variable_new(v->name, v->value))) { - tmpvar->next = p->chanvars; + tmpvar->next = p->chanvars; p->chanvars = tmpvar; } } @@ -6379,11 +6329,13 @@ ast_copy_string(p->cid_num, peer->cid_num, sizeof(p->cid_num)); ast_shrink_phone_number(p->cid_num); } - if (!ast_strlen_zero(peer->cid_name) && !ast_strlen_zero(p->cid_name)) + if (!ast_strlen_zero(peer->cid_name) && !ast_strlen_zero(p->cid_name)) { ast_copy_string(p->cid_name, peer->cid_name, sizeof(p->cid_name)); + } ast_copy_string(p->fullcontact, peer->fullcontact, sizeof(p->fullcontact)); - if (!ast_strlen_zero(peer->context)) + if (!ast_strlen_zero(peer->context)) { ast_copy_string(p->context, peer->context, sizeof(p->context)); + } ast_copy_string(p->peersecret, peer->secret, sizeof(p->peersecret)); ast_copy_string(p->peermd5secret, peer->md5secret, sizeof(p->peermd5secret)); ast_copy_string(p->language, peer->language, sizeof(p->language)); @@ -6393,33 +6345,35 @@ p->pickupgroup = peer->pickupgroup; p->capability = peer->capability; p->jointcapability = peer->capability; - if (p->peercapability) + if (p->peercapability) { p->jointcapability &= p->peercapability; - if (ast_test_flag(p, SIP_DTMF) == SIP_DTMF_RFC2833) + } + if (ast_test_flag(p, SIP_DTMF) == SIP_DTMF_RFC2833) { p->noncodeccapability |= AST_RTP_DTMF; - else + } else { p->noncodeccapability &= ~AST_RTP_DTMF; + } } - ASTOBJ_UNREF(peer,sip_destroy_peer); - } else { - if (debug) + ASTOBJ_UNREF(peer, sip_destroy_peer); + } else { + if (debug) { 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)); - + } /* do we allow guests? */ - if (!global_allowguest) - res = -1; /* we don't want any guests, authentication will fail */ -#ifdef OSP_SUPPORT + if (!global_allowguest) { + res = -1; /* we don't want any guests, authentication will fail */ + } +#ifdef OSP_SUPPORT else if (global_allowguest == 2) { ast_copy_flags(p, &global_flags, SIP_OSPAUTH); - res = check_auth(p, req, p->randdata, sizeof(p->randdata), "", "", "", sipmethod, uri, reliable, ignore); + res = check_auth(p, req, p->randdata, sizeof(p->randdata), "", "", "", sipmethod, uri, reliable, ignore); } #endif } - } if (user) - ASTOBJ_UNREF(user,sip_destroy_user); + ASTOBJ_UNREF(user, sip_destroy_user); return res; } @@ -6439,7 +6393,7 @@ y = len - strlen(buf) - 5; if (y < 0) y = 0; - for (x=0;xlines;x++) { + for (x = 0; xlines; x++) { strncat(buf, req->line[x], y); /* safe */ y -= strlen(req->line[x]) + 1; if (y < 0) @@ -6450,7 +6404,6 @@ return 0; } - /*--- receive_message: Receive SIP MESSAGE method messages ---*/ /* we handle messages within current calls currently */ static void receive_message(struct sip_pvt *p, struct sip_request *req) @@ -6475,8 +6428,8 @@ } } -/*--- sip_show_inuse: CLI Command to show calls within limits set by - incominglimit ---*/ +/*--- sip_show_inuse: CLI Command to show calls within limits set by + * incominglimit ---*/ static int sip_show_inuse(int fd, int argc, char *argv[]) { #define FORMAT "%-25.25s %-15.15s %-15.15s \n" #define FORMAT2 "%-25.25s %-15.15s %-15.15s \n" @@ -6484,19 +6437,22 @@ char iused[40]; int showall = 0; - if (argc < 3) + if (argc < 3) { return RESULT_SHOWUSAGE; + } + + if (argc == 4 && !strcmp(argv[3], "all")) { + showall = 1; + } - if (argc == 4 && !strcmp(argv[3],"all")) - showall = 1; - ast_cli(fd, FORMAT, "* User name", "In use", "Limit"); ASTOBJ_CONTAINER_TRAVERSE(&userl, 1, do { ASTOBJ_RDLOCK(iterator); - if (iterator->incominglimit) + if (iterator->incominglimit) { snprintf(ilimits, sizeof(ilimits), "%d", iterator->incominglimit); - else + } else { ast_copy_string(ilimits, "N/A", sizeof(ilimits)); + } /* Code disabled ---------------------------- if (iterator->outgoinglimit) snprintf(olimits, sizeof(olimits), "%d", iterator->outgoinglimit); @@ -6505,8 +6461,9 @@ snprintf(oused, sizeof(oused), "%d", iterator->outUse); ---------------------------------------------*/ snprintf(iused, sizeof(iused), "%d", iterator->inUse); - if (showall || iterator->incominglimit) + if (showall || iterator->incominglimit) { ast_cli(fd, FORMAT2, iterator->name, iused, ilimits); + } ASTOBJ_UNLOCK(iterator); } while (0) ); @@ -6514,10 +6471,11 @@ ASTOBJ_CONTAINER_TRAVERSE(&peerl, 1, do { ASTOBJ_RDLOCK(iterator); - if (iterator->incominglimit) + if (iterator->incominglimit) { snprintf(ilimits, sizeof(ilimits), "%d", iterator->incominglimit); - else + } else { ast_copy_string(ilimits, "N/A", sizeof(ilimits)); + } /* Code disabled ---------------------------- if (iterator->outgoinglimit) snprintf(olimits, sizeof(olimits), "%d", iterator->outgoinglimit); @@ -6539,7 +6497,7 @@ /*--- nat2str: Convert NAT setting to text string */ static char *nat2str(int nat) { - switch(nat) { + switch (nat) { case SIP_NAT_NEVER: return "No"; case SIP_NAT_ROUTE: @@ -6554,7 +6512,7 @@ } /*--- peer_status: Report Peer status in character string */ -/* returns 1 if peer is online, -1 if unmonitored */ +/* returns 1 if peer is online, -1 if unmonitored */ static int peer_status(struct sip_peer *peer, char *status, int statuslen) { int res = 0; @@ -6570,14 +6528,14 @@ } else { ast_copy_string(status, "UNKNOWN", statuslen); } - } else { + } else { ast_copy_string(status, "Unmonitored", statuslen); /* Checking if port is 0 */ res = -1; } return res; } - + /*--- sip_show_users: CLI Command 'SIP Show Users' ---*/ static int sip_show_users(int fd, int argc, char *argv[]) { @@ -6609,12 +6567,12 @@ continue; } - ast_cli(fd, FORMAT, iterator->name, - iterator->secret, - iterator->accountcode, - iterator->context, - iterator->ha ? "Yes" : "No", - nat2str(ast_test_flag(iterator, SIP_NAT))); + ast_cli(fd, FORMAT, iterator->name, + iterator->secret, + iterator->accountcode, + iterator->context, + iterator->ha ? "Yes" : "No", + nat2str(ast_test_flag(iterator, SIP_NAT))); ASTOBJ_UNLOCK(iterator); } while (0) ); @@ -6626,24 +6584,22 @@ #undef FORMAT } -static char mandescr_show_peers[] = +static char mandescr_show_peers[] = "Description: Lists SIP peers in text format with details on current status.\n" "Variables: \n" " ActionID: Action ID for this transaction. Will be returned.\n"; -static int _sip_show_peers(int fd, int *total, struct mansession *s, struct message *m, int argc, char *argv[]); - /*--- manager_sip_show_peers: Show SIP peers in the manager API ---*/ /* Inspired from chan_iax2 */ -static int manager_sip_show_peers( struct mansession *s, struct message *m ) +static int manager_sip_show_peers(struct mansession *s, struct message *m) { - char *id = astman_get_header(m,"ActionID"); + char *id = astman_get_header(m, "ActionID"); char *a[] = { "sip", "show", "peers" }; char idtext[256] = ""; int total = 0; if (id && !ast_strlen_zero(id)) - snprintf(idtext,256,"ActionID: %s\r\n",id); + snprintf(idtext, 256, "ActionID: %s\r\n", id); astman_send_ack(s, m, "Peer status list will follow"); /* List the peers in separate manager events */ @@ -6683,9 +6639,9 @@ char idtext[256] = ""; if (s) { /* Manager - get ActionID */ - id = astman_get_header(m,"ActionID"); + id = astman_get_header(m, "ActionID"); if (id && !ast_strlen_zero(id)) - snprintf(idtext,256,"ActionID: %s\r\n",id); + snprintf(idtext, 256, "ActionID: %s\r\n", id); } switch (argc) { @@ -6704,14 +6660,14 @@ if (!s) { /* Normal list */ ast_cli(fd, FORMAT2, "Name/username", "Host", "Dyn", "Nat", "ACL", "Mask", "Port", "Status"); - } - + } + ASTOBJ_CONTAINER_TRAVERSE(&peerl, 1, do { char nm[20] = ""; char status[20] = ""; char srch[2000]; char pstatus; - + ASTOBJ_RDLOCK(iterator); if (havepattern && regexec(®exbuf, iterator->name, 0, NULL, 0)) { @@ -6726,77 +6682,75 @@ ast_copy_string(name, iterator->name, sizeof(name)); pstatus = peer_status(iterator, status, sizeof(status)); - if (pstatus) + if (pstatus) { peers_online++; - else { - if (pstatus == 0) + } else { + if (pstatus == 0) { peers_offline++; - else { /* Unmonitored */ + } else { /* Unmonitored */ /* Checking if port is 0 */ - if ( ntohs(iterator->addr.sin_port) == 0 ) { + if (ntohs(iterator->addr.sin_port) == 0) { peers_offline++; } else { peers_online++; } } - } - + } + snprintf(srch, sizeof(srch), FORMAT, name, iterator->addr.sin_addr.s_addr ? ast_inet_ntoa(iabuf, sizeof(iabuf), iterator->addr.sin_addr) : "(Unspecified)", - ast_test_flag(iterator, SIP_DYNAMIC) ? " D " : " ", /* Dynamic or not? */ - (ast_test_flag(iterator, SIP_NAT) & SIP_NAT_ROUTE) ? " N " : " ", /* NAT=yes? */ - iterator->ha ? " A " : " ", /* permit/deny */ + ast_test_flag(iterator, SIP_DYNAMIC) ? " D " : " ", /* Dynamic or not? */ + (ast_test_flag(iterator, SIP_NAT) & SIP_NAT_ROUTE) ? " N " : " ", /* NAT=yes? */ + iterator->ha ? " A " : " ", /* permit/deny */ nm, ntohs(iterator->addr.sin_port), status); - if (!s) {/* Normal CLI list */ - ast_cli(fd, FORMAT, name, - iterator->addr.sin_addr.s_addr ? ast_inet_ntoa(iabuf, sizeof(iabuf), iterator->addr.sin_addr) : "(Unspecified)", - ast_test_flag(iterator, SIP_DYNAMIC) ? " D " : " ", /* Dynamic or not? */ - (ast_test_flag(iterator, SIP_NAT) & SIP_NAT_ROUTE) ? " N " : " ", /* NAT=yes? */ - iterator->ha ? " A " : " ", /* permit/deny */ - nm, - ntohs(iterator->addr.sin_port), status); - } else { /* Manager format */ + if (!s) { /* Normal CLI list */ + ast_cli(fd, FORMAT, name, + iterator->addr.sin_addr.s_addr ? ast_inet_ntoa(iabuf, sizeof(iabuf), iterator->addr.sin_addr) : "(Unspecified)", + ast_test_flag(iterator, SIP_DYNAMIC) ? " D " : " ", /* Dynamic or not? */ + (ast_test_flag(iterator, SIP_NAT) & SIP_NAT_ROUTE) ? " N " : " ", /* NAT=yes? */ + iterator->ha ? " A " : " ", /* permit/deny */ + nm, + ntohs(iterator->addr.sin_port), status); + } else { /* Manager format */ /* The names here need to be the same as other channels */ ast_mutex_lock(&s->lock); - ast_cli(fd, - "Event: PeerEntry\r\n%s" - "Channeltype: SIP\r\n" - "ObjectName: %s\r\n" - "ChanObjectType: peer\r\n" /* "peer" or "user" */ - "IPaddress: %s\r\n" - "IPport: %d\r\n" - "Dynamic: %s\r\n" - "Natsupport: %s\r\n" - "ACL: %s\r\n" - "Status: %s\r\n\r\n", - idtext, - iterator->name, - iterator->addr.sin_addr.s_addr ? ast_inet_ntoa(iabuf, sizeof(iabuf), iterator->addr.sin_addr) : "-none-", - ntohs(iterator->addr.sin_port), - ast_test_flag(iterator, SIP_DYNAMIC) ? "yes" : "no", /* Dynamic or not? */ - (ast_test_flag(iterator, SIP_NAT) & SIP_NAT_ROUTE) ? "yes" : "no", /* NAT=yes? */ - iterator->ha ? "yes" : "no", /* permit/deny */ - status); - + ast_cli(fd, + "Event: PeerEntry\r\n%s" + "Channeltype: SIP\r\n" + "ObjectName: %s\r\n" + "ChanObjectType: peer\r\n" /* "peer" or "user" */ + "IPaddress: %s\r\n" + "IPport: %d\r\n" + "Dynamic: %s\r\n" + "Natsupport: %s\r\n" + "ACL: %s\r\n" + "Status: %s\r\n\r\n", + idtext, + iterator->name, + iterator->addr.sin_addr.s_addr ? ast_inet_ntoa(iabuf, sizeof(iabuf), iterator->addr.sin_addr) : "-none-", + ntohs(iterator->addr.sin_port), + ast_test_flag(iterator, SIP_DYNAMIC) ? "yes" : "no", /* Dynamic or not? */ + (ast_test_flag(iterator, SIP_NAT) & SIP_NAT_ROUTE) ? "yes" : "no", /* NAT=yes? */ + iterator->ha ? "yes" : "no", /* permit/deny */ + status); ast_mutex_unlock(&s->lock); } ASTOBJ_UNLOCK(iterator); total_peers++; - } while(0) ); + } while (0) ); if (!s) { - ast_cli(fd,"%d sip peers [%d online , %d offline]\n",total_peers,peers_online,peers_offline); + ast_cli(fd, "%d sip peers [%d online , %d offline]\n", total_peers, peers_online, peers_offline); } - - if (havepattern) + if (havepattern) { regfree(®exbuf); - - if (total) + } + if (total) { *total = total_peers; - + } return RESULT_SUCCESS; #undef FORMAT @@ -6818,10 +6772,10 @@ return RESULT_SUCCESS; } /*--- print_group: Print call group and pickup group ---*/ -static void print_group(int fd, unsigned int group) +static void print_group(int fd, unsigned int group) { char buf[256]; - ast_cli(fd, "%s\n", ast_print_group(buf, sizeof(buf), group) ); + ast_cli(fd, "%s\n", ast_print_group(buf, sizeof(buf), group)); } /*--- dtmfmode2str: Convert DTMF mode to printable string ---*/ @@ -6998,24 +6952,22 @@ return RESULT_SUCCESS; } -static char mandescr_show_peer[] = +static char mandescr_show_peer[] = "Description: Show one SIP peer with details on current status.\n" " The XML format is under development, feedback welcome! /oej\n" "Variables: \n" " Peer: The peer name you want to check.\n" -" ActionID: Optional action ID for this AMI transaction.\n"; - -static int _sip_show_peer(int type, int fd, struct mansession *s, struct message *m, int argc, char *argv[]); +" ActionID: Optional action ID for this AMI transaction.\n"; /*--- manager_sip_show_peer: Show SIP peers in the manager API ---*/ -static int manager_sip_show_peer( struct mansession *s, struct message *m ) +static int manager_sip_show_peer(struct mansession *s, struct message *m) { - char *id = astman_get_header(m,"ActionID"); + char *id = astman_get_header(m, "ActionID"); char *a[4]; char *peer; int ret; - peer = astman_get_header(m,"Peer"); + peer = astman_get_header(m, "Peer"); if (!peer || ast_strlen_zero(peer)) { astman_send_error(s, m, "Peer: missing.\n"); return 0; @@ -7027,15 +6979,13 @@ a[3] = peer; if (id && !ast_strlen_zero(id)) - ast_cli(s->fd, "ActionID: %s\r\n",id); - ret = _sip_show_peer(1, s->fd, s, m, 4, a ); - ast_cli( s->fd, "\r\n\r\n" ); + ast_cli(s->fd, "ActionID: %s\r\n", id); + ret = _sip_show_peer(1, s->fd, s, m, 4, a); + ast_cli(s->fd, "\r\n\r\n"); ast_mutex_unlock(&s->lock); return ret; } - - /*--- sip_show_peer: Show one peer in detail ---*/ static int sip_show_peer(int fd, int argc, char *argv[]) { @@ -7059,7 +7009,7 @@ load_realtime = (argc == 5 && !strcmp(argv[4], "load")) ? 1 : 0; peer = find_peer(argv[3], NULL, load_realtime); - if (s) { /* Manager */ + if (s) { /* Manager */ if (peer) ast_cli(s->fd, "Response: Success\r\n"); else { @@ -7068,13 +7018,13 @@ return 0; } } - if (peer && type==0 ) { /* Normal listing */ - ast_cli(fd,"\n\n"); + if (peer && type == 0) { /* Normal listing */ + ast_cli(fd, "\n\n"); ast_cli(fd, " * Name : %s\n", peer->name); ast_cli(fd, " Secret : %s\n", ast_strlen_zero(peer->secret)?"":""); ast_cli(fd, " MD5Secret : %s\n", ast_strlen_zero(peer->md5secret)?"":""); auth = peer->auth; - while(auth) { + while (auth) { ast_cli(fd, " Realm-auth : Realm %-15.15s User %-10.20s ", auth->realm, auth->username); ast_cli(fd, "%s\n", !ast_strlen_zero(auth->secret)?"":(!ast_strlen_zero(auth->md5secret)?"" : "")); auth = auth->next; @@ -7117,7 +7067,7 @@ ast_cli(fd, " Def. Username: %s\n", peer->username); ast_cli(fd, " SIP Options : "); if (peer->sipoptions) { - for (x=0 ; (x < (sizeof(sip_options) / sizeof(sip_options[0]))); x++) { + for (x = 0 ; (x < (sizeof(sip_options) / sizeof(sip_options[0]))); x++) { if (peer->sipoptions & sip_options[x].id) ast_cli(fd, "%s ", sip_options[x].text); } @@ -7130,12 +7080,12 @@ ast_cli(fd, "%s\n", codec_buf); ast_cli(fd, " Codec Order : ("); pref = &peer->prefs; - for(x = 0; x < 32 ; x++) { - codec = ast_codec_pref_index(pref,x); + for (x = 0; x < 32 ; x++) { + codec = ast_codec_pref_index(pref, x); if (!codec) break; ast_cli(fd, "%s", ast_getformatname(codec)); - if (x < 31 && ast_codec_pref_index(pref, x+1)) + if (x < 31 && ast_codec_pref_index(pref, x + 1)) ast_cli(fd, "|"); } @@ -7145,18 +7095,19 @@ ast_cli(fd, " Status : "); peer_status(peer, status, sizeof(status)); - ast_cli(fd, "%s\n",status); - ast_cli(fd, " Useragent : %s\n", peer->useragent); - ast_cli(fd, " Reg. Contact : %s\n", peer->fullcontact); + ast_cli(fd, "%s\n", status); + ast_cli(fd, " Useragent : %s\n", peer->useragent); + ast_cli(fd, " Reg. Contact : %s\n", peer->fullcontact); if (peer->chanvars) { - ast_cli(fd, " Variables :\n"); - for (v = peer->chanvars ; v ; v = v->next) - ast_cli(fd, " %s = %s\n", v->name, v->value); + ast_cli(fd, " Variables :\n"); + for (v = peer->chanvars ; v ; v = v->next) { + ast_cli(fd, " %s = %s\n", v->name, v->value); + } } - ast_cli(fd,"\n"); - ASTOBJ_UNREF(peer,sip_destroy_peer); + ast_cli(fd, "\n"); + ASTOBJ_UNREF(peer, sip_destroy_peer); } else if (peer && type == 1) { /* manager listing */ - char *actionid = astman_get_header(m,"ActionID"); + char *actionid = astman_get_header(m, "ActionID"); ast_cli(fd, "Channeltype: SIP\r\n"); if (actionid) @@ -7185,7 +7136,7 @@ ast_cli(fd, "Outgoinglimit: %d\r\n", peer->outgoinglimit); ast_cli(fd, "Dynamic: %s\r\n", (ast_test_flag(peer, SIP_DYNAMIC)?"Y":"N")); ast_cli(fd, "Callerid: %s\r\n", ast_callerid_merge(cbuf, sizeof(cbuf), peer->cid_name, peer->cid_num, "")); - ast_cli(fd, "RegExpire: %ld seconds\r\n", ast_sched_when(sched,peer->expire)); + ast_cli(fd, "RegExpire: %ld seconds\r\n", ast_sched_when(sched, peer->expire)); ast_cli(fd, "RegExpiry: %d\r\n", peer->expiry); ast_cli(fd, "SIP-AuthInsecure: %s\r\n", insecure2str(ast_test_flag(peer, SIP_INSECURE_PORT), ast_test_flag(peer, SIP_INSECURE_INVITE))); ast_cli(fd, "SIP-NatSupport: %s\r\n", nat2str(ast_test_flag(peer, SIP_NAT))); @@ -7206,12 +7157,12 @@ ast_cli(fd, "%s\r\n", codec_buf); ast_cli(fd, "CodecOrder: "); pref = &peer->prefs; - for(x = 0; x < 32 ; x++) { - codec = ast_codec_pref_index(pref,x); + for (x = 0; x < 32 ; x++) { + codec = ast_codec_pref_index(pref, x); if (!codec) break; ast_cli(fd, "%s", ast_getformatname(codec)); - if (x < 31 && ast_codec_pref_index(pref,x+1)) + if (x < 31 && ast_codec_pref_index(pref, x+1)) ast_cli(fd, ","); } @@ -7219,20 +7170,20 @@ ast_cli(fd, "Status: "); peer_status(peer, status, sizeof(status)); ast_cli(fd, "%s\r\n", status); - ast_cli(fd, "SIP-Useragent: %s\r\n", peer->useragent); - ast_cli(fd, "Reg-Contact : %s\r\n", peer->fullcontact); + ast_cli(fd, "SIP-Useragent: %s\r\n", peer->useragent); + ast_cli(fd, "Reg-Contact : %s\r\n", peer->fullcontact); if (peer->chanvars) { for (v = peer->chanvars ; v ; v = v->next) { - ast_cli(fd, "ChanVariable:\n"); - ast_cli(fd, " %s,%s\r\n", v->name, v->value); + ast_cli(fd, "ChanVariable:\n"); + ast_cli(fd, " %s,%s\r\n", v->name, v->value); } } - ASTOBJ_UNREF(peer,sip_destroy_peer); + ASTOBJ_UNREF(peer, sip_destroy_peer); } else { - ast_cli(fd,"Peer %s not found.\n", argv[3]); - ast_cli(fd,"\n"); + ast_cli(fd, "Peer %s not found.\n", argv[3]); + ast_cli(fd, "\n"); } return RESULT_SUCCESS; @@ -7255,7 +7206,7 @@ user = find_user(argv[3], load_realtime); if (user) { - ast_cli(fd,"\n\n"); + ast_cli(fd, "\n\n"); ast_cli(fd, " * Name : %s\n", user->name); ast_cli(fd, " Secret : %s\n", ast_strlen_zero(user->secret)?"":""); ast_cli(fd, " MD5Secret : %s\n", ast_strlen_zero(user->md5secret)?"":""); @@ -7275,12 +7226,12 @@ ast_cli(fd, " ACL : %s\n", (user->ha?"Yes":"No")); ast_cli(fd, " Codec Order : ("); pref = &user->prefs; - for(x = 0; x < 32 ; x++) { - codec = ast_codec_pref_index(pref,x); + for (x = 0; x < 32 ; x++) { + codec = ast_codec_pref_index(pref, x); if (!codec) break; ast_cli(fd, "%s", ast_getformatname(codec)); - if (x < 31 && ast_codec_pref_index(pref,x+1)) + if (x < 31 && ast_codec_pref_index(pref, x+1)) ast_cli(fd, "|"); } @@ -7289,15 +7240,16 @@ ast_cli(fd, ")\n"); if (user->chanvars) { - ast_cli(fd, " Variables :\n"); - for (v = user->chanvars ; v ; v = v->next) - ast_cli(fd, " %s = %s\n", v->name, v->value); + ast_cli(fd, " Variables :\n"); + for (v = user->chanvars ; v ; v = v->next) { + ast_cli(fd, " %s = %s\n", v->name, v->value); + } } - ast_cli(fd,"\n"); - ASTOBJ_UNREF(user,sip_destroy_user); + ast_cli(fd, "\n"); + ASTOBJ_UNREF(user, sip_destroy_user); } else { - ast_cli(fd,"User %s not found.\n", argv[3]); - ast_cli(fd,"\n"); + ast_cli(fd, "User %s not found.\n", argv[3]); + ast_cli(fd, "\n"); } return RESULT_SUCCESS; @@ -7318,7 +7270,7 @@ snprintf(host, sizeof(host), "%s:%d", iterator->hostname, iterator->portno ? iterator->portno : DEFAULT_SIP_PORT); ast_cli(fd, FORMAT, host, iterator->username, iterator->refresh, regstate2str(iterator->regstate)); ASTOBJ_UNLOCK(iterator); - } while(0)); + } while (0)); return RESULT_SUCCESS; #undef FORMAT #undef FORMAT2 @@ -7328,22 +7280,22 @@ static int __sip_show_channels(int fd, int argc, char *argv[], int subscriptions); /*--- sip_show_channels: Show active SIP channels ---*/ -static int sip_show_channels(int fd, int argc, char *argv[]) +static int sip_show_channels(int fd, int argc, char *argv[]) { - return __sip_show_channels(fd, argc, argv, 0); + return __sip_show_channels(fd, argc, argv, 0); } - + /*--- sip_show_subscriptions: Show active SIP subscriptions ---*/ static int sip_show_subscriptions(int fd, int argc, char *argv[]) { - return __sip_show_channels(fd, argc, argv, 1); + return __sip_show_channels(fd, argc, argv, 1); } static int __sip_show_channels(int fd, int argc, char *argv[], int subscriptions) { #define FORMAT3 "%-15.15s %-10.10s %-21.21s %-15.15s\n" -#define FORMAT2 "%-15.15s %-10.10s %-11.11s %-11.11s %s %s\n" -#define FORMAT "%-15.15s %-10.10s %-11.11s %5.5d/%5.5d %-6.6s%s %s\n" +#define FORMAT2 "%-15.15s %-10.10s %-11.11s %-11.11s %s %s\n" +#define FORMAT "%-15.15s %-10.10s %-11.11s %5.5d/%5.5d %-6.6s%s %s\n" struct sip_pvt *cur; char iabuf[INET_ADDRSTRLEN]; int numchans = 0; @@ -7354,24 +7306,21 @@ if (!subscriptions) ast_cli(fd, FORMAT2, "Peer", "User/ANR", "Call ID", "Seq (Tx/Rx)", "Format", "Last Msg"); else - ast_cli(fd, FORMAT3, "Peer", "User", "Call ID", "URI"); + ast_cli(fd, FORMAT3, "Peer", "User", "Call ID", "URI"); while (cur) { if (!cur->subscribed && !subscriptions) { - ast_cli(fd, FORMAT, ast_inet_ntoa(iabuf, sizeof(iabuf), cur->sa.sin_addr), - ast_strlen_zero(cur->username) ? ( ast_strlen_zero(cur->cid_num) ? "(None)" : cur->cid_num ) : cur->username, - cur->callid, - cur->ocseq, cur->icseq, - ast_getformatname(cur->owner ? cur->owner->nativeformats : 0), - ast_test_flag(cur, SIP_NEEDDESTROY) ? "(d)" : "", - cur->lastmsg ); + ast_cli(fd, FORMAT, ast_inet_ntoa(iabuf, sizeof(iabuf), cur->sa.sin_addr), + ast_strlen_zero(cur->username) ? (ast_strlen_zero(cur->cid_num) ? "(None)" : cur->cid_num) : cur->username, + cur->callid, cur->ocseq, cur->icseq, + ast_getformatname(cur->owner ? cur->owner->nativeformats : 0), + ast_test_flag(cur, SIP_NEEDDESTROY) ? "(d)" : "", cur->lastmsg); numchans++; } if (cur->subscribed && subscriptions) { - ast_cli(fd, FORMAT3, ast_inet_ntoa(iabuf, sizeof(iabuf), cur->sa.sin_addr), - ast_strlen_zero(cur->username) ? ( ast_strlen_zero(cur->cid_num) ? "(None)" : cur->cid_num ) : cur->username, - cur->callid, cur->uri); - - } + ast_cli(fd, FORMAT3, ast_inet_ntoa(iabuf, sizeof(iabuf), cur->sa.sin_addr), + ast_strlen_zero(cur->username) ? (ast_strlen_zero(cur->cid_num) ? "(None)" : cur->cid_num) : cur->username, + cur->callid, cur->uri); + } cur = cur->next; } ast_mutex_unlock(&iflock); @@ -7388,13 +7337,13 @@ /*--- complete_sipch: Support routine for 'sip show channel' CLI ---*/ static char *complete_sipch(char *line, char *word, int pos, int state) { - int which=0; + int which = 0; struct sip_pvt *cur; char *c = NULL; ast_mutex_lock(&iflock); cur = iflist; - while(cur) { + while (cur) { if (!strncasecmp(word, cur->callid, strlen(word))) { if (++which > state) { c = strdup(cur->callid); @@ -7423,7 +7372,7 @@ result = strdup(iterator->name); } } - } while(0) ); + } while (0) ); return result; } @@ -7461,7 +7410,7 @@ result = strdup(iterator->name); } } - } while(0) ); + } while (0) ); return result; } @@ -7487,9 +7436,9 @@ if (!notify_types) return NULL; - + cat = ast_category_browse(notify_types, NULL); - while(cat) { + while (cat) { if (!strncasecmp(word, cat, strlen(word))) { if (++which > state) { c = strdup(cat); @@ -7537,9 +7486,9 @@ len = strlen(argv[3]); ast_mutex_lock(&iflock); cur = iflist; - while(cur) { - if (!strncasecmp(cur->callid, argv[3],len)) { - ast_cli(fd,"\n"); + while (cur) { + if (!strncasecmp(cur->callid, argv[3], len)) { + ast_cli(fd, "\n"); if (cur->subscribed) ast_cli(fd, " * Subscription\n"); else @@ -7550,7 +7499,7 @@ ast_cli(fd, " Non-Codec Capability: %d\n", cur->noncodeccapability); ast_cli(fd, " Their Codec Capability: %d\n", cur->peercapability); ast_cli(fd, " Joint Codec Capability: %d\n", cur->jointcapability); - ast_cli(fd, " Format %s\n", ast_getformatname(cur->owner ? cur->owner->nativeformats : 0) ); + ast_cli(fd, " Format %s\n", ast_getformatname(cur->owner ? cur->owner->nativeformats : 0)); ast_cli(fd, " Theoretical Address: %s:%d\n", ast_inet_ntoa(iabuf, sizeof(iabuf), cur->sa.sin_addr), ntohs(cur->sa.sin_port)); ast_cli(fd, " Received Address: %s:%d\n", ast_inet_ntoa(iabuf, sizeof(iabuf), cur->recv.sin_addr), ntohs(cur->recv.sin_port)); ast_cli(fd, " NAT Support: %s\n", nat2str(ast_test_flag(cur, SIP_NAT))); @@ -7570,10 +7519,10 @@ ast_cli(fd, " Promiscuous Redir: %s\n", ast_test_flag(cur, SIP_PROMISCREDIR) ? "Yes" : "No"); ast_cli(fd, " Route: %s\n", cur->route ? cur->route->hop : "N/A"); ast_cli(fd, " DTMF Mode: %s\n", dtmfmode2str(ast_test_flag(cur, SIP_DTMF))); - ast_cli(fd, " SIP Options : "); + ast_cli(fd, " SIP Options: "); if (cur->sipoptions) { int x; - for (x=0 ; (x < (sizeof(sip_options) / sizeof(sip_options[0]))); x++) { + for (x = 0 ; (x < (sizeof(sip_options) / sizeof(sip_options[0]))); x++) { if (cur->sipoptions & sip_options[x].id) ast_cli(fd, "%s ", sip_options[x].text); } @@ -7585,8 +7534,9 @@ cur = cur->next; } ast_mutex_unlock(&iflock); - if (!found) + if (!found) { ast_cli(fd, "No such SIP Call ID starting with '%s'\n", argv[3]); + } return RESULT_SUCCESS; } @@ -7606,16 +7556,16 @@ len = strlen(argv[3]); ast_mutex_lock(&iflock); cur = iflist; - while(cur) { - if (!strncasecmp(cur->callid, argv[3],len)) { - ast_cli(fd,"\n"); + while (cur) { + if (!strncasecmp(cur->callid, argv[3], len)) { + ast_cli(fd, "\n"); if (cur->subscribed) ast_cli(fd, " * Subscription\n"); else ast_cli(fd, " * SIP Call\n"); x = 0; hist = cur->history; - while(hist) { + while (hist) { x++; ast_cli(fd, "%d. %s\n", x, hist->event); hist = hist->next; @@ -7627,12 +7577,12 @@ cur = cur->next; } ast_mutex_unlock(&iflock); - if (!found) + if (!found) { ast_cli(fd, "No such SIP Call ID starting with '%s'\n", argv[3]); + } return RESULT_SUCCESS; } - /*--- handle_request_info: Receive SIP INFO Message ---*/ /* Doesn't read the duration of the DTMF signal */ static void handle_request_info(struct sip_pvt *p, struct sip_request *req) @@ -7642,7 +7592,7 @@ char resp = 0; struct ast_frame f; char *c; - + /* Need to check the media/type */ if (!strcasecmp(get_header(req, "Content-Type"), "application/dtmf-relay") || !strcasecmp(get_header(req, "Content-Type"), "application/vnd.nortelnetworks.digits")) { @@ -7655,7 +7605,7 @@ } else { ast_copy_string(buf, c, sizeof(buf)); } - + if (p->owner) { /* PBX call */ if (!ast_strlen_zero(buf)) { if (sipdebug) @@ -7764,7 +7714,7 @@ sipdebug = 1; } else ast_cli(fd, "Unable to get IP address of peer '%s'\n", argv[3]); - ASTOBJ_UNREF(peer,sip_destroy_peer); + ASTOBJ_UNREF(peer, sip_destroy_peer); } else ast_cli(fd, "No such peer '%s'\n", argv[3]); return RESULT_SUCCESS; @@ -7775,13 +7725,15 @@ { int oldsipdebug = sipdebug; if (argc != 2) { - if (argc != 4) + if (argc != 4) { return RESULT_SHOWUSAGE; - else if (strncmp(argv[2], "ip\0", 3) == 0) + } else if (strncmp(argv[2], "ip\0", 3) == 0) { return sip_do_debug_ip(fd, argc, argv); - else if (strncmp(argv[2], "peer\0", 5) == 0) + } else if (strncmp(argv[2], "peer\0", 5) == 0) { return sip_do_debug_peer(fd, argc, argv); - else return RESULT_SHOWUSAGE; + } else { + return RESULT_SHOWUSAGE; + } } sipdebug = 1; memset(&debugaddr, 0, sizeof(debugaddr)); @@ -7882,44 +7834,44 @@ return RESULT_SUCCESS; } -static int reply_digest(struct sip_pvt *p, struct sip_request *req, char *header, int sipmethod, char *digest, int digest_len); - /*--- do_register_auth: Authenticate for outbound registration ---*/ -static int do_register_auth(struct sip_pvt *p, struct sip_request *req, char *header, char *respheader) +static int do_register_auth(struct sip_pvt *p, struct sip_request *req, char *header, char *respheader) { char digest[1024]; p->authtries++; - memset(digest,0,sizeof(digest)); + memset(digest, 0, sizeof(digest)); if (reply_digest(p, req, header, SIP_REGISTER, digest, sizeof(digest))) { - /* There's nothing to use for authentication */ - /* No digest challenge in request */ - if (sip_debug_test_pvt(p) && p->registry) - ast_verbose("No authentication challenge, sending blank registration to domain/host name %s\n", p->registry->hostname); - /* No old challenge */ + /* There's nothing to use for authentication + * No digest challenge in request */ + if (sip_debug_test_pvt(p) && p->registry) { + ast_verbose("No authentication challenge, sending blank registration to domain/host name %s\n", p->registry->hostname); + /* No old challenge */ + } return -1; } - if (sip_debug_test_pvt(p) && p->registry) - ast_verbose("Responding to challenge, registration to domain/host name %s\n", p->registry->hostname); - return transmit_register(p->registry, SIP_REGISTER, digest, respheader); + if (sip_debug_test_pvt(p) && p->registry) { + ast_verbose("Responding to challenge, registration to domain/host name %s\n", p->registry->hostname); + } + return transmit_register(p->registry, SIP_REGISTER, digest, respheader); } /*--- do_proxy_auth: Add authentication on outbound SIP packet ---*/ -static int do_proxy_auth(struct sip_pvt *p, struct sip_request *req, char *header, char *respheader, int sipmethod, int init) +static int do_proxy_auth(struct sip_pvt *p, struct sip_request *req, char *header, char *respheader, int sipmethod, int init) { char digest[1024]; struct sip_invite_param options; memset(&options, 0, sizeof(struct sip_invite_param)); p->authtries++; - memset(digest,0,sizeof(digest)); - if (reply_digest(p, req, header, sipmethod, digest, sizeof(digest) )) { + memset(digest, 0, sizeof(digest)); + if (reply_digest(p, req, header, sipmethod, digest, sizeof(digest))) { /* No way to authenticate */ return -1; } /* Now we have a reply digest */ options.auth = digest; options.authheader = respheader; - return transmit_invite(p, sipmethod, sipmethod == SIP_INVITE, &options, init); + return transmit_invite(p, sipmethod, sipmethod == SIP_INVITE, &options, init); } /*--- reply_digest: reply to authentication for outbound registrations ---*/ @@ -7946,8 +7898,9 @@ }; ast_copy_string(tmp, get_header(req, header), sizeof(tmp)); - if (ast_strlen_zero(tmp)) + if (ast_strlen_zero(tmp)) { return -1; + } if (strncasecmp(tmp, "Digest ", strlen("Digest "))) { ast_log(LOG_WARNING, "missing Digest.\n"); return -1; @@ -7987,13 +7940,13 @@ ast_copy_string(r->opaque, p->opaque, sizeof(r->opaque)); ast_copy_string(r->qop, p->qop, sizeof(r->qop)); } - build_reply_digest(p, sipmethod, digest, digest_len); + build_reply_digest(p, sipmethod, digest, digest_len); return 0; } /*--- build_reply_digest: Build reply digest ---*/ -/* Build digest challenge for authentication of peers (for registration) - and users (for calls). Also used for authentication of CANCEL and BYE */ +/* Build digest challenge for authentication of peers (for registration) and + * users (for calls). Also used for authentication of CANCEL and BYE */ static int build_reply_digest(struct sip_pvt *p, int method, char* digest, int digest_len) { char a1[256]; @@ -8015,39 +7968,39 @@ else if (!ast_strlen_zero(p->uri)) ast_copy_string(uri, p->uri, sizeof(uri)); else - snprintf(uri, sizeof(uri), "sip:%s@%s",p->username, ast_inet_ntoa(iabuf, sizeof(iabuf), p->sa.sin_addr)); + snprintf(uri, sizeof(uri), "sip:%s@%s", p->username, ast_inet_ntoa(iabuf, sizeof(iabuf), p->sa.sin_addr)); snprintf(cnonce, sizeof(cnonce), "%08x", rand()); - /* Check if we have separate auth credentials */ - if ((auth = find_realm_authentication(authl, p->realm))) { - username = auth->username; - secret = auth->secret; - md5secret = auth->md5secret; - ast_log(LOG_NOTICE,"Using realm %s authentication for this call\n", p->realm); - } else { - /* No authentication, use peer or register= config */ - username = p->authname; - secret = p->peersecret; - md5secret = p->peermd5secret; - } - - - /* Calculate SIP digest response */ - snprintf(a1,sizeof(a1),"%s:%s:%s",username,p->realm,secret); - snprintf(a2,sizeof(a2),"%s:%s", sip_methods[method].text, uri); + /* Check if we have separate auth credentials */ + if ((auth = find_realm_authentication(authl, p->realm))) { + username = auth->username; + secret = auth->secret; + md5secret = auth->md5secret; + ast_log(LOG_NOTICE, "Using realm %s authentication for this call\n", p->realm); + } else { + /* No authentication, use peer or register= config */ + username = p->authname; + secret = p->peersecret; + md5secret = p->peermd5secret; + } + + /* Calculate SIP digest response */ + snprintf(a1, sizeof(a1), "%s:%s:%s", username, p->realm, secret); + snprintf(a2, sizeof(a2), "%s:%s", sip_methods[method].text, uri); if (!ast_strlen_zero(md5secret)) ast_copy_string(a1_hash, md5secret, sizeof(a1_hash)); else - ast_md5_hash(a1_hash,a1); - ast_md5_hash(a2_hash,a2); - /* XXX We hard code the nonce-number to 1... What are the odds? Are we seriously going to keep - track of every nonce we've seen? Also we hard code to "auth"... XXX */ + ast_md5_hash(a1_hash, a1); + ast_md5_hash(a2_hash, a2); + /* XXX We hard code the nonce-number to 1... What are the odds? Are we + * seriously going to keep track of every nonce we've seen? Also we hard + * code to "auth"... XXX */ if (!ast_strlen_zero(p->qop)) - snprintf(resp,sizeof(resp),"%s:%s:%s:%s:%s:%s",a1_hash,p->nonce, "00000001", cnonce, "auth", a2_hash); + snprintf(resp, sizeof(resp), "%s:%s:%s:%s:%s:%s", a1_hash, p->nonce, "00000001", cnonce, "auth", a2_hash); else - snprintf(resp,sizeof(resp),"%s:%s:%s",a1_hash,p->nonce,a2_hash); - ast_md5_hash(resp_hash,resp); + snprintf(resp, sizeof(resp), "%s:%s:%s", a1_hash, p->nonce, a2_hash); + ast_md5_hash(resp_hash, resp); /* XXX We hard code our qop to "auth" for now. XXX */ if (!ast_strlen_zero(p->qop)) snprintf(digest, digest_len, "Digest username=\"%s\", realm=\"%s\", algorithm=MD5, uri=\"%s\", nonce=\"%s\", response=\"%s\", opaque=\"%s\", qop=auth, cnonce=\"%s\", nc=00000001", username, p->realm, uri, p->nonce, resp_hash, p->opaque, cnonce); @@ -8056,15 +8009,13 @@ return 0; } - - static char notify_usage[] = "Usage: sip notify [...]\n" " Send a NOTIFY message to a SIP peer or peers\n" " Message types are defined in sip_notify.conf\n"; -static char show_users_usage[] = +static char show_users_usage[] = "Usage: sip show users [like ]\n" " Lists all known SIP users.\n" " Optional regular expression pattern is used to filter the user list.\n"; @@ -8074,24 +8025,24 @@ " Lists all details on one SIP user and the current status.\n" " Option \"load\" forces lookup of peer in realtime storage.\n"; -static char show_inuse_usage[] = +static char show_inuse_usage[] = "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"; -static char show_channels_usage[] = +static char show_channels_usage[] = "Usage: sip show channels\n" " Lists all currently active SIP channels.\n"; -static char show_channel_usage[] = +static char show_channel_usage[] = "Usage: sip show channel \n" " Provides detailed status on a given SIP channel.\n"; -static char show_history_usage[] = +static char show_history_usage[] = "Usage: sip show history \n" " Provides detailed dialog history on a given SIP channel.\n"; -static char show_peers_usage[] = +static char show_peers_usage[] = "Usage: sip show peers [like ]\n" " Lists all known SIP peers.\n" " Optional regular expression pattern is used to filter the peer list.\n"; @@ -8110,7 +8061,7 @@ "Usage: sip show registry\n" " Lists all registration requests and status.\n"; -static char debug_usage[] = +static char debug_usage[] = "Usage: sip debug\n" " Enables dumping of SIP packets for debugging purposes\n\n" " sip debug ip \n" @@ -8119,15 +8070,15 @@ " Enables dumping of SIP packets to and from host.\n" " Require peer to be registered.\n"; -static char no_debug_usage[] = +static char no_debug_usage[] = "Usage: sip no debug\n" " Disables dumping of SIP packets for debugging purposes\n"; -static char no_history_usage[] = +static char no_history_usage[] = "Usage: sip no history\n" " Disables recording of SIP dialog history for debugging purposes\n"; -static char history_usage[] = +static char history_usage[] = "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"; @@ -8137,21 +8088,20 @@ " Reloads SIP configuration from sip.conf\n"; static char show_subscriptions_usage[] = -"Usage: sip show subscriptions\n" +"Usage: sip show subscriptions\n" " Shows active SIP subscriptions for extension states\n"; static char show_objects_usage[] = -"Usage: sip show objects\n" +"Usage: sip show objects\n" " Shows status of known SIP objects\n"; - /*--- func_header_read: Read SIP header (dialplan function) */ -static char *func_header_read(struct ast_channel *chan, char *cmd, char *data, char *buf, size_t len) +static char *func_header_read(struct ast_channel *chan, char *cmd, char *data, char *buf, size_t len) { struct sip_pvt *p; char *content; - - if (!data) { + + if (!data) { ast_log(LOG_WARNING, "This function requires a header name.\n"); return NULL; } @@ -8184,7 +8134,6 @@ return buf; } - static struct ast_custom_function sip_header_function = { .name = "SIP_HEADER", .synopsis = "Gets or sets the specified SIP header", @@ -8245,7 +8194,7 @@ } else if (!strncasecmp(colname, "codec[", 6)) { char *codecnum, *ptr; int index = 0, codec = 0; - + codecnum = strchr(colname, '['); *codecnum = '\0'; codecnum++; @@ -8253,7 +8202,7 @@ *ptr = '\0'; } index = atoi(codecnum); - if((codec = ast_codec_pref_index(&peer->prefs, index))) { + if ((codec = ast_codec_pref_index(&peer->prefs, index))) { ast_copy_string(buf, ast_getformatname(codec), len); } } @@ -8330,13 +8279,13 @@ /* Go ahead and send bye at this point */ if (ast_test_flag(p, SIP_PENDINGBYE)) { transmit_request_with_auth(p, SIP_BYE, 0, 1, 1); - ast_set_flag(p, SIP_NEEDDESTROY); - ast_clear_flag(p, SIP_NEEDREINVITE); + ast_set_flag(p, SIP_NEEDDESTROY); + ast_clear_flag(p, SIP_NEEDREINVITE); } else if (ast_test_flag(p, SIP_NEEDREINVITE)) { ast_log(LOG_DEBUG, "Sending pending reinvite on '%s'\n", p->callid); /* Didn't get to reinvite yet, so do it now */ transmit_reinvite_with_sdp(p); - ast_clear_flag(p, SIP_NEEDREINVITE); + ast_clear_flag(p, SIP_NEEDREINVITE); } } @@ -8344,50 +8293,49 @@ static int handle_response_register(struct sip_pvt *p, int resp, char *rest, struct sip_request *req, int ignore, int seqno) { int expires, expires_ms; - struct sip_registry *r; - r=p->registry; + struct sip_registry *r = p->registry; switch (resp) { case 401: /* Unauthorized */ if ((p->authtries > 1) || do_register_auth(p, req, "WWW-Authenticate", "Authorization")) { ast_log(LOG_NOTICE, "Failed to authenticate on REGISTER to '%s@%s' (Tries %d)\n", p->registry->username, p->registry->hostname, p->authtries); - ast_set_flag(p, SIP_NEEDDESTROY); + ast_set_flag(p, SIP_NEEDDESTROY); } break; case 403: /* Forbidden */ ast_log(LOG_WARNING, "Forbidden - wrong password on authentication for REGISTER for '%s' to '%s'\n", p->registry->username, p->registry->hostname); p->registry->regattempts = global_regattempts_max+1; ast_sched_del(sched, r->timeout); - ast_set_flag(p, SIP_NEEDDESTROY); + ast_set_flag(p, SIP_NEEDDESTROY); break; case 404: /* Not found */ - ast_log(LOG_WARNING, "Got 404 Not found on SIP register to service %s@%s, giving up\n", p->registry->username,p->registry->hostname); + ast_log(LOG_WARNING, "Got 404 Not found on SIP register to service %s@%s, giving up\n", p->registry->username, p->registry->hostname); p->registry->regattempts = global_regattempts_max+1; - ast_set_flag(p, SIP_NEEDDESTROY); + ast_set_flag(p, SIP_NEEDDESTROY); r->call = NULL; ast_sched_del(sched, r->timeout); break; case 407: /* Proxy auth */ if ((p->authtries > 1) || do_register_auth(p, req, "Proxy-Authenticate", "Proxy-Authorization")) { ast_log(LOG_NOTICE, "Failed to authenticate on REGISTER to '%s' (tries '%d')\n", get_header(&p->initreq, "From"), p->authtries); - ast_set_flag(p, SIP_NEEDDESTROY); + ast_set_flag(p, SIP_NEEDDESTROY); } break; case 479: /* SER: Not able to process the URI - address is wrong in register*/ - ast_log(LOG_WARNING, "Got error 479 on register to %s@%s, giving up (check config)\n", p->registry->username,p->registry->hostname); + ast_log(LOG_WARNING, "Got error 479 on register to %s@%s, giving up (check config)\n", p->registry->username, p->registry->hostname); p->registry->regattempts = global_regattempts_max+1; - ast_set_flag(p, SIP_NEEDDESTROY); + ast_set_flag(p, SIP_NEEDDESTROY); r->call = NULL; ast_sched_del(sched, r->timeout); break; case 200: /* 200 OK */ if (!r) { ast_log(LOG_WARNING, "Got 200 OK on REGISTER that isn't a register\n"); - ast_set_flag(p, SIP_NEEDDESTROY); + ast_set_flag(p, SIP_NEEDDESTROY); return 0; } - r->regstate=REG_STATE_REGISTERED; + r->regstate = REG_STATE_REGISTERED; manager_event(EVENT_FLAG_SYSTEM, "Registry", "Channel: SIP\r\nDomain: %s\r\nStatus: %s\r\n", r->hostname, regstate2str(r->regstate)); r->regattempts = 0; ast_log(LOG_DEBUG, "Registration successful\n"); @@ -8395,7 +8343,7 @@ ast_log(LOG_DEBUG, "Cancelling timeout %d\n", r->timeout); ast_sched_del(sched, r->timeout); } - r->timeout=-1; + r->timeout = -1; r->call = NULL; p->registry = NULL; /* Let this one hang around until we have all the responses */ @@ -8406,19 +8354,19 @@ /* figure out how long we got registered for */ if (r->expire > -1) ast_sched_del(sched, r->expire); - /* according to section 6.13 of RFC, contact headers override - expires headers, so check those first */ + /* according to section 6.13 of RFC, contact headers override expires + * headers, so check those first */ expires = 0; if (!ast_strlen_zero(get_header(req, "Contact"))) { char *contact = NULL; char *tmptmp = NULL; int start = 0; - for(;;) { + for (;;) { contact = __get_header(req, "Contact", &start); /* this loop ensures we get a contact header about our register request */ - if(!ast_strlen_zero(contact)) { - if( (tmptmp=strstr(contact, p->our_contact))) { - contact=tmptmp; + if (!ast_strlen_zero(contact)) { + if ((tmptmp = strstr(contact, p->our_contact))) { + contact = tmptmp; break; } } else @@ -8430,23 +8378,24 @@ expires = 0; } } - if (!expires) - expires=atoi(get_header(req, "expires")); - if (!expires) - expires=default_expiry; - + if (!expires) { + expires = atoi(get_header(req, "expires")); + expires = default_expiry; + } expires_ms = expires * 1000; - if (expires <= EXPIRY_GUARD_LIMIT) - expires_ms -= MAX((expires_ms * EXPIRY_GUARD_PCT),EXPIRY_GUARD_MIN); - else + if (expires <= EXPIRY_GUARD_LIMIT) { + expires_ms -= MAX((expires_ms * EXPIRY_GUARD_PCT), EXPIRY_GUARD_MIN); + } else { expires_ms -= EXPIRY_GUARD_SECS * 1000; - if (sipdebug) - ast_log(LOG_NOTICE, "Outbound Registration: Expiry for %s is %d sec (Scheduling reregistration in %d ms)\n", r->hostname, expires, expires_ms); + } + if (sipdebug) { + ast_log(LOG_NOTICE, "Outbound Registration: Expiry for %s is %d sec (Scheduling reregistration in %d ms)\n", r->hostname, expires, expires_ms); + } r->refresh= (int) expires_ms / 1000; /* Schedule re-registration before we expire */ - r->expire=ast_sched_add(sched, expires_ms, sip_reregister, r); + r->expire = ast_sched_add(sched, expires_ms, sip_reregister, r); ASTOBJ_UNREF(r, sip_registry_destroy); } return 1; @@ -8496,7 +8445,7 @@ ast_sched_del(sched, peer->pokeexpire); if (sipmethod == SIP_INVITE) /* Does this really happen? */ transmit_request(p, SIP_ACK, seqno, 0, 0); - ast_set_flag(p, SIP_NEEDDESTROY); + ast_set_flag(p, SIP_NEEDDESTROY); /* Try again eventually */ if ((peer->lastms < 0) || (peer->lastms > peer->maxms)) @@ -8519,15 +8468,17 @@ c = get_header(req, "Cseq"); msg = strchr(c, ' '); - if (!msg) + if (!msg) { msg = ""; - else + } else { msg++; + } sipmethod = find_sip_method(msg); owner = p->owner; - if (owner) + if (owner) { owner->hangupcause = hangup_sip2cause(resp); + } /* Acknowledge whatever it is destined for */ if ((resp >= 100) && (resp <= 199)) @@ -8548,10 +8499,9 @@ } } if (p->peerpoke) { - /* We don't really care what the response is, just that it replied back. - Well, as long as it's not a 100 response... since we might - need to hang around for something more "definitive" */ - + /* We don't really care what the response is, just that it replied back. + * Well, as long as it's not a 100 response... since we might need to + * hang around for something more "definitive". */ res = handle_response_peerpoke(p, resp, rest, req, ignore, seqno, sipmethod); } else if (ast_test_flag(p, SIP_OUTGOING)) { /* Acknowledge sequence number */ @@ -8560,7 +8510,7 @@ ast_sched_del(sched, p->initid); p->initid = -1; } - switch(resp) { + switch (resp) { case 100: /* 100 Trying */ if (sipmethod == SIP_INVITE) { sip_cancel_destroy(p); @@ -8590,7 +8540,7 @@ case 200: /* 200 OK */ if (sipmethod == SIP_MESSAGE) { /* We successfully transmitted a message */ - ast_set_flag(p, SIP_NEEDDESTROY); + ast_set_flag(p, SIP_NEEDDESTROY); } else if (sipmethod == SIP_NOTIFY) { /* They got the notify, this is the end */ if (p->owner) { @@ -8598,7 +8548,7 @@ ast_queue_hangup(p->owner); } else { if (!p->subscribed) { - ast_set_flag(p, SIP_NEEDDESTROY); + ast_set_flag(p, SIP_NEEDDESTROY); } } } else if (sipmethod == SIP_INVITE) { @@ -8615,7 +8565,7 @@ build_route(p, req, 1); if (p->owner) { if (p->owner->_state != AST_STATE_UP) { -#ifdef OSP_SUPPORT +#ifdef OSP_SUPPORT time(&p->ospstart); #endif ast_queue_control(p->owner, AST_CONTROL_ANSWER); @@ -8623,11 +8573,14 @@ struct ast_frame af = { AST_FRAME_NULL, }; ast_queue_frame(p->owner, &af); } - } else /* It's possible we're getting an ACK after we've tried to disconnect - by sending CANCEL */ - ast_set_flag(p, SIP_PENDINGBYE); + } else { + /* It's possible we're getting an ACK after we've tried to + * disconnect by sending CANCEL */ + ast_set_flag(p, SIP_PENDINGBYE); + } p->authtries = 0; - /* If I understand this right, the branch is different for a non-200 ACK only */ + /* If I understand this right, the branch is different for a + * non-200 ACK only */ transmit_request(p, SIP_ACK, seqno, 0, 1); check_pendings(p); } else if (sipmethod == SIP_REGISTER) { @@ -8639,16 +8592,16 @@ /* First we ACK */ transmit_request(p, SIP_ACK, seqno, 0, 0); /* Then we AUTH */ - p->theirtag[0]='\0'; /* forget their old tag, so we don't match tags when getting response */ + p->theirtag[0] = '\0'; /* forget their old tag, so we don't match tags when getting response */ if ((p->authtries > 1) || do_proxy_auth(p, req, "WWW-Authenticate", "Authorization", SIP_INVITE, 1)) { ast_log(LOG_NOTICE, "Failed to authenticate on INVITE to '%s'\n", get_header(&p->initreq, "From")); - ast_set_flag(p, SIP_NEEDDESTROY); + ast_set_flag(p, SIP_NEEDDESTROY); } } else if (p->registry && sipmethod == SIP_REGISTER) { res = handle_response_register(p, resp, rest, req, ignore, seqno); } else { ast_log(LOG_WARNING, "Got authentication request (401) on unknown %s to '%s'\n", sip_methods[sipmethod].text, get_header(req, "To")); - ast_set_flag(p, SIP_NEEDDESTROY); + ast_set_flag(p, SIP_NEEDDESTROY); } break; case 403: /* Forbidden - we failed authentication */ @@ -8658,7 +8611,7 @@ ast_log(LOG_WARNING, "Forbidden - wrong password on authentication for INVITE to '%s'\n", get_header(&p->initreq, "From")); if (owner) ast_queue_control(p->owner, AST_CONTROL_CONGESTION); - ast_set_flag(p, SIP_NEEDDESTROY); + ast_set_flag(p, SIP_NEEDDESTROY); } else if (p->registry && sipmethod == SIP_REGISTER) { res = handle_response_register(p, resp, rest, req, ignore, seqno); } else { @@ -8678,25 +8631,25 @@ /* Then we AUTH */ /* But only if the packet wasn't marked as ignore in handle_request */ if (!ignore){ - p->theirtag[0]='\0'; /* forget their old tag, so we don't match tags when getting response */ + p->theirtag[0] = '\0'; /* forget their old tag, so we don't match tags when getting response */ if ((p->authtries > 1) || do_proxy_auth(p, req, "Proxy-Authenticate", "Proxy-Authorization", SIP_INVITE, 1)) { ast_log(LOG_NOTICE, "Failed to authenticate on INVITE to '%s'\n", get_header(&p->initreq, "From")); - ast_set_flag(p, SIP_NEEDDESTROY); + ast_set_flag(p, SIP_NEEDDESTROY); } } } else if (sipmethod == SIP_BYE || sipmethod == SIP_REFER) { if (ast_strlen_zero(p->authname)) ast_log(LOG_WARNING, "Asked to authenticate %s, to %s:%d but we have no matching peer!\n", msg, ast_inet_ntoa(iabuf, sizeof(iabuf), p->recv.sin_addr), ntohs(p->recv.sin_port)); - ast_set_flag(p, SIP_NEEDDESTROY); + ast_set_flag(p, SIP_NEEDDESTROY); if ((p->authtries > 1) || do_proxy_auth(p, req, "Proxy-Authenticate", "Proxy-Authorization", sipmethod, 0)) { ast_log(LOG_NOTICE, "Failed to authenticate on %s to '%s'\n", msg, get_header(&p->initreq, "From")); - ast_set_flag(p, SIP_NEEDDESTROY); + ast_set_flag(p, SIP_NEEDDESTROY); } } else if (p->registry && sipmethod == SIP_REGISTER) { res = handle_response_register(p, resp, rest, req, ignore, seqno); } else - ast_set_flag(p, SIP_NEEDDESTROY); + ast_set_flag(p, SIP_NEEDDESTROY); break; case 501: /* Not Implemented */ @@ -8710,7 +8663,7 @@ if ((resp >= 300) && (resp < 700)) { if ((option_verbose > 2) && (resp != 487)) 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)); - ast_set_flag(p, SIP_ALREADYGONE); + ast_set_flag(p, SIP_ALREADYGONE); if (p->rtp) { /* Immediately stop RTP */ ast_rtp_stop(p->rtp); @@ -8720,7 +8673,7 @@ ast_rtp_stop(p->vrtp); } /* XXX Locking issues?? XXX */ - switch(resp) { + switch (resp) { case 300: /* Multiple Choices */ case 301: /* Moved permenantly */ case 302: /* Moved temporarily */ @@ -8738,10 +8691,11 @@ update_user_counter(p, DEC_IN_USE); } break; - case 482: /* SIP is incapable of performing a hairpin call, which - is yet another failure of not having a layer 2 (again, YAY - IETF for thinking ahead). So we treat this as a call - forward and hope we end up at the right place... */ + case 482: /* SIP is incapable of performing a hairpin call, + * which is yet another failure of not having a layer 2 + * (again, YAY IETF for thinking ahead). So we treat + * this as a call forward and hope we end up at the + * right place... */ ast_log(LOG_DEBUG, "Hairpin detected, setting up call forward for what it's worth\n"); if (p->owner) snprintf(p->owner->call_forward, sizeof(p->owner->call_forward), "Local/%s@%s", p->username, p->context); @@ -8762,17 +8716,19 @@ ast_queue_control(p->owner, AST_CONTROL_CONGESTION); break; default: - /* Send hangup */ + /* Send hangup */ if (owner) ast_queue_hangup(p->owner); break; } /* ACK on invite */ - if (sipmethod == SIP_INVITE) + if (sipmethod == SIP_INVITE) { transmit_request(p, SIP_ACK, seqno, 0, 0); - ast_set_flag(p, SIP_ALREADYGONE); - if (!p->owner) - ast_set_flag(p, SIP_NEEDDESTROY); + } + ast_set_flag(p, SIP_ALREADYGONE); + if (!p->owner) { + ast_set_flag(p, SIP_NEEDDESTROY); + } } else if ((resp >= 100) && (resp < 200)) { if (sipmethod == SIP_INVITE) { sip_cancel_destroy(p); @@ -8786,19 +8742,20 @@ } else 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)); } - } else { - /* Responses to OUTGOING SIP requests on INCOMING calls - get handled here. As well as out-of-call message responses */ - if (sip_debug_test_pvt(p)) + } else { + /* Responses to OUTGOING SIP requests on INCOMING calls + * get handled here. As well as out-of-call message responses */ + if (sip_debug_test_pvt(p)) { ast_verbose("Response message %s arrived\n", msg); - switch(resp) { + } + switch (resp) { case 200: /* Change branch since this is a 200 response */ if (sipmethod == SIP_INVITE) transmit_request(p, SIP_ACK, seqno, 0, 1); else if (sipmethod == SIP_MESSAGE) /* We successfully transmitted a message */ - ast_set_flag(p, SIP_NEEDDESTROY); + ast_set_flag(p, SIP_NEEDDESTROY); break; case 407: if (sipmethod == SIP_BYE || sipmethod == SIP_REFER) { @@ -8807,7 +8764,7 @@ msg, ast_inet_ntoa(iabuf, sizeof(iabuf), p->recv.sin_addr), ntohs(p->recv.sin_port)); if ((p->authtries > 1) || do_proxy_auth(p, req, "Proxy-Authenticate", "Proxy-Authorization", sipmethod, 0)) { ast_log(LOG_NOTICE, "Failed to authenticate on %s to '%s'\n", msg, get_header(&p->initreq, "From")); - ast_set_flag(p, SIP_NEEDDESTROY); + ast_set_flag(p, SIP_NEEDDESTROY); } } break; @@ -8868,10 +8825,10 @@ ast_copy_string(chan1m->context, chan1->context, sizeof(chan1m->context)); ast_copy_string(chan1m->exten, chan1->exten, sizeof(chan1m->exten)); chan1m->priority = chan1->priority; - - /* We make a clone of the peer channel too, so we can play - back the announcement */ - snprintf(chan2m->name, sizeof (chan2m->name), "SIPPeer/%s",chan2->name); + + /* We make a clone of the peer channel too, so we can play back the + * announcement */ + snprintf(chan2m->name, sizeof (chan2m->name), "SIPPeer/%s", chan2->name); /* Make formats okay */ chan2m->readformat = chan2->readformat; chan2m->writeformat = chan2->writeformat; @@ -8903,7 +8860,7 @@ } /*--- ast_quiet_chan: Turn off generator data */ -static void ast_quiet_chan(struct ast_channel *chan) +static void ast_quiet_chan(struct ast_channel *chan) { if (chan && chan->_state == AST_STATE_UP) { if (chan->generatordata) @@ -8915,7 +8872,7 @@ static int attempt_transfer(struct sip_pvt *p1, struct sip_pvt *p2) { int res = 0; - struct ast_channel + struct ast_channel *chana = NULL, *chanb = NULL, *bridgea = NULL, @@ -8933,7 +8890,7 @@ chanb = p2->owner; bridgea = ast_bridged_channel(chana); bridgeb = ast_bridged_channel(chanb); - + if (bridgea) { peera = chana; peerb = chanb; @@ -8945,7 +8902,7 @@ peerc = bridgeb; peerd = bridgea; } - + if (peera && peerb && peerc && (peerb != peerc)) { ast_quiet_chan(peera); ast_quiet_chan(peerb); @@ -8965,7 +8922,7 @@ peerb->cdr = peerc->cdr; } peerc->cdr = NULL; - + if (ast_channel_masquerade(peerb, peerc)) { ast_log(LOG_WARNING, "Failed to masquerade %s into %s\n", peerb->name, peerc->name); res = -1; @@ -8990,19 +8947,21 @@ res = get_destination(p, req); build_contact(p); /* XXX Should we authenticate OPTIONS? XXX */ - if (ast_strlen_zero(p->context)) + if (ast_strlen_zero(p->context)) { strcpy(p->context, default_context); - if (res < 0) + } + if (res < 0) { transmit_response_with_allow(p, "404 Not Found", req, 0); - else if (res > 0) + } else if (res > 0) { transmit_response_with_allow(p, "484 Address Incomplete", req, 0); - else + } else { transmit_response_with_allow(p, "200 OK", req, 0); + } /* Destroy if this OPTIONS was the opening request, but not if - it's in the middle of a normal call flow. */ - if (!p->lastinvite) - ast_set_flag(p, SIP_NEEDDESTROY); - + * it's in the middle of a normal call flow. */ + if (!p->lastinvite) { + ast_set_flag(p, SIP_NEEDDESTROY); + } return res; } @@ -9010,7 +8969,7 @@ 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) { int res = 1; - struct ast_channel *c=NULL; + struct ast_channel *c = NULL; int gotdest; struct ast_frame af = { AST_FRAME_NULL, }; char *supported; @@ -9026,22 +8985,20 @@ required = get_header(req, "Required"); if (required && !ast_strlen_zero(required)) { required_profile = parse_sip_options(NULL, required); - if (required_profile) { /* They require something */ + if (required_profile) { /* They require something */ /* At this point we support no extensions, so fail */ transmit_response_with_unsupported(p, "420 Bad extension", req, required); - ast_set_flag(p, SIP_NEEDDESTROY); + ast_set_flag(p, SIP_NEEDDESTROY); return -1; - } } /* Check if this is a loop */ - /* This happens since we do not properly support SIP domain - handling yet... -oej */ + /* This happens since we do not properly support SIP domain handling yet... -oej */ if (ast_test_flag(p, SIP_OUTGOING) && p->owner && (p->owner->_state != AST_STATE_UP)) { - /* This is a call to ourself. Send ourselves an error code and stop - processing immediately, as SIP really has no good mechanism for - being able to call yourself */ + /* This is a call to ourself. Send ourselves an error code and stop + * processing immediately, as SIP really has no good mechanism for being + * able to call yourself */ transmit_response(p, "482 Loop Detected", req); /* We do NOT destroy p here, so that our response will be accepted */ return 0; @@ -9062,7 +9019,7 @@ if (!strcasecmp(get_header(req, "Content-Type"), "application/sdp")) { if (process_sdp(p, req)) { transmit_response(p, "488 Not acceptable here", req); - ast_set_flag(p, SIP_NEEDDESTROY); + ast_set_flag(p, SIP_NEEDDESTROY); return -1; } } else { @@ -9082,7 +9039,7 @@ transmit_response(p, "403 Forbidden", req); else transmit_response_reliable(p, "403 Forbidden", req, 1); - ast_set_flag(p, SIP_NEEDDESTROY); + ast_set_flag(p, SIP_NEEDDESTROY); } return 0; } @@ -9090,7 +9047,7 @@ if (!ast_strlen_zero(get_header(req, "Content-Type"))) { if (process_sdp(p, req)) { transmit_response(p, "488 Not acceptable here", req); - ast_set_flag(p, SIP_NEEDDESTROY); + ast_set_flag(p, SIP_NEEDDESTROY); return -1; } } else { @@ -9109,11 +9066,12 @@ if (res) { if (res < 0) { ast_log(LOG_NOTICE, "Failed to place call for user %s, too many calls\n", p->username); - if (ignore) + if (ignore) { transmit_response(p, "480 Temporarily Unavailable (Call limit)", req); - else + } else { transmit_response_reliable(p, "480 Temporarily Unavailable (Call limit) ", req, 1); - ast_set_flag(p, SIP_NEEDDESTROY); + } + ast_set_flag(p, SIP_NEEDDESTROY); } return 0; } @@ -9129,23 +9087,25 @@ transmit_response(p, "404 Not Found", req); else transmit_response_reliable(p, "404 Not Found", req, 1); - update_user_counter(p,DEC_IN_USE); + update_user_counter(p, DEC_IN_USE); } else { - if (ignore) + if (ignore) { transmit_response(p, "484 Address Incomplete", req); - else + } else { transmit_response_reliable(p, "484 Address Incomplete", req, 1); - update_user_counter(p,DEC_IN_USE); + } + update_user_counter(p, DEC_IN_USE); } - ast_set_flag(p, SIP_NEEDDESTROY); + ast_set_flag(p, SIP_NEEDDESTROY); } else { /* If no extension was specified, use the s one */ - if (ast_strlen_zero(p->exten)) + if (ast_strlen_zero(p->exten)) { ast_copy_string(p->exten, "s", sizeof(p->exten)); - /* Initialize tag */ + } + /* Initialize tag */ p->tag = rand(); /* First invitation */ - c = sip_new(p, AST_STATE_DOWN, ast_strlen_zero(p->username) ? NULL : p->username ); + c = sip_new(p, AST_STATE_DOWN, ast_strlen_zero(p->username) ? NULL : p->username); *recount = 1; /* Save Record-Route for any later requests we make on this dialogue */ build_route(p, req, 0); @@ -9154,7 +9114,6 @@ ast_mutex_lock(&c->lock); } } - } else { if (option_debug > 1 && sipdebug) ast_log(LOG_DEBUG, "Got a SIP re-invite for call %s\n", p->callid); @@ -9163,7 +9122,7 @@ if (!ignore && p) p->lastinvite = seqno; if (c) { - switch(c->_state) { + switch (c->_state) { case AST_STATE_DOWN: transmit_response(p, "100 Trying", req); ast_setstate(c, AST_STATE_RING); @@ -9189,7 +9148,7 @@ transmit_response(p, "503 Unavailable", req); else transmit_response_reliable(p, "503 Unavailable", req, 1); - ast_set_flag(p, SIP_ALREADYGONE); + ast_set_flag(p, SIP_ALREADYGONE); /* Unlock locks so ast_hangup can do its magic */ ast_mutex_unlock(&p->lock); ast_hangup(c); @@ -9224,14 +9183,14 @@ transmit_response(p, "488 Not Acceptable Here (codec error)", req); else transmit_response_reliable(p, "488 Not Acceptable Here (codec error)", req, 1); - ast_set_flag(p, SIP_NEEDDESTROY); + ast_set_flag(p, SIP_NEEDDESTROY); } else { ast_log(LOG_NOTICE, "Unable to create/find channel\n"); if (ignore) transmit_response(p, "503 Unavailable", req); else transmit_response_reliable(p, "503 Unavailable", req, 1); - ast_set_flag(p, SIP_NEEDDESTROY); + ast_set_flag(p, SIP_NEEDDESTROY); } } } @@ -9241,7 +9200,7 @@ /*--- handle_request_refer: Handle incoming REFER request ---*/ static int handle_request_refer(struct sip_pvt *p, struct sip_request *req, int debug, int ignore, int seqno, int *nounlock) { - struct ast_channel *c=NULL; + struct ast_channel *c = NULL; int res; struct ast_channel *transfer_to; @@ -9258,15 +9217,15 @@ int nobye = 0; if (!ignore) { if (p->refer_call) { - ast_log(LOG_DEBUG,"202 Accepted (supervised)\n"); + ast_log(LOG_DEBUG, "202 Accepted (supervised)\n"); attempt_transfer(p, p->refer_call); if (p->refer_call->owner) ast_mutex_unlock(&p->refer_call->owner->lock); ast_mutex_unlock(&p->refer_call->lock); p->refer_call = NULL; - ast_set_flag(p, SIP_GOTREFER); + ast_set_flag(p, SIP_GOTREFER); } else { - ast_log(LOG_DEBUG,"202 Accepted (blind)\n"); + ast_log(LOG_DEBUG, "202 Accepted (blind)\n"); c = p->owner; if (c) { transfer_to = ast_bridged_channel(c); @@ -9274,43 +9233,43 @@ ast_log(LOG_DEBUG, "Got SIP blind transfer, applying to '%s'\n", transfer_to->name); ast_moh_stop(transfer_to); if (!strcmp(p->refer_to, ast_parking_ext())) { - /* Must release c's lock now, because it will not longer - be accessible after the transfer! */ + /* Must release c's lock now, because it will not + * longer be accessible after the transfer! */ *nounlock = 1; ast_mutex_unlock(&c->lock); sip_park(transfer_to, c, req); nobye = 1; } else { - /* Must release c's lock now, because it will not longer - be accessible after the transfer! */ + /* Must release c's lock now, because it will not + * longer be accessible after the transfer! */ *nounlock = 1; ast_mutex_unlock(&c->lock); - ast_async_goto(transfer_to,p->context, p->refer_to,1); + ast_async_goto(transfer_to, p->context, p->refer_to, 1); } } else { ast_log(LOG_DEBUG, "Got SIP blind transfer but nothing to transfer to.\n"); ast_queue_hangup(p->owner); } } - ast_set_flag(p, SIP_GOTREFER); + ast_set_flag(p, SIP_GOTREFER); } transmit_response(p, "202 Accepted", req); transmit_notify_with_sipfrag(p, seqno); /* Always increment on a BYE */ if (!nobye) { transmit_request_with_auth(p, SIP_BYE, 0, 1, 1); - ast_set_flag(p, SIP_ALREADYGONE); + ast_set_flag(p, SIP_ALREADYGONE); } } } return res; } + /*--- handle_request_cancel: Handle incoming CANCEL request ---*/ static int handle_request_cancel(struct sip_pvt *p, struct sip_request *req, int debug, int ignore) { - check_via(p, req); - ast_set_flag(p, SIP_ALREADYGONE); + ast_set_flag(p, SIP_ALREADYGONE); if (p->rtp) { /* Immediately stop RTP */ ast_rtp_stop(p->rtp); @@ -9322,7 +9281,7 @@ if (p->owner) ast_queue_hangup(p->owner); else - ast_set_flag(p, SIP_NEEDDESTROY); + ast_set_flag(p, SIP_NEEDDESTROY); if (p->initreq.len > 0) { if (!ignore) transmit_response_reliable(p, "487 Request Terminated", &p->initreq, 1); @@ -9337,14 +9296,14 @@ /*--- handle_request_bye: Handle incoming BYE request ---*/ static int handle_request_bye(struct sip_pvt *p, struct sip_request *req, int debug) { - struct ast_channel *c=NULL; + struct ast_channel *c = NULL; int res; struct ast_channel *bridged_to; char iabuf[INET_ADDRSTRLEN]; copy_request(&p->initreq, req); check_via(p, req); - ast_set_flag(p, SIP_ALREADYGONE); + ast_set_flag(p, SIP_ALREADYGONE); if (p->rtp) { /* Immediately stop RTP */ ast_rtp_stop(p->rtp); @@ -9366,7 +9325,7 @@ if (bridged_to) { /* Don't actually hangup here... */ ast_moh_stop(bridged_to); - ast_async_goto(bridged_to, p->context, p->refer_to,1); + ast_async_goto(bridged_to, p->context, p->refer_to, 1); } else ast_queue_hangup(p->owner); } @@ -9377,7 +9336,7 @@ } else if (p->owner) ast_queue_hangup(p->owner); else - ast_set_flag(p, SIP_NEEDDESTROY); + ast_set_flag(p, SIP_NEEDDESTROY); transmit_response(p, "200 OK", req); return 1; @@ -9399,12 +9358,13 @@ } return 1; } + /*--- handle_request_subscribe: Handle incoming SUBSCRIBE 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) { int gotdest; int res = 0; - struct ast_channel *c=NULL; + struct ast_channel *c = NULL; if (!ignore) { /* Use this as the basis */ @@ -9418,7 +9378,7 @@ ast_verbose("Ignoring this SUBSCRIBE request\n"); if (!p->lastinvite) { - char mailbox[256]=""; + char mailbox[256] = ""; int found = 0; /* Handle authentication if this is our first subscribe */ @@ -9426,7 +9386,7 @@ if (res) { if (res < 0) { ast_log(LOG_NOTICE, "Failed to authenticate user %s for SUBSCRIBE\n", get_header(req, "From")); - ast_set_flag(p, SIP_NEEDDESTROY); + ast_set_flag(p, SIP_NEEDDESTROY); } return 0; } @@ -9441,37 +9401,37 @@ transmit_response(p, "404 Not Found", req); else transmit_response(p, "484 Address Incomplete", req); - ast_set_flag(p, SIP_NEEDDESTROY); + ast_set_flag(p, SIP_NEEDDESTROY); } else { - /* Initialize tag */ + /* Initialize tag */ p->tag = rand(); if (!strcmp(get_header(req, "Accept"), "application/dialog-info+xml")) p->subscribed = 2; else if (!strcmp(get_header(req, "Accept"), "application/simple-message-summary")) { /* Looks like they actually want a mailbox */ - /* At this point, we should check if they subscribe to a mailbox that - has the same extension as the peer or the mailbox id. If we configure - the context to be the same as a SIP domain, we could check mailbox - context as well. To be able to securely accept subscribes on mailbox - IDs, not extensions, we need to check the digest auth user to make - sure that the user has access to the mailbox. - - Since we do not act on this subscribe anyway, we might as well - accept any authenticated peer with a mailbox definition in their - config section. - - */ + /* At this point, we should check if they subscribe to a mailbox + * that has the same extension as the peer or the mailbox id. If + * we configure the context to be the same as a SIP domain, we + * could check mailbox context as well. To be able to securely + * accept subscribes on mailbox IDs, not extensions, we need to + * check the digest auth user to make sure that the user has + * access to the mailbox. + * + * Since we do not act on this subscribe anyway, we might as + * well accept any authenticated peer with a mailbox definition + * in their config section. + */ if (!ast_strlen_zero(mailbox)) { found++; } if (found){ transmit_response(p, "200 OK", req); - ast_set_flag(p, SIP_NEEDDESTROY); + ast_set_flag(p, SIP_NEEDDESTROY); } else { transmit_response(p, "403 Forbidden", req); - ast_set_flag(p, SIP_NEEDDESTROY); + ast_set_flag(p, SIP_NEEDDESTROY); } return 0; } else @@ -9479,19 +9439,20 @@ if (p->subscribed) p->stateid = ast_extension_state_add(p->context, p->exten, cb_extensionstate, p); } - } else + } else { c = p->owner; + } if (!ignore && p) p->lastinvite = seqno; if (p && !ast_test_flag(p, SIP_NEEDDESTROY)) { if (!(p->expiry = atoi(get_header(req, "Expires")))) { transmit_response(p, "200 OK", req); - ast_set_flag(p, SIP_NEEDDESTROY); + ast_set_flag(p, SIP_NEEDDESTROY); return 0; } /* The next line can be removed if the SNOM200 Expires bug is fixed */ - if (p->subscribed == 1) { + if (p->subscribed == 1) { if (p->expiry>max_expiry) p->expiry = max_expiry; } @@ -9506,7 +9467,7 @@ } transmit_response(p, "200 OK", req); sip_scheddestroy(p, (p->expiry+10)*1000); - transmit_state_notify(p, ast_extension_state(NULL, p->context, p->exten),1); + transmit_state_notify(p, ast_extension_state(NULL, p->context, p->exten), 1); } return 1; } @@ -9522,8 +9483,9 @@ ast_verbose("Using latest request as basis request\n"); copy_request(&p->initreq, req); check_via(p, req); - if ((res = register_verify(p, sin, req, e, ignore)) < 0) + if ((res = register_verify(p, sin, req, e, ignore)) < 0) { ast_log(LOG_NOTICE, "Registration from '%s' failed for '%s'\n", get_header(req, "To"), ast_inet_ntoa(iabuf, sizeof(iabuf), sin->sin_addr)); + } if (res < 1) { /* Go ahead and free RTP port */ if (p->rtp && !p->owner) { @@ -9534,18 +9496,19 @@ ast_rtp_destroy(p->vrtp); p->vrtp = NULL; } - /* Destroy the session, but keep us around for just a bit in case they don't - get our 200 OK */ + /* Destroy the session, but keep us around for just a bit in case they + * don't get our 200 OK */ sip_scheddestroy(p, 15*1000); } return res; } + /*--- handle_request: Handle SIP requests (methods) ---*/ /* this is where all incoming requests go first */ static int handle_request(struct sip_pvt *p, struct sip_request *req, struct sockaddr_in *sin, int *recount, int *nounlock) { - /* Called with p->lock held, as well as p->owner->lock if appropriate, keeping things - relatively static */ + /* Called with p->lock held, as well as p->owner->lock if appropriate, + * keeping things relatively static */ struct sip_request resp; char *cmd; char *cseq; @@ -9553,7 +9516,7 @@ char *useragent; int seqno; int len; - int ignore=0; + int ignore = 0; int respid; int res = 0; char iabuf[INET_ADDRSTRLEN]; @@ -9586,53 +9549,53 @@ /* Find out SIP method for incoming request */ if (req->method == SIP_RESPONSE) { /* Response to our request */ - /* Response to our request -- Do some sanity checks */ + /* Response to our request -- Do some sanity checks */ if (!p->initreq.headers) { ast_log(LOG_DEBUG, "That's odd... Got a response on a call we dont know about. Cseq %d Cmd %s\n", seqno, cmd); - ast_set_flag(p, SIP_NEEDDESTROY); + ast_set_flag(p, SIP_NEEDDESTROY); return 0; } else if (p->ocseq && (p->ocseq < seqno)) { ast_log(LOG_DEBUG, "Ignoring out of order response %d (expecting %d)\n", seqno, p->ocseq); return -1; } else if (p->ocseq && (p->ocseq != seqno)) { - /* ignore means "don't do anything with it" but still have to - respond appropriately */ - ignore=1; + /* ignore means "don't do anything with it" but still have to + * respond appropriately. */ + ignore = 1; } - + extract_uri(p, req); e = ast_skip_blanks(e); if (sscanf(e, "%d %n", &respid, &len) != 1) { ast_log(LOG_WARNING, "Invalid response: '%s'\n", e); } else { - handle_response(p, respid, e + len, req,ignore, seqno); + handle_response(p, respid, e + len, req, ignore, seqno); } return 0; } - /* New SIP request coming in - (could be new request in existing SIP dialog as well...) - */ + /* New SIP request coming in + * (could be new request in existing SIP dialog as well...) */ p->method = req->method; /* Find out which SIP method they are using */ - if (option_debug > 2) - ast_log(LOG_DEBUG, "**** Received %s (%d) - Command in SIP %s\n", sip_methods[p->method].text, sip_methods[p->method].id, cmd); + if (option_debug > 2) { + ast_log(LOG_DEBUG, "**** Received %s (%d) - Command in SIP %s\n", sip_methods[p->method].text, sip_methods[p->method].id, cmd); + } if (p->icseq && (p->icseq > seqno)) { ast_log(LOG_DEBUG, "Ignoring too old SIP packet packet %d (expecting >= %d)\n", seqno, p->icseq); return -1; } else if (p->icseq && (p->icseq == seqno) && req->method != SIP_ACK &&(p->method != SIP_CANCEL|| ast_test_flag(p, SIP_ALREADYGONE))) { - /* ignore means "don't do anything with it" but still have to - respond appropriately. We do this if we receive a repeat of - the last sequence number */ - ignore=2; - if (option_debug > 2) + /* ignore means "don't do anything with it" but still have to respond + * appropriately. We do this if we receive a repeat of the last + * sequence number. */ + ignore = 2; + if (option_debug > 2) { ast_log(LOG_DEBUG, "Ignoring SIP message because of retransmit (%s Seqno %d, ours %d)\n", sip_methods[p->method].text, p->icseq, seqno); + } } - + if (seqno >= p->icseq) - /* Next should follow monotonically (but not necessarily - incrementally -- thanks again to the genius authors of SIP -- - increasing */ + /* Next should follow monotonically (but not necessarily incrementally + * -- thanks again to the genius authors of SIP -- increasing */ p->icseq = seqno; /* Find their tag if we haven't got it */ @@ -9688,8 +9651,9 @@ /* XXX we get NOTIFY's from some servers. WHY?? Maybe we should look into this someday XXX */ transmit_response(p, "200 OK", req); - if (!p->lastinvite) - ast_set_flag(p, SIP_NEEDDESTROY); + if (!p->lastinvite) { + ast_set_flag(p, SIP_NEEDDESTROY); + } break; case SIP_ACK: /* Make sure we don't ignore this */ @@ -9697,21 +9661,23 @@ p->pendinginvite = 0; __sip_ack(p, seqno, FLAG_RESPONSE, -1); if (!ast_strlen_zero(get_header(req, "Content-Type"))) { - if (process_sdp(p, req)) + if (process_sdp(p, req)) { return -1; - } + } + } check_pendings(p); } if (!p->lastinvite && ast_strlen_zero(p->randdata)) - ast_set_flag(p, SIP_NEEDDESTROY); + ast_set_flag(p, SIP_NEEDDESTROY); break; default: transmit_response_with_allow(p, "501 Method Not Implemented", req, 0); - ast_log(LOG_NOTICE, "Unknown SIP command '%s' from '%s'\n", - cmd, ast_inet_ntoa(iabuf, sizeof(iabuf), p->sa.sin_addr)); + ast_log(LOG_NOTICE, "Unknown SIP command '%s' from '%s'\n", + cmd, ast_inet_ntoa(iabuf, sizeof(iabuf), p->sa.sin_addr)); /* If this is some new method, and we don't have a call, destroy it now */ - if (!p->initreq.headers) - ast_set_flag(p, SIP_NEEDDESTROY); + if (!p->initreq.headers) { + ast_set_flag(p, SIP_NEEDDESTROY); + } break; } return res; @@ -9754,8 +9720,9 @@ req.method = find_sip_method(req.rlPart1); if (req.debug) { ast_verbose("--- (%d headers %d lines)", req.headers, req.lines); - if (req.headers + req.lines == 0) + if (req.headers + req.lines == 0) { ast_verbose(" Nat keepalive "); + } ast_verbose("---\n"); } @@ -9808,14 +9775,14 @@ /* Check for messages */ ast_app_messagecount(peer->mailbox, &newmsgs, &oldmsgs); - + time(&peer->lastmsgcheck); - + /* Return now if it's the same thing we told them last time */ if (((newmsgs << 8) | (oldmsgs)) == peer->lastmsgssent) { return 0; } - + p = sip_alloc(NULL, NULL, 0, SIP_NOTIFY); if (!p) { ast_log(LOG_WARNING, "Unable to build sip pvt data for MWI\n"); @@ -9828,7 +9795,7 @@ return 0; } /* Recalculate our side, and recalculate Call ID */ - if (ast_sip_ouraddrfor(&p->sa.sin_addr,&p->ourip)) + if (ast_sip_ouraddrfor(&p->sa.sin_addr, &p->ourip)) memcpy(&p->ourip, &__ourip, sizeof(p->ourip)); build_via(p, p->via, sizeof(p->via)); build_callid(p->callid, sizeof(p->callid), p->ourip, p->fromdomain); @@ -9846,19 +9813,19 @@ struct sip_pvt *sip; struct sip_peer *peer = NULL; time_t t; - int fastrestart =0; + int fastrestart = 0; int lastpeernum = -1; int curpeernum; int reloading; /* Add an I/O event to our UDP socket */ - if (sipsock > -1) + if (sipsock > -1) { ast_io_add(io, sipsock, sipsock_read, AST_IO_IN, NULL); - - /* This thread monitors all the frame relay interfaces which are not yet in use - (and thus do not have a separate thread) indefinitely */ - /* From here on out, we die whenever asked */ - for(;;) { + } + /* This thread monitors all the frame relay interfaces which are not yet in + * use (and thus do not have a separate thread) indefinitely + * From here on out, we die whenever asked */ + for (;;) { /* Check for a reload request */ ast_mutex_lock(&sip_reload_lock); reloading = sip_reloading; @@ -9871,10 +9838,10 @@ } /* Check for interfaces needing to be killed */ ast_mutex_lock(&iflock); -restartsearch: +restartsearch: time(&t); sip = iflist; - while(sip) { + while (sip) { ast_mutex_lock(&sip->lock); if (sip->rtp && sip->owner && (sip->owner->_state == AST_STATE_UP) && !sip->redirip.sin_addr.s_addr) { if (sip->lastrtptx && sip->rtpkeepalive && t > sip->lastrtptx + sip->rtpkeepalive) { @@ -9886,12 +9853,10 @@ /* Might be a timeout now -- see if we're on hold */ struct sockaddr_in sin; ast_rtp_get_peer(sip->rtp, &sin); - if (sin.sin_addr.s_addr || - (sip->rtpholdtimeout && - (t > sip->lastrtprx + sip->rtpholdtimeout))) { + if (sin.sin_addr.s_addr || (sip->rtpholdtimeout && (t > sip->lastrtprx + sip->rtpholdtimeout))) { /* Needs a hangup */ if (sip->rtptimeout) { - while(sip->owner && ast_mutex_trylock(&sip->owner->lock)) { + while (sip->owner && ast_mutex_trylock(&sip->owner->lock)) { ast_mutex_unlock(&sip->lock); usleep(1); ast_mutex_lock(&sip->lock); @@ -9915,8 +9880,9 @@ sip = sip->next; } ast_mutex_unlock(&iflock); - /* Don't let anybody kill us right away. Nobody should lock the interface list - and wait for the monitor list, but the other way around is okay. */ + /* Don't let anybody kill us right away. Nobody should lock the + * interface list and wait for the monitor list, but the other way + * around is okay. */ ast_mutex_lock(&monlock); /* Lock the network interface */ ast_mutex_lock(&netlock); @@ -9934,8 +9900,9 @@ res = 1; res = ast_io_wait(io, res); ast_mutex_lock(&monlock); - if (res >= 0) + if (res >= 0) { ast_sched_runq(sched); + } /* needs work to send mwi to realtime peers */ time(&t); @@ -9955,7 +9922,7 @@ ASTOBJ_WRLOCK(peer); sip_send_mwi_to_peer(peer); ASTOBJ_UNLOCK(peer); - ASTOBJ_UNREF(peer,sip_destroy_peer); + ASTOBJ_UNREF(peer, sip_destroy_peer); } else { /* Reset where we come from */ lastpeernum = -1; @@ -9964,7 +9931,6 @@ } /* Never reached */ return NULL; - } /*--- restart_monitor: Start the channel monitor thread ---*/ @@ -10004,7 +9970,7 @@ static int sip_poke_noanswer(void *data) { struct sip_peer *peer = data; - + peer->pokeexpire = -1; if (peer->lastms > -1) { ast_log(LOG_NOTICE, "Peer '%s' is now UNREACHABLE! Last qualify: %d\n", peer->name, peer->lastms); @@ -10027,8 +9993,8 @@ { struct sip_pvt *p; if (!peer->maxms || !peer->addr.sin_addr.s_addr) { - /* IF we have no IP, or this isn't to be monitored, return - imeediately after clearing things out */ + /* IF we have no IP, or this isn't to be monitored, return imeediately + * after clearing things out */ if (peer->pokeexpire > -1) ast_sched_del(sched, peer->pokeexpire); peer->lastms = 0; @@ -10059,7 +10025,7 @@ ast_inet_ntoa(p->tohost, sizeof(p->tohost), peer->addr.sin_addr); /* Recalculate our side, and recalculate Call ID */ - if (ast_sip_ouraddrfor(&p->sa.sin_addr,&p->ourip)) + if (ast_sip_ouraddrfor(&p->sa.sin_addr, &p->ourip)) memcpy(&p->ourip, &__ourip, sizeof(p->ourip)); build_via(p, p->via, sizeof(p->via)); build_callid(p->callid, sizeof(p->callid), p->ourip, p->fromdomain); @@ -10122,7 +10088,7 @@ } if (p) - ASTOBJ_UNREF(p,sip_destroy_peer); + ASTOBJ_UNREF(p, sip_destroy_peer); return res; } @@ -10178,18 +10144,17 @@ if (ast_strlen_zero(p->peername) && ext) ast_copy_string(p->peername, ext, sizeof(p->peername)); /* Recalculate our side, and recalculate Call ID */ - if (ast_sip_ouraddrfor(&p->sa.sin_addr,&p->ourip)) + if (ast_sip_ouraddrfor(&p->sa.sin_addr, &p->ourip)) memcpy(&p->ourip, &__ourip, sizeof(p->ourip)); build_via(p, p->via, sizeof(p->via)); build_callid(p->callid, sizeof(p->callid), p->ourip, p->fromdomain); - + /* We have an extension to call, don't use the full contact here */ - /* This to enable dialling registred peers with extension dialling, - like SIP/peername/extension - SIP/peername will still use the full contact */ + /* This to enable dialling registred peers with extension dialling, like + * SIP/peername/extension SIP/peername will still use the full contact */ if (ext) { ast_copy_string(p->username, ext, sizeof(p->username)); - p->fullcontact[0] = 0; + p->fullcontact[0] = 0; } #if 0 printf("Setting up to call extension '%s' at '%s'\n", ext ? ext : "", host); @@ -10278,24 +10243,26 @@ ast_set_flag(flags, SIP_PROG_INBAND_NO); else if (ast_true(v->value)) ast_set_flag(flags, SIP_PROG_INBAND_YES); - } else if (!strcasecmp(v->name, "allowguest")) { + } else if (!strcasecmp(v->name, "allowguest")) { #ifdef OSP_SUPPORT - if (!strcasecmp(v->value, "osp")) + if (!strcasecmp(v->value, "osp")) global_allowguest = 2; else #endif - if (ast_true(v->value)) + if (ast_true(v->value)) { global_allowguest = 1; - else + } else { global_allowguest = 0; + } #ifdef OSP_SUPPORT } else if (!strcasecmp(v->name, "ospauth")) { ast_set_flag(mask, SIP_OSPAUTH); ast_clear_flag(flags, SIP_OSPAUTH); - if (!strcasecmp(v->value, "exclusive")) + if (!strcasecmp(v->value, "exclusive")) { ast_set_flag(flags, SIP_OSPAUTH_EXCLUSIVE); - else + } else { ast_set2_flag(flags, ast_true(v->value), SIP_OSPAUTH_YES); + } #endif } else if (!strcasecmp(v->name, "promiscredir")) { ast_set_flag(mask, SIP_PROMISCREDIR); @@ -10310,7 +10277,7 @@ static struct sip_auth *add_realm_authentication(struct sip_auth *authlist, char *configuration, int lineno) { char authcopy[256] = ""; - char *username=NULL, *realm=NULL, *secret=NULL, *md5secret=NULL; + char *username = NULL, *realm = NULL, *secret = NULL, *md5secret = NULL; char *stringp; struct sip_auth *auth; struct sip_auth *b = NULL, *a = authlist; @@ -10339,7 +10306,7 @@ secret = strsep(&stringp, ":"); if (!secret) { stringp = username; - md5secret = strsep(&stringp,"#"); + md5secret = strsep(&stringp, "#"); } } auth = malloc(sizeof(struct sip_auth)); @@ -10359,8 +10326,8 @@ /* Add authentication to authl */ if (!authlist) { /* No existing list */ return auth; - } - while(a) { + } + while (a) { b = a; a = a->next; } @@ -10391,7 +10358,7 @@ /*--- find_realm_authentication: Find authentication for a specific realm ---*/ static struct sip_auth *find_realm_authentication(struct sip_auth *authlist, char *realm) { - struct sip_auth *a = authlist; /* First entry in auth list */ + struct sip_auth *a = authlist; /* First entry in auth list */ while (a) { if (!strcasecmp(a->realm, realm)){ @@ -10399,7 +10366,6 @@ } a = a->next; } - return a; } @@ -10414,7 +10380,6 @@ struct ast_flags userflags = {(0)}; struct ast_flags mask = {(0)}; - user = (struct sip_user *)malloc(sizeof(struct sip_user)); if (!user) { return NULL; @@ -10437,7 +10402,7 @@ strcpy(user->context, default_context); strcpy(user->language, default_language); strcpy(user->musicclass, global_musicclass); - while(v) { + while (v) { if (handle_common_options(&userflags, &mask, v)) { v = v->next; continue; @@ -10447,7 +10412,7 @@ ast_copy_string(user->context, v->value, sizeof(user->context)); } else if (!strcasecmp(v->name, "setvar")) { varname = ast_strdupa(v->value); - if (varname && (varval = strchr(varname,'='))) { + if (varname && (varval = strchr(varname, '='))) { *varval = '\0'; varval++; if ((tmpvar = ast_variable_new(varname, varval))) { @@ -10459,7 +10424,7 @@ !strcasecmp(v->name, "deny")) { user->ha = ast_append_ha(v->name, v->value, user->ha); } else if (!strcasecmp(v->name, "secret")) { - ast_copy_string(user->secret, v->value, sizeof(user->secret)); + ast_copy_string(user->secret, v->value, sizeof(user->secret)); } else if (!strcasecmp(v->name, "md5secret")) { ast_copy_string(user->md5secret, v->value, sizeof(user->md5secret)); } else if (!strcasecmp(v->name, "callerid")) { @@ -10495,10 +10460,11 @@ ast_parse_allow_disallow(&user->prefs, &user->capability, v->value, 0); } else if (!strcasecmp(v->name, "callingpres")) { user->callingpres = ast_parse_caller_presentation(v->value); - if (user->callingpres == -1) + if (user->callingpres == -1) { user->callingpres = atoi(v->value); + } } - /*else if (strcasecmp(v->name,"type")) + /*else if (strcasecmp(v->name, "type")) * ast_log(LOG_WARNING, "Ignoring %s\n", v->name); */ v = v->next; @@ -10524,10 +10490,10 @@ peer->expire = -1; peer->pokeexpire = -1; ast_copy_string(peer->name, name, sizeof(peer->name)); - ast_copy_flags(peer, &global_flags, - SIP_PROMISCREDIR | SIP_USEREQPHONE | SIP_TRUSTRPID | SIP_USECLIENTCODE | - SIP_DTMF | SIP_NAT | SIP_REINVITE | SIP_INSECURE_PORT | SIP_INSECURE_INVITE | - SIP_PROG_INBAND | SIP_OSPAUTH); + ast_copy_flags(peer, &global_flags, SIP_PROMISCREDIR | SIP_USEREQPHONE | + SIP_TRUSTRPID | SIP_USECLIENTCODE | SIP_DTMF | SIP_NAT | + SIP_REINVITE | SIP_INSECURE_PORT | SIP_INSECURE_INVITE | + SIP_PROG_INBAND | SIP_OSPAUTH); strcpy(peer->context, default_context); strcpy(peer->language, default_language); strcpy(peer->musicclass, global_musicclass); @@ -10551,17 +10517,16 @@ { struct sip_peer *peer = NULL; struct ast_ha *oldha = NULL; - int maskfound=0; - int obproxyfound=0; - int found=0; - int format=0; /* Ama flags */ + int maskfound = 0; + int obproxyfound = 0; + int found = 0; + int format = 0; /* Ama flags */ time_t regseconds; char *varname = NULL, *varval = NULL; struct ast_variable *tmpvar = NULL; struct ast_flags peerflags = {(0)}; struct ast_flags mask = {(0)}; - if (!realtime) /* Note we do NOT use find_peer here, to avoid realtime recursion */ peer = ASTOBJ_CONTAINER_FIND_UNLINK(&peerl, name); @@ -10569,7 +10534,7 @@ if (peer) { /* Already in the list, remove it and it will be added back (or FREE'd) */ found++; - } else { + } else { peer = malloc(sizeof(struct sip_peer)); if (peer) { memset(peer, 0, sizeof(struct sip_peer)); @@ -10622,14 +10587,13 @@ oldha = peer->ha; peer->ha = NULL; peer->addr.sin_family = AF_INET; - ast_copy_flags(peer, &global_flags, - SIP_PROMISCREDIR | SIP_TRUSTRPID | SIP_USECLIENTCODE | - SIP_DTMF | SIP_REINVITE | SIP_INSECURE_PORT | SIP_INSECURE_INVITE | - SIP_PROG_INBAND | SIP_OSPAUTH); + ast_copy_flags(peer, &global_flags, SIP_PROMISCREDIR | SIP_TRUSTRPID | + SIP_USECLIENTCODE | SIP_DTMF | SIP_REINVITE | SIP_INSECURE_PORT | + SIP_INSECURE_INVITE | SIP_PROG_INBAND | SIP_OSPAUTH); peer->capability = global_capability; peer->rtptimeout = global_rtptimeout; peer->rtpholdtimeout = global_rtpholdtimeout; - while(v) { + while (v) { if (handle_common_options(&peerflags, &mask, v)) { v = v->next; continue; @@ -10638,27 +10602,27 @@ if (realtime && !strcasecmp(v->name, "regseconds")) { if (sscanf(v->value, "%li", ®seconds) != 1) regseconds = 0; - } else if (realtime && !strcasecmp(v->name, "ipaddr") && !ast_strlen_zero(v->value) ) { + } else if (realtime && !strcasecmp(v->name, "ipaddr") && !ast_strlen_zero(v->value)) { inet_aton(v->value, &(peer->addr.sin_addr)); - } else if (realtime && !strcasecmp(v->name, "name")) + } else if (realtime && !strcasecmp(v->name, "name")) { ast_copy_string(peer->name, v->value, sizeof(peer->name)); - else if (!strcasecmp(v->name, "secret")) + } else if (!strcasecmp(v->name, "secret")) { ast_copy_string(peer->secret, v->value, sizeof(peer->secret)); - else if (!strcasecmp(v->name, "md5secret")) + } else if (!strcasecmp(v->name, "md5secret")) { ast_copy_string(peer->md5secret, v->value, sizeof(peer->md5secret)); - else if (!strcasecmp(v->name, "auth")) + } else if (!strcasecmp(v->name, "auth")) { peer->auth = add_realm_authentication(peer->auth, v->value, v->lineno); - else if (!strcasecmp(v->name, "callerid")) { + } else if (!strcasecmp(v->name, "callerid")) { ast_callerid_split(v->value, peer->cid_name, sizeof(peer->cid_name), peer->cid_num, sizeof(peer->cid_num)); } else if (!strcasecmp(v->name, "context")) { ast_copy_string(peer->context, v->value, sizeof(peer->context)); - } else if (!strcasecmp(v->name, "fromdomain")) + } else if (!strcasecmp(v->name, "fromdomain")) { ast_copy_string(peer->fromdomain, v->value, sizeof(peer->fromdomain)); - else if (!strcasecmp(v->name, "usereqphone")) + } else if (!strcasecmp(v->name, "usereqphone")) { ast_set2_flag(peer, ast_true(v->value), SIP_USEREQPHONE); - else if (!strcasecmp(v->name, "fromuser")) + } else if (!strcasecmp(v->name, "fromuser")) { ast_copy_string(peer->fromuser, v->value, sizeof(peer->fromuser)); - else if (!strcasecmp(v->name, "host") || !strcasecmp(v->name, "outboundproxy")) { + } else if (!strcasecmp(v->name, "host") || !strcasecmp(v->name, "outboundproxy")) { if (!strcasecmp(v->value, "dynamic")) { if (!strcasecmp(v->name, "outboundproxy") || obproxyfound) { ast_log(LOG_WARNING, "You can't have a dynamic outbound proxy, you big silly head at line %d.\n", v->lineno); @@ -10666,11 +10630,12 @@ /* They'll register with us */ ast_set_flag(peer, SIP_DYNAMIC); if (!found) { - /* Initialize stuff iff we're not found, otherwise - we keep going with what we had */ + /* Initialize stuff iff we're not found, otherwise we + * keep going with what we had */ memset(&peer->addr.sin_addr, 0, 4); if (peer->addr.sin_port) { - /* If we've already got a port, make it the default rather than absolute */ + /* If we've already got a port, make it the default + * rather than absolute */ peer->defaddr.sin_port = peer->addr.sin_port; peer->addr.sin_port = 0; } @@ -10681,17 +10646,18 @@ if (peer->expire > -1) ast_sched_del(sched, peer->expire); peer->expire = -1; - ast_clear_flag(peer, SIP_DYNAMIC); + ast_clear_flag(peer, SIP_DYNAMIC); if (!obproxyfound || !strcasecmp(v->name, "outboundproxy")) { if (ast_get_ip_or_srv(&peer->addr, v->value, "_sip._udp")) { ASTOBJ_UNREF(peer, sip_destroy_peer); return NULL; } } - if (!strcasecmp(v->name, "outboundproxy")) - obproxyfound=1; - else + if (!strcasecmp(v->name, "outboundproxy")) { + obproxyfound = 1; + } else { ast_copy_string(peer->tohost, v->value, sizeof(peer->tohost)); + } } if (!maskfound) inet_aton("255.255.255.255", &peer->mask); @@ -10767,7 +10733,7 @@ } else if (!strcasecmp(v->name, "setvar")) { /* Set peer channel variable */ varname = ast_strdupa(v->value); - if (varname && (varval = strchr(varname,'='))) { + if (varname && (varval = strchr(varname, '='))) { *varval = '\0'; varval++; if ((tmpvar = ast_variable_new(varname, varval))) { @@ -10785,10 +10751,10 @@ peer->maxms = 0; } } - /* else if (strcasecmp(v->name,"type")) + /* else if (strcasecmp(v->name, "type")) * ast_log(LOG_WARNING, "Ignoring %s\n", v->name); */ - v=v->next; + v = v->next; } if (realtime && !ast_test_flag((&global_flags_page2), SIP_PAGE2_RTIGNOREREGEXPIRE) && ast_test_flag(peer, SIP_DYNAMIC)) { time_t nowtime; @@ -10796,13 +10762,15 @@ time(&nowtime); if ((nowtime - regseconds) > 0) { memset(&peer->addr, 0, sizeof(peer->addr)); - if (option_debug) + if (option_debug) { ast_log(LOG_DEBUG, "Bah, we're expired (%ld/%ld/%ld)!\n", nowtime - regseconds, regseconds, nowtime); + } } } ast_copy_flags(peer, &peerflags, mask.flags); - if (!found && ast_test_flag(peer, SIP_DYNAMIC) && !ast_test_flag(peer, SIP_REALTIME)) + if (!found && ast_test_flag(peer, SIP_DYNAMIC) && !ast_test_flag(peer, SIP_REALTIME)) { reg_source_db(peer); + } ASTOBJ_UNMARK(peer); ast_free_ha(oldha); return peer; @@ -10828,7 +10796,7 @@ int oldport = ntohs(bindaddr.sin_port); char iabuf[INET_ADDRSTRLEN]; struct ast_flags dummy; - + cfg = ast_config_load(config); /* We *must* have a config file otherwise stop immediately */ @@ -10836,7 +10804,7 @@ ast_log(LOG_NOTICE, "Unable to load config %s\n", config); return -1; } - + /* Reset IP addresses */ memset(&bindaddr, 0, sizeof(bindaddr)); memset(&localaddr, 0, sizeof(localaddr)); @@ -10885,7 +10853,7 @@ /* Read the [general] config section of sip.conf (or from realtime config) */ v = ast_variable_browse(cfg, "general"); - while(v) { + while (v) { if (handle_common_options(&global_flags, &dummy, v)) { v = v->next; continue; @@ -10898,23 +10866,23 @@ ast_copy_string(global_realm, v->value, sizeof(global_realm)); } else if (!strcasecmp(v->name, "useragent")) { ast_copy_string(default_useragent, v->value, sizeof(default_useragent)); - ast_log(LOG_DEBUG, "Setting User Agent Name to %s\n", - default_useragent); + ast_log(LOG_DEBUG, "Setting User Agent Name to %s\n", default_useragent); } else if (!strcasecmp(v->name, "rtcachefriends")) { - ast_set2_flag((&global_flags_page2), ast_true(v->value), SIP_PAGE2_RTCACHEFRIENDS); + ast_set2_flag((&global_flags_page2), ast_true(v->value), SIP_PAGE2_RTCACHEFRIENDS); } else if (!strcasecmp(v->name, "rtnoupdate")) { - ast_set2_flag((&global_flags_page2), ast_true(v->value), SIP_PAGE2_RTNOUPDATE); + ast_set2_flag((&global_flags_page2), ast_true(v->value), SIP_PAGE2_RTNOUPDATE); } else if (!strcasecmp(v->name, "rtignoreregexpire")) { - ast_set2_flag((&global_flags_page2), ast_true(v->value), SIP_PAGE2_RTIGNOREREGEXPIRE); + ast_set2_flag((&global_flags_page2), ast_true(v->value), SIP_PAGE2_RTIGNOREREGEXPIRE); } else if (!strcasecmp(v->name, "rtautoclear")) { int i = atoi(v->value); - if (i > 0) + if (i > 0) { global_rtautoclear = i; - else + } else { i = 0; + } ast_set2_flag((&global_flags_page2), i || ast_true(v->value), SIP_PAGE2_RTAUTOCLEAR); } else if (!strcasecmp(v->name, "usereqphone")) { - ast_set2_flag((&global_flags), ast_true(v->value), SIP_USEREQPHONE); + ast_set2_flag((&global_flags), ast_true(v->value), SIP_USEREQPHONE); } else if (!strcasecmp(v->name, "relaxdtmf")) { relaxdtmf = ast_true(v->value); } else if (!strcasecmp(v->name, "checkmwi")) { @@ -10950,15 +10918,17 @@ } else if (!strcasecmp(v->name, "regcontext")) { ast_copy_string(regcontext, v->value, sizeof(regcontext)); /* Create context if it doesn't exist already */ - if (!ast_context_find(regcontext)) + if (!ast_context_find(regcontext)) { ast_context_create(NULL, regcontext, channeltype); + } } else if (!strcasecmp(v->name, "callerid")) { ast_copy_string(default_callerid, v->value, sizeof(default_callerid)); } else if (!strcasecmp(v->name, "fromdomain")) { ast_copy_string(default_fromdomain, v->value, sizeof(default_fromdomain)); } else if (!strcasecmp(v->name, "outboundproxy")) { - if (ast_get_ip_or_srv(&outboundproxyip, v->value, "_sip._udp") < 0) + if (ast_get_ip_or_srv(&outboundproxyip, v->value, "_sip._udp") < 0) { ast_log(LOG_WARNING, "Unable to locate host '%s'\n", v->value); + } } else if (!strcasecmp(v->name, "outboundproxyport")) { /* Port needs to be after IP */ sscanf(v->value, "%d", &format); @@ -10971,19 +10941,22 @@ pedanticsipchecking = ast_true(v->value); } else if (!strcasecmp(v->name, "maxexpirey") || !strcasecmp(v->name, "maxexpiry")) { max_expiry = atoi(v->value); - if (max_expiry < 1) + if (max_expiry < 1) { max_expiry = DEFAULT_MAX_EXPIRY; + } } else if (!strcasecmp(v->name, "defaultexpiry") || !strcasecmp(v->name, "defaultexpirey")) { default_expiry = atoi(v->value); - if (default_expiry < 1) + if (default_expiry < 1) { default_expiry = DEFAULT_DEFAULT_EXPIRY; - } else if (!strcasecmp(v->name, "sipdebug")){ + } + } else if (!strcasecmp(v->name, "sipdebug")) { sipdebug = ast_true(v->value); - } else if (!strcasecmp(v->name, "registertimeout")){ + } else if (!strcasecmp(v->name, "registertimeout")) { global_reg_timeout = atoi(v->value); - if (global_reg_timeout < 1) + if (global_reg_timeout < 1) { global_reg_timeout = DEFAULT_REGISTRATION_TIMEOUT; - } else if (!strcasecmp(v->name, "registerattempts")){ + } + } else if (!strcasecmp(v->name, "registerattempts")) { global_regattempts_max = atoi(v->value); } else if (!strcasecmp(v->name, "bindaddr")) { if (!(hp = ast_gethostbyname(v->value, &ahp))) { @@ -10993,24 +10966,27 @@ } } else if (!strcasecmp(v->name, "localnet")) { struct ast_ha *na; - if (!(na = ast_append_ha("d", v->value, localaddr))) + if (!(na = ast_append_ha("d", v->value, localaddr))) { ast_log(LOG_WARNING, "Invalid localnet value: %s\n", v->value); - else + } else { localaddr = na; + } } else if (!strcasecmp(v->name, "localmask")) { ast_log(LOG_WARNING, "Use of localmask is no long supported -- use localnet with mask syntax\n"); } else if (!strcasecmp(v->name, "externip")) { - if (!(hp = ast_gethostbyname(v->value, &ahp))) + if (!(hp = ast_gethostbyname(v->value, &ahp))) { ast_log(LOG_WARNING, "Invalid address for externip keyword: %s\n", v->value); - else + } else { memcpy(&externip.sin_addr, hp->h_addr, sizeof(externip.sin_addr)); + } externexpire = 0; } else if (!strcasecmp(v->name, "externhost")) { ast_copy_string(externhost, v->value, sizeof(externhost)); - if (!(hp = ast_gethostbyname(externhost, &ahp))) + if (!(hp = ast_gethostbyname(externhost, &ahp))) { ast_log(LOG_WARNING, "Invalid address for externhost keyword: %s\n", externhost); - else + } else { memcpy(&externip.sin_addr, hp->h_addr, sizeof(externip.sin_addr)); + } time(&externexpire); } else if (!strcasecmp(v->name, "externrefresh")) { if (sscanf(v->value, "%d", &externrefresh) != 1) { @@ -11026,20 +11002,21 @@ } else if (!strcasecmp(v->name, "recordhistory")) { recordhistory = ast_true(v->value); } else if (!strcasecmp(v->name, "tos")) { - if (sscanf(v->value, "%d", &format) == 1) + if (sscanf(v->value, "%d", &format) == 1) { tos = format & 0xff; - else if (!strcasecmp(v->value, "lowdelay")) + } else if (!strcasecmp(v->value, "lowdelay")) { tos = IPTOS_LOWDELAY; - else if (!strcasecmp(v->value, "throughput")) + } else if (!strcasecmp(v->value, "throughput")) { tos = IPTOS_THROUGHPUT; - else if (!strcasecmp(v->value, "reliability")) + } else if (!strcasecmp(v->value, "reliability")) { tos = IPTOS_RELIABILITY; - else if (!strcasecmp(v->value, "mincost")) + } else if (!strcasecmp(v->value, "mincost")) { tos = IPTOS_MINCOST; - else if (!strcasecmp(v->value, "none")) + } else if (!strcasecmp(v->value, "none")) { tos = 0; - else + } else { ast_log(LOG_WARNING, "Invalid tos value at line %d, should be 'lowdelay', 'throughput', 'reliability', 'mincost', or 'none'\n", v->lineno); + } } else if (!strcasecmp(v->name, "bindport")) { if (sscanf(v->value, "%d", &ourport) == 1) { bindaddr.sin_port = htons(ourport); @@ -11058,39 +11035,39 @@ } else if (!strcasecmp(v->name, "callevents")) { callevents = ast_true(v->value); } - /* else if (strcasecmp(v->name,"type")) + /* else if (strcasecmp(v->name, "type")) * ast_log(LOG_WARNING, "Ignoring %s\n", v->name); */ - v = v->next; + v = v->next; } - + /* Build list of authentication to various SIP realms, i.e. service providers */ - v = ast_variable_browse(cfg, "authentication"); - while(v) { - /* Format for authentication is auth = username:password@realm */ - if (!strcasecmp(v->name, "auth")) { - authl = add_realm_authentication(authl, v->value, v->lineno); - } - v = v->next; - } - + v = ast_variable_browse(cfg, "authentication"); + while (v) { + /* Format for authentication is auth = username:password@realm */ + if (!strcasecmp(v->name, "auth")) { + authl = add_realm_authentication(authl, v->value, v->lineno); + } + v = v->next; + } + /* Load peers, users and friends */ cat = ast_category_browse(cfg, NULL); - while(cat) { + while (cat) { if (strcasecmp(cat, "general") && strcasecmp(cat, "authentication")) { utype = ast_variable_retrieve(cfg, cat, "type"); if (utype) { if (!strcasecmp(utype, "user") || !strcasecmp(utype, "friend")) { user = build_user(cat, ast_variable_browse(cfg, cat), 0); if (user) { - ASTOBJ_CONTAINER_LINK(&userl,user); + ASTOBJ_CONTAINER_LINK(&userl, user); ASTOBJ_UNREF(user, sip_destroy_user); } } if (!strcasecmp(utype, "peer") || !strcasecmp(utype, "friend")) { peer = build_peer(cat, ast_variable_browse(cfg, cat), 0); if (peer) { - ASTOBJ_CONTAINER_LINK(&peerl,peer); + ASTOBJ_CONTAINER_LINK(&peerl, peer); ASTOBJ_UNREF(peer, sip_destroy_peer); } } else if (strcasecmp(utype, "user")) { @@ -11121,9 +11098,8 @@ /* Allow SIP clients on the same host to access us: */ const int reuseFlag = 1; setsockopt(sipsock, SOL_SOCKET, SO_REUSEADDR, - (const char*)&reuseFlag, - sizeof reuseFlag); - + (const char*)&reuseFlag, + sizeof reuseFlag); if (bind(sipsock, (struct sockaddr *)&bindaddr, sizeof(bindaddr)) < 0) { ast_log(LOG_WARNING, "Failed to bind to %s:%d: %s\n", ast_inet_ntoa(iabuf, sizeof(iabuf), bindaddr.sin_addr), ntohs(bindaddr.sin_port), @@ -11131,13 +11107,14 @@ close(sipsock); sipsock = -1; } else { - if (option_verbose > 1) { - ast_verbose(VERBOSE_PREFIX_2 "SIP Listening on %s:%d\n", + if (option_verbose > 1) { + ast_verbose(VERBOSE_PREFIX_2 "SIP Listening on %s:%d\n", ast_inet_ntoa(iabuf, sizeof(iabuf), bindaddr.sin_addr), ntohs(bindaddr.sin_port)); ast_verbose(VERBOSE_PREFIX_2 "Using TOS bits %d\n", tos); } - if (setsockopt(sipsock, IPPROTO_IP, IP_TOS, &tos, sizeof(tos))) + if (setsockopt(sipsock, IPPROTO_IP, IP_TOS, &tos, sizeof(tos))) { ast_log(LOG_WARNING, "Unable to set TOS to %d\n", tos); + } } } } @@ -11209,7 +11186,7 @@ transmit_reinvite_with_sdp(p); else if (!ast_test_flag(p, SIP_PENDINGBYE)) { ast_log(LOG_DEBUG, "Deferring reinvite on '%s'\n", p->callid); - ast_set_flag(p, SIP_NEEDREINVITE); + ast_set_flag(p, SIP_NEEDREINVITE); } } /* Reset lastrtprx timer */ @@ -11226,7 +11203,6 @@ static char *app_sipaddheader = "SIPAddHeader"; static char *synopsis_sipaddheader = "Add a SIP header to the outbound call"; - static char *descrip_sipaddheader = "" " SIPAddHeader(Header: Content)\n" "Adds a header to a SIP call placed with DIAL.\n" @@ -11237,7 +11213,7 @@ static char *app_sipgetheader = "SIPGetHeader"; static char *synopsis_sipgetheader = "Get a SIP header from an incoming call"; - + static char *descrip_sipgetheader = "" " SIPGetHeader(var=headername): \n" "Sets a channel variable to the content of a SIP header\n" @@ -11267,17 +11243,18 @@ return 0; } ast_mutex_lock(&p->lock); - if (!strcasecmp(mode,"info")) { + if (!strcasecmp(mode, "info")) { ast_clear_flag(p, SIP_DTMF); ast_set_flag(p, SIP_DTMF_INFO); - } else if (!strcasecmp(mode,"rfc2833")) { + } else if (!strcasecmp(mode, "rfc2833")) { ast_clear_flag(p, SIP_DTMF); ast_set_flag(p, SIP_DTMF_RFC2833); - } else if (!strcasecmp(mode,"inband")) { + } else if (!strcasecmp(mode, "inband")) { ast_clear_flag(p, SIP_DTMF); ast_set_flag(p, SIP_DTMF_INBAND); - } else - ast_log(LOG_WARNING, "I don't know about this dtmf mode: %s\n",mode); + } else { + ast_log(LOG_WARNING, "I don't know about this dtmf mode: %s\n", mode); + } if (ast_test_flag(p, SIP_DTMF) == SIP_DTMF_INBAND) { if (!p->vad) { p->vad = ast_dsp_new(); @@ -11302,7 +11279,7 @@ int ok = 0; char *content = (char *) NULL; char varbuf[128]; - + arglen = strlen(data); if (!arglen) { ast_log(LOG_WARNING, "This application requires the argument: Header\n"); @@ -11327,7 +11304,7 @@ if (ok) { pbx_builtin_setvar_helper (chan, varbuf, data); if (sipdebug) - ast_log(LOG_DEBUG,"SIP Header added \"%s\" as %s\n", (char *) data, varbuf); + ast_log(LOG_DEBUG, "SIP Header added \"%s\" as %s\n", (char *) data, varbuf); } else { ast_log(LOG_WARNING, "Too many SIP headers added, max 50\n"); } @@ -11341,7 +11318,7 @@ static int dep_warning = 0; struct sip_pvt *p; char *argv, *varname = NULL, *header = NULL, *content; - + if (!dep_warning) { ast_log(LOG_WARNING, "SIPGetHeader is deprecated, use the SIP_HEADER function instead.\n"); dep_warning = 1; @@ -11353,7 +11330,7 @@ return 0; } - if (strchr (argv, '=') ) { /* Pick out argumenet */ + if (strchr (argv, '=')) { /* Pick out argumenet */ varname = strsep (&argv, "="); header = strsep (&argv, "\0"); } @@ -11375,10 +11352,10 @@ if (!ast_strlen_zero(content)) { pbx_builtin_setvar_helper(chan, varname, content); } else { - ast_log(LOG_WARNING,"SIP Header %s not found for channel variable %s\n", header, varname); + ast_log(LOG_WARNING, "SIP Header %s not found for channel variable %s\n", header, varname); ast_goto_if_exists(chan, chan->context, chan->exten, chan->priority + 101); } - + ast_mutex_unlock(&chan->lock); return 0; } @@ -11392,7 +11369,7 @@ char *cdest; char *extension, *host, *port; char tmp[80]; - + cdest = ast_strdupa(dest); if (!cdest) { ast_log(LOG_ERROR, "Problem allocating the memory\n"); @@ -11466,7 +11443,7 @@ static int sip_get_codec(struct ast_channel *chan) { struct sip_pvt *p = chan->tech_pvt; - return p->peercapability; + return p->peercapability; } /*--- sip_rtp: Interface structure with callbacks used to connect to rtp module --*/ @@ -11527,12 +11504,12 @@ /*--- sip_reload: Force reload of module from cli ---*/ static int sip_reload(int fd, int argc, char *argv[]) { - ast_mutex_lock(&sip_reload_lock); if (sip_reloading) { ast_verbose("Previous SIP reload not yet done\n"); - } else + } else { sip_reloading = 1; + } ast_mutex_unlock(&sip_reload_lock); restart_monitor(); @@ -11560,12 +11537,9 @@ { { "sip", "debug", "peer", NULL }, sip_do_debug, "Enable SIP debugging on Peername", debug_usage, complete_sip_debug_peer }, { { "sip", "show", "peer", NULL }, sip_show_peer, "Show details on specific SIP peer", show_peer_usage, complete_sip_show_peer }, { { "sip", "show", "peers", NULL }, sip_show_peers, "Show defined SIP peers", show_peers_usage }, - { { "sip", "prune", "realtime", NULL }, sip_prune_realtime, - "Prune cached Realtime object(s)", prune_realtime_usage }, - { { "sip", "prune", "realtime", "peer", NULL }, sip_prune_realtime, - "Prune cached Realtime peer(s)", prune_realtime_usage, complete_sip_prune_realtime_peer }, - { { "sip", "prune", "realtime", "user", NULL }, sip_prune_realtime, - "Prune cached Realtime user(s)", prune_realtime_usage, complete_sip_prune_realtime_user }, + { { "sip", "prune", "realtime", NULL }, sip_prune_realtime, "Prune cached Realtime object(s)", prune_realtime_usage }, + { { "sip", "prune", "realtime", "peer", NULL }, sip_prune_realtime, "Prune cached Realtime peer(s)", prune_realtime_usage, complete_sip_prune_realtime_peer }, + { { "sip", "prune", "realtime", "user", NULL }, sip_prune_realtime, "Prune cached Realtime user(s)", prune_realtime_usage, complete_sip_prune_realtime_user }, { { "sip", "show", "inuse", NULL }, sip_show_inuse, "List all inuse/limits", show_inuse_usage }, { { "sip", "show", "registry", NULL }, sip_show_registry, "Show SIP registration status", show_reg_usage }, { { "sip", "history", NULL }, sip_do_history, "Enable SIP history", history_usage }, @@ -11619,13 +11593,13 @@ /* Register manager commands */ ast_manager_register2("SIPpeers", EVENT_FLAG_SYSTEM, manager_sip_show_peers, - "List SIP peers (text format)", mandescr_show_peers); + "List SIP peers (text format)", mandescr_show_peers); ast_manager_register2("SIPshowpeer", EVENT_FLAG_SYSTEM, manager_sip_show_peer, - "Show SIP peer (text format)", mandescr_show_peer); + "Show SIP peer (text format)", mandescr_show_peer); - sip_poke_all_peers(); + sip_poke_all_peers(); sip_send_all_registers(); - + /* And start the monitor for the first time */ restart_monitor(); @@ -11635,7 +11609,7 @@ int unload_module() { struct sip_pvt *p, *pl; - + /* First, take us out of the channel type list */ ast_channel_unregister(&sip_tech); @@ -11714,7 +11688,7 @@ clear_realm_authentication(authl); close(sipsock); - + return 0; } @@ -11732,5 +11706,3 @@ { return (char *) desc; } - -