Review Board 1.7.16


SIP: peer matching by callbackextension

Review Request #344 - Created Aug. 27, 2009 and submitted

David Vossel
/trunk
14340
Reviewers
asterisk-dev
Asterisk
If there are a number of peers with different callbackextension parameters and the same host address.  The first peer found matching the address is used regardless if that peer's callbackextension matches the incoming extension or not.

Now, to better match peers with incoming calls, if an incoming call's address can match multiple peers by address, we check each of those peer's callbackextension against the incoming extension for the best possible match.

It is possible that my implementation may be too expensive and only serve to address a minor edge case in the usage of chan_sip.  I do not fully understand the impact my changes may have upon performance when a large number of peers are present.  This patch assumes the new parse_uri() change has been made.

-------------------------------------------
for example with two peers as follows
[trunk1]
host=sip.myitsp.com
callbackextension=9991
...
[trunk2]
host=sip.myitsp.com
callbackextension=9992
...

incoming calls to 9991 and to 9992 are both matched to the peer trunk1
--------------------------------------------
Tested multiple peers with the same address containing different callbackextensions. Verified the correct peers were matched with incoming calls.

Changes between revision 2 and 3

1 2 3 4 5
1 2 3 4 5

  1. /trunk/channels/chan_sip.c: Loading...
/trunk/channels/chan_sip.c
Diff Revision 2 Diff Revision 3
[20] 1225 lines
[+20] [+] static int global_prematuremediafilter; /*!< Enable/disable premature frames in a call (causing 183 early media) */
1226
static int global_rtpholdtimeout;	/*!< Time out call if no RTP during hold */
1226
static int global_rtpholdtimeout;	/*!< Time out call if no RTP during hold */
1227
static int global_rtpkeepalive;		/*!< Send RTP keepalives */
1227
static int global_rtpkeepalive;		/*!< Send RTP keepalives */
1228
static int global_reg_timeout;		/*!< Global time between attempts for outbound registrations */
1228
static int global_reg_timeout;		/*!< Global time between attempts for outbound registrations */
1229
static int global_regattempts_max;	/*!< Registration attempts before giving up */
1229
static int global_regattempts_max;	/*!< Registration attempts before giving up */
1230
static int global_callcounter;		/*!< Enable call counters for all devices. This is currently enabled by setting the peer
1230
static int global_callcounter;		/*!< Enable call counters for all devices. This is currently enabled by setting the peer
1231
						call-limit to UINT_MAX. When we remove the call-limit from the code, we can make it
1231
						call-limit to INT_MAX. When we remove the call-limit from the code, we can make it
1232
						with just a boolean flag in the device structure */
1232
						with just a boolean flag in the device structure */
1233
static unsigned int global_tos_sip;		/*!< IP type of service for SIP packets */
1233
static unsigned int global_tos_sip;		/*!< IP type of service for SIP packets */
1234
static unsigned int global_tos_audio;		/*!< IP type of service for audio RTP packets */
1234
static unsigned int global_tos_audio;		/*!< IP type of service for audio RTP packets */
1235
static unsigned int global_tos_video;		/*!< IP type of service for video RTP packets */
1235
static unsigned int global_tos_video;		/*!< IP type of service for video RTP packets */
1236
static unsigned int global_tos_text;		/*!< IP type of service for text RTP packets */
1236
static unsigned int global_tos_text;		/*!< IP type of service for text RTP packets */
[+20] [20] 264 lines
[+20] [+] struct sip_auth {
1501
/* realtime flags */
1501
/* realtime flags */
1502
#define SIP_PAGE2_RTCACHEFRIENDS	(1 << 0)	/*!< GP: Should we keep RT objects in memory for extended time? */
1502
#define SIP_PAGE2_RTCACHEFRIENDS	(1 << 0)	/*!< GP: Should we keep RT objects in memory for extended time? */
1503
#define SIP_PAGE2_RTAUTOCLEAR		(1 << 2)	/*!< GP: Should we clean memory from peers after expiry? */
1503
#define SIP_PAGE2_RTAUTOCLEAR		(1 << 2)	/*!< GP: Should we clean memory from peers after expiry? */
1504
#define SIP_PAGE2_RPID_UPDATE		(1 << 3)
1504
#define SIP_PAGE2_RPID_UPDATE		(1 << 3)
1505
/* Space for addition of other realtime flags in the future */
1505
/* Space for addition of other realtime flags in the future */

    
   
1506
#define SIP_PAGE2_CONSTANT_SSRC         (1 << 7)       /*!< GDP: Don't change SSRC on reinvite */
1506
#define SIP_PAGE2_SYMMETRICRTP          (1 << 8)        /*!< GDP: Whether symmetric RTP is enabled or not */
1507
#define SIP_PAGE2_SYMMETRICRTP          (1 << 8)        /*!< GDP: Whether symmetric RTP is enabled or not */
1507
#define SIP_PAGE2_STATECHANGEQUEUE	(1 << 9)	/*!< D: Unsent state pending change exists */
1508
#define SIP_PAGE2_STATECHANGEQUEUE	(1 << 9)	/*!< D: Unsent state pending change exists */
1508

    
   
1509

   
1509
#define SIP_PAGE2_CONNECTLINEUPDATE_PEND		(1 << 10)
1510
#define SIP_PAGE2_CONNECTLINEUPDATE_PEND		(1 << 10)
1510
#define SIP_PAGE2_RPID_IMMEDIATE			(1 << 11)
1511
#define SIP_PAGE2_RPID_IMMEDIATE			(1 << 11)
[+20] [20] 27 lines
[+20] struct sip_auth {
1538
#define SIP_PAGE2_FLAGS_TO_COPY \
1539
#define SIP_PAGE2_FLAGS_TO_COPY \
1539
	(SIP_PAGE2_ALLOWSUBSCRIBE | SIP_PAGE2_ALLOWOVERLAP | SIP_PAGE2_IGNORESDPVERSION | \
1540
	(SIP_PAGE2_ALLOWSUBSCRIBE | SIP_PAGE2_ALLOWOVERLAP | SIP_PAGE2_IGNORESDPVERSION | \
1540
	SIP_PAGE2_VIDEOSUPPORT | SIP_PAGE2_T38SUPPORT | SIP_PAGE2_RFC2833_COMPENSATE | \
1541
	SIP_PAGE2_VIDEOSUPPORT | SIP_PAGE2_T38SUPPORT | SIP_PAGE2_RFC2833_COMPENSATE | \
1541
	SIP_PAGE2_BUGGY_MWI | SIP_PAGE2_TEXTSUPPORT | SIP_PAGE2_FAX_DETECT | \
1542
	SIP_PAGE2_BUGGY_MWI | SIP_PAGE2_TEXTSUPPORT | SIP_PAGE2_FAX_DETECT | \
1542
	SIP_PAGE2_UDPTL_DESTINATION | SIP_PAGE2_VIDEOSUPPORT_ALWAYS | SIP_PAGE2_PREFERRED_CODEC | \
1543
	SIP_PAGE2_UDPTL_DESTINATION | SIP_PAGE2_VIDEOSUPPORT_ALWAYS | SIP_PAGE2_PREFERRED_CODEC | \
1543
	SIP_PAGE2_RPID_IMMEDIATE | SIP_PAGE2_RPID_UPDATE | SIP_PAGE2_SYMMETRICRTP)
1544
	SIP_PAGE2_RPID_IMMEDIATE | SIP_PAGE2_RPID_UPDATE | SIP_PAGE2_SYMMETRICRTP | SIP_PAGE2_CONSTANT_SSRC)
1544

    
   
1545

   
1545
/*@}*/
1546
/*@}*/
1546

    
   
1547

   
1547
/*! \brief debugging state
1548
/*! \brief debugging state
1548
 * We store separately the debugging requests from the config file
1549
 * We store separately the debugging requests from the config file
[+20] [20] 224 lines
[+20] [+] struct sip_pvt {
1773
	int sessionversion;			/*!< SDP Session Version */
1774
	int sessionversion;			/*!< SDP Session Version */
1774
	int sessionid;				/*!< SDP Session ID */
1775
	int sessionid;				/*!< SDP Session ID */
1775
	long branch;				/*!< The branch identifier of this session */
1776
	long branch;				/*!< The branch identifier of this session */
1776
	long invite_branch;			/*!< The branch used when we sent the initial INVITE */
1777
	long invite_branch;			/*!< The branch used when we sent the initial INVITE */
1777
	int64_t sessionversion_remote;		/*!< Remote UA's SDP Session Version */
1778
	int64_t sessionversion_remote;		/*!< Remote UA's SDP Session Version */

    
   
1779
	unsigned int portinuri:1;		/*!< Non zero if a port has been specified, will also disable srv lookups */
1778
	struct sockaddr_in sa;			/*!< Our peer */
1780
	struct sockaddr_in sa;			/*!< Our peer */
1779
	struct sockaddr_in redirip;		/*!< Where our RTP should be going if not to us */
1781
	struct sockaddr_in redirip;		/*!< Where our RTP should be going if not to us */
1780
	struct sockaddr_in vredirip;		/*!< Where our Video RTP should be going if not to us */
1782
	struct sockaddr_in vredirip;		/*!< Where our Video RTP should be going if not to us */
1781
	struct sockaddr_in tredirip;		/*!< Where our Text RTP should be going if not to us */
1783
	struct sockaddr_in tredirip;		/*!< Where our Text RTP should be going if not to us */
1782
	time_t lastrtprx;			/*!< Last RTP received */
1784
	time_t lastrtprx;			/*!< Last RTP received */
[+20] [20] 137 lines
[+20] [+] static struct sip_pvt *dialog_unref(struct sip_pvt *p, char *tag)
1920
 * Each packet holds a reference to the parent struct sip_pvt.
1922
 * Each packet holds a reference to the parent struct sip_pvt.
1921
 * This structure is allocated in __sip_reliable_xmit() and only for packets that
1923
 * This structure is allocated in __sip_reliable_xmit() and only for packets that
1922
 * require retransmissions.
1924
 * require retransmissions.
1923
 */
1925
 */
1924
struct sip_pkt {
1926
struct sip_pkt {
1925
	struct sip_pkt *next;			/*!< Next packet in linked list */
1927
	struct sip_pkt *next;		/*!< Next packet in linked list */
1926
	int retrans;				/*!< Retransmission number */
1928
	int retrans;			/*!< Retransmission number */
1927
	int method;				/*!< SIP method for this packet */
1929
	int method;			/*!< SIP method for this packet */
1928
	int seqno;				/*!< Sequence number */
1930
	int seqno;			/*!< Sequence number */
1929
	char is_resp;				/*!< 1 if this is a response packet (e.g. 200 OK), 0 if it is a request */
1931
	char is_resp;			/*!< 1 if this is a response packet (e.g. 200 OK), 0 if it is a request */
1930
	char is_fatal;				/*!< non-zero if there is a fatal error */
1932
	char is_fatal;			/*!< non-zero if there is a fatal error */
1931
	int response_code;		/*!< If this is a response, the response code */
1933
	int response_code;		/*!< If this is a response, the response code */
1932
	struct sip_pvt *owner;			/*!< Owner AST call */
1934
	struct sip_pvt *owner;		/*!< Owner AST call */
1933
	int retransid;				/*!< Retransmission ID */
1935
	int retransid;			/*!< Retransmission ID */
1934
	int timer_a;				/*!< SIP timer A, retransmission timer */
1936
	int timer_a;			/*!< SIP timer A, retransmission timer */
1935
	int timer_t1;				/*!< SIP Timer T1, estimated RTT or 500 ms */
1937
	int timer_t1;			/*!< SIP Timer T1, estimated RTT or 500 ms */
1936
	int packetlen;				/*!< Length of packet */
1938
	int packetlen;			/*!< Length of packet */
1937
	struct ast_str *data;
1939
	struct ast_str *data;
1938
};	
1940
};	
1939

    
   
1941

   
1940
/*!
1942
/*!
1941
 * \brief A peer's mailbox
1943
 * \brief A peer's mailbox
[+20] [20] 85 lines
[+20] [+] struct sip_peer {
2027
	ast_group_t callgroup;		/*!<  Call group */
2029
	ast_group_t callgroup;		/*!<  Call group */
2028
	ast_group_t pickupgroup;	/*!<  Pickup group */
2030
	ast_group_t pickupgroup;	/*!<  Pickup group */
2029
	struct sip_proxy *outboundproxy;	/*!< Outbound proxy for this peer */
2031
	struct sip_proxy *outboundproxy;	/*!< Outbound proxy for this peer */
2030
	struct ast_dnsmgr_entry *dnsmgr;/*!<  DNS refresh manager for peer */
2032
	struct ast_dnsmgr_entry *dnsmgr;/*!<  DNS refresh manager for peer */
2031
	struct sockaddr_in addr;	/*!<  IP address of peer */
2033
	struct sockaddr_in addr;	/*!<  IP address of peer */

    
   
2034
	unsigned int portinuri:1;	/*!< Whether the port should be included in the URI */
2032
	struct sip_pvt *call;		/*!<  Call pointer */
2035
	struct sip_pvt *call;		/*!<  Call pointer */
2033
	int pokeexpire;			/*!<  Qualification: When to expire poke (qualify= checking) */
2036
	int pokeexpire;			/*!<  Qualification: When to expire poke (qualify= checking) */
2034
	int lastms;			/*!<  Qualification: How long last response took (in ms), or -1 for no response */
2037
	int lastms;			/*!<  Qualification: How long last response took (in ms), or -1 for no response */
2035
	int maxms;			/*!<  Qualification: Max ms we will accept for the host to be up, 0 to not monitor */
2038
	int maxms;			/*!<  Qualification: Max ms we will accept for the host to be up, 0 to not monitor */
2036
	int qualifyfreq;		/*!<  Qualification: Qualification: How often to check for the host to be up */
2039
	int qualifyfreq;		/*!<  Qualification: Qualification: How often to check for the host to be up */
[+20] [20] 528 lines
[+20] [+] static void sip_dump_history(struct sip_pvt *dialog); /* Dump history to debuglog at end of dialog, before destroying data */
2565
static inline int sip_debug_test_pvt(struct sip_pvt *p);
2568
static inline int sip_debug_test_pvt(struct sip_pvt *p);
2566
static void append_history_full(struct sip_pvt *p, const char *fmt, ...);
2569
static void append_history_full(struct sip_pvt *p, const char *fmt, ...);
2567
static void sip_dump_history(struct sip_pvt *dialog);
2570
static void sip_dump_history(struct sip_pvt *dialog);
2568

    
   
2571

   
2569
/*--- Device object handling */
2572
/*--- Device object handling */
2570
static struct sip_peer *build_peer(const char *name, struct ast_variable *v, struct ast_variable *alt, int realtime);
2573
static struct sip_peer *build_peer(const char *name, struct ast_variable *v, struct ast_variable *alt, int realtime, int devstate_only);
2571
static int update_call_counter(struct sip_pvt *fup, int event);
2574
static int update_call_counter(struct sip_pvt *fup, int event);
2572
static void sip_destroy_peer(struct sip_peer *peer);
2575
static void sip_destroy_peer(struct sip_peer *peer);
2573
static void sip_destroy_peer_fn(void *peer);
2576
static void sip_destroy_peer_fn(void *peer);
2574
static void set_peer_defaults(struct sip_peer *peer);
2577
static void set_peer_defaults(struct sip_peer *peer);
2575
static struct sip_peer *temp_peer(const char *name);
2578
static struct sip_peer *temp_peer(const char *name);
[+20] [20] 108 lines
[+20] [+] static int handle_request_bye(struct sip_pvt *p, struct sip_request *req);
2684
static int handle_request_cancel(struct sip_pvt *p, struct sip_request *req);
2687
static int handle_request_cancel(struct sip_pvt *p, struct sip_request *req);
2685
static int handle_request_message(struct sip_pvt *p, struct sip_request *req);
2688
static int handle_request_message(struct sip_pvt *p, struct sip_request *req);
2686
static int handle_request_subscribe(struct sip_pvt *p, struct sip_request *req, struct sockaddr_in *sin, int seqno, const char *e);
2689
static int handle_request_subscribe(struct sip_pvt *p, struct sip_request *req, struct sockaddr_in *sin, int seqno, const char *e);
2687
static void handle_request_info(struct sip_pvt *p, struct sip_request *req);
2690
static void handle_request_info(struct sip_pvt *p, struct sip_request *req);
2688
static int handle_request_options(struct sip_pvt *p, struct sip_request *req);
2691
static int handle_request_options(struct sip_pvt *p, struct sip_request *req);
2689
static int handle_invite_replaces(struct sip_pvt *p, struct sip_request *req, int debug, int seqno, struct sockaddr_in *sin);
2692
static int handle_invite_replaces(struct sip_pvt *p, struct sip_request *req, int debug, int seqno, struct sockaddr_in *sin, int *nounlock);
2690
static int handle_request_notify(struct sip_pvt *p, struct sip_request *req, struct sockaddr_in *sin, int seqno, const char *e);
2693
static int handle_request_notify(struct sip_pvt *p, struct sip_request *req, struct sockaddr_in *sin, int seqno, const char *e);
2691
static int local_attended_transfer(struct sip_pvt *transferer, struct sip_dual *current, struct sip_request *req, int seqno);
2694
static int local_attended_transfer(struct sip_pvt *transferer, struct sip_dual *current, struct sip_request *req, int seqno);
2692

    
   
2695

   
2693
/*------Response handling functions */
2696
/*------Response handling functions */
2694
static void handle_response_invite(struct sip_pvt *p, int resp, const char *rest, struct sip_request *req, int seqno);
2697
static void handle_response_invite(struct sip_pvt *p, int resp, const char *rest, struct sip_request *req, int seqno);
[+20] [20] 266 lines
[+20] [+] static void *_sip_tcp_helper_thread(struct sip_pvt *pvt, struct ast_tcptls_session_instance *tcptls_session)
2961
		copy_request(&reqcpy, &req);
2964
		copy_request(&reqcpy, &req);
2962
		parse_request(&reqcpy);
2965
		parse_request(&reqcpy);
2963
		/* In order to know how much to read, we need the content-length header */
2966
		/* In order to know how much to read, we need the content-length header */
2964
		if (sscanf(get_header(&reqcpy, "Content-Length"), "%30d", &cl)) {
2967
		if (sscanf(get_header(&reqcpy, "Content-Length"), "%30d", &cl)) {
2965
			while (cl > 0) {
2968
			while (cl > 0) {

    
   
2969
				size_t bytes_read;
2966
				ast_mutex_lock(&tcptls_session->lock);
2970
				ast_mutex_lock(&tcptls_session->lock);
2967
				if (!fread(buf, (cl < sizeof(buf)) ? cl : sizeof(buf), 1, tcptls_session->f)) {
2971
				if (!(bytes_read = fread(buf, 1, MIN(sizeof(buf) - 1, cl), tcptls_session->f))) {
2968
					ast_mutex_unlock(&tcptls_session->lock);
2972
					ast_mutex_unlock(&tcptls_session->lock);
2969
					goto cleanup;
2973
					goto cleanup;
2970
				}
2974
				}

    
   
2975
				buf[bytes_read] = '\0';
2971
				ast_mutex_unlock(&tcptls_session->lock);
2976
				ast_mutex_unlock(&tcptls_session->lock);
2972
				if (me->stop)
2977
				if (me->stop)
2973
					goto cleanup;
2978
					goto cleanup;
2974
				cl -= strlen(buf);
2979
				cl -= strlen(buf);
2975
				ast_str_append(&req.data, 0, "%s", buf);
2980
				ast_str_append(&req.data, 0, "%s", buf);
[+20] [20] 232 lines
[+20] [+] static int proxy_update(struct sip_proxy *proxy)
3208
 *  to an int value, the port provided as the standard is used.
3213
 *  to an int value, the port provided as the standard is used.
3209
 */
3214
 */
3210
static int port_str2int(const char *pt, unsigned int standard)
3215
static int port_str2int(const char *pt, unsigned int standard)
3211
{
3216
{
3212
	int port = standard;
3217
	int port = standard;
3213
	if (ast_strlen_zero(pt) || (sscanf(pt, "%30d", &port) != 1) || (port < 0)) {
3218
	if (ast_strlen_zero(pt) || (sscanf(pt, "%30d", &port) != 1) || (port < 1) || (port > 65535)) {
3214
		port = standard;
3219
		port = standard;
3215
	}
3220
	}
3216

    
   
3221

   
3217
	return port;
3222
	return port;
3218
}
3223
}
[+20] [20] 252 lines
[+20] [+] static int __sip_xmit(struct sip_pvt *p, struct ast_str *data, int len)
3471
	} else if (p->socket.tcptls_session) {
3476
	} else if (p->socket.tcptls_session) {
3472
		if (p->socket.tcptls_session->f) {
3477
		if (p->socket.tcptls_session->f) {
3473
			res = ast_tcptls_server_write(p->socket.tcptls_session, data->str, len);
3478
			res = ast_tcptls_server_write(p->socket.tcptls_session, data->str, len);
3474
		} else {
3479
		} else {
3475
			ast_debug(2, "No p->socket.tcptls_session->f len=%d\n", len);
3480
			ast_debug(2, "No p->socket.tcptls_session->f len=%d\n", len);

    
   
3481
			return XMIT_ERROR;
3476
		}
3482
		}
3477
	} else {
3483
	} else {
3478
		ast_debug(2, "Socket type is TCP but no tcptls_session is present to write to\n");
3484
		ast_debug(2, "Socket type is TCP but no tcptls_session is present to write to\n");
3479
		return XMIT_ERROR;
3485
		return XMIT_ERROR;
3480
	}
3486
	}
[+20] [20] 1274 lines
[+20] [+] static struct sip_peer *realtime_peer(const char *newpeername, struct sockaddr_in *sin, int devstate_only)
4755
			if (var && sin) {
4761
			if (var && sin) {
4756
				for (tmp = var; tmp; tmp = tmp->next) {
4762
				for (tmp = var; tmp; tmp = tmp->next) {
4757
					if (!strcasecmp(tmp->name, "host")) {
4763
					if (!strcasecmp(tmp->name, "host")) {
4758
						struct hostent *hp;
4764
						struct hostent *hp;
4759
						struct ast_hostent ahp;
4765
						struct ast_hostent ahp;
4760
						if (!(hp = ast_gethostbyname(tmp->value, &ahp)) || (memcmp(&hp->h_addr, &sin->sin_addr, sizeof(hp->h_addr)))) {
4766
						if (!(hp = ast_gethostbyname(tmp->value, &ahp)) || (memcmp(hp->h_addr, &sin->sin_addr, sizeof(hp->h_addr)))) {
4761
							/* No match */
4767
							/* No match */
4762
							ast_variables_destroy(var);
4768
							ast_variables_destroy(var);
4763
							var = NULL;
4769
							var = NULL;
4764
						}
4770
						}
4765
						break;
4771
						break;
[+20] [20] 101 lines
[+20] static struct sip_peer *realtime_peer(const char *newpeername, struct sockaddr_in *sin, int devstate_only)
4867
		return NULL;
4873
		return NULL;
4868
	}
4874
	}
4869

    
   
4875

   
4870

    
   
4876

   
4871
	/* Peer found in realtime, now build it in memory */
4877
	/* Peer found in realtime, now build it in memory */
4872
	peer = build_peer(newpeername, var, varregs, TRUE);
4878
	peer = build_peer(newpeername, var, varregs, TRUE, devstate_only);
4873
	if (!peer) {
4879
	if (!peer) {
4874
		if(peerlist)
4880
		if(peerlist)
4875
			ast_config_destroy(peerlist);
4881
			ast_config_destroy(peerlist);
4876
		else {
4882
		else {
4877
			ast_variables_destroy(var);
4883
			ast_variables_destroy(var);
[+20] [20] 308 lines
[+20] [+] static int create_addr_from_peer(struct sip_pvt *dialog, struct sip_peer *peer)
5186
	}
5192
	}
5187

    
   
5193

   
5188
	if (dialog->rtp) { /* Audio */
5194
	if (dialog->rtp) { /* Audio */
5189
		ast_rtp_instance_set_prop(dialog->rtp, AST_RTP_PROPERTY_DTMF, ast_test_flag(&dialog->flags[0], SIP_DTMF) == SIP_DTMF_RFC2833);
5195
		ast_rtp_instance_set_prop(dialog->rtp, AST_RTP_PROPERTY_DTMF, ast_test_flag(&dialog->flags[0], SIP_DTMF) == SIP_DTMF_RFC2833);
5190
		ast_rtp_instance_set_prop(dialog->rtp, AST_RTP_PROPERTY_DTMF_COMPENSATE, ast_test_flag(&dialog->flags[1], SIP_PAGE2_RFC2833_COMPENSATE));
5196
		ast_rtp_instance_set_prop(dialog->rtp, AST_RTP_PROPERTY_DTMF_COMPENSATE, ast_test_flag(&dialog->flags[1], SIP_PAGE2_RFC2833_COMPENSATE));

    
   
5197
		ast_rtp_instance_set_prop(dialog->rtp, AST_RTP_PROPERTY_CONSTANT_SSRC, ast_test_flag(&dialog->flags[1], SIP_PAGE2_CONSTANT_SSRC));
5191
		ast_rtp_instance_set_timeout(dialog->rtp, peer->rtptimeout);
5198
		ast_rtp_instance_set_timeout(dialog->rtp, peer->rtptimeout);
5192
		ast_rtp_instance_set_hold_timeout(dialog->rtp, peer->rtpholdtimeout);
5199
		ast_rtp_instance_set_hold_timeout(dialog->rtp, peer->rtpholdtimeout);
5193
		/* Set Frame packetization */
5200
		/* Set Frame packetization */
5194
		ast_rtp_codecs_packetization_set(ast_rtp_instance_get_codecs(dialog->rtp), dialog->rtp, &dialog->prefs);
5201
		ast_rtp_codecs_packetization_set(ast_rtp_instance_get_codecs(dialog->rtp), dialog->rtp, &dialog->prefs);
5195
		dialog->autoframing = peer->autoframing;
5202
		dialog->autoframing = peer->autoframing;
5196
	}
5203
	}
5197
	if (dialog->vrtp) { /* Video */
5204
	if (dialog->vrtp) { /* Video */
5198
		ast_rtp_instance_set_timeout(dialog->vrtp, peer->rtptimeout);
5205
		ast_rtp_instance_set_timeout(dialog->vrtp, peer->rtptimeout);
5199
		ast_rtp_instance_set_hold_timeout(dialog->vrtp, peer->rtpholdtimeout);
5206
		ast_rtp_instance_set_hold_timeout(dialog->vrtp, peer->rtpholdtimeout);

    
   
5207
		ast_rtp_instance_set_prop(dialog->vrtp, AST_RTP_PROPERTY_CONSTANT_SSRC, ast_test_flag(&dialog->flags[1], SIP_PAGE2_CONSTANT_SSRC));
5200
	}
5208
	}
5201
	if (dialog->trtp) { /* Realtime text */
5209
	if (dialog->trtp) { /* Realtime text */
5202
		ast_rtp_instance_set_timeout(dialog->trtp, peer->rtptimeout);
5210
		ast_rtp_instance_set_timeout(dialog->trtp, peer->rtptimeout);
5203
		ast_rtp_instance_set_hold_timeout(dialog->trtp, peer->rtpholdtimeout);
5211
		ast_rtp_instance_set_hold_timeout(dialog->trtp, peer->rtpholdtimeout);
5204
	}
5212
	}
[+20] [20] 65 lines
[+20] static int create_addr_from_peer(struct sip_pvt *dialog, struct sip_peer *peer)
5270
		dialog->noncodeccapability |= AST_RTP_DTMF;
5278
		dialog->noncodeccapability |= AST_RTP_DTMF;
5271
	else
5279
	else
5272
		dialog->noncodeccapability &= ~AST_RTP_DTMF;
5280
		dialog->noncodeccapability &= ~AST_RTP_DTMF;
5273
	if (peer->call_limit)
5281
	if (peer->call_limit)
5274
		ast_set_flag(&dialog->flags[0], SIP_CALL_LIMIT);
5282
		ast_set_flag(&dialog->flags[0], SIP_CALL_LIMIT);

    
   
5283
	if (!dialog->portinuri)

    
   
5284
		dialog->portinuri = peer->portinuri;
5275
	
5285
	
5276
	dialog->chanvars = copy_vars(peer->chanvars);
5286
	dialog->chanvars = copy_vars(peer->chanvars);
5277

    
   
5287

   
5278
	return 0;
5288
	return 0;
5279
}
5289
}
[+20] [20] 12 lines
[+20] [+] static int create_addr(struct sip_pvt *dialog, const char *opeer, struct sockaddr_in *sin, int newdialog)
5292
	char peername[256];
5302
	char peername[256];
5293
	int srv_ret = 0;
5303
	int srv_ret = 0;
5294

    
   
5304

   
5295
	ast_copy_string(peername, opeer, sizeof(peername));
5305
	ast_copy_string(peername, opeer, sizeof(peername));
5296
	port = strchr(peername, ':');
5306
	port = strchr(peername, ':');
5297
	if (port)
5307
	if (port) {
5298
		*port++ = '\0';
5308
		*port++ = '\0';

    
   
5309
		dialog->portinuri = 1;

    
   
5310
	}
5299
	dialog->sa.sin_family = AF_INET;
5311
	dialog->sa.sin_family = AF_INET;
5300
	dialog->timer_t1 = global_t1; /* Default SIP retransmission timer T1 (RFC 3261) */
5312
	dialog->timer_t1 = global_t1; /* Default SIP retransmission timer T1 (RFC 3261) */
5301
	dialog->timer_b = global_timer_b; /* Default SIP transaction timer B (RFC 3261) */
5313
	dialog->timer_b = global_timer_b; /* Default SIP transaction timer B (RFC 3261) */
5302
	peer = find_peer(peername, NULL, TRUE, FINDPEERS, FALSE, 0);
5314
	peer = find_peer(peername, NULL, TRUE, FINDPEERS, FALSE, 0);
5303

    
   
5315

   
[+20] [20] 2289 lines
[+20] [+] static int sip_register(const char *value, int lineno)
7593
	 * host1.expiry => expiry
7605
	 * host1.expiry => expiry
7594
	 */
7606
	 */
7595
	AST_NONSTANDARD_RAW_ARGS(user2, user1.userpart, '@');
7607
	AST_NONSTANDARD_RAW_ARGS(user2, user1.userpart, '@');
7596

    
   
7608

   
7597
	if (host3.port) {
7609
	if (host3.port) {
7598
		if (sscanf(host3.port, "%5u", &portnum) != 1 || portnum > 65535) {
7610
		if (!(portnum = port_str2int(host3.port, 0))) {
7599
			ast_log(LOG_NOTICE, "'%s' is not a valid port number on line %d of sip.conf. using default.\n", host3.port, lineno);
7611
			ast_log(LOG_NOTICE, "'%s' is not a valid port number on line %d of sip.conf. using default.\n", host3.port, lineno);
7600
			portnum = -1;

   
7601
		}
7612
		}
7602
	}
7613
	}
7603

    
   
7614

   

    
   
7615
	/* set transport type */
7604
	if (!pre2.transport) {
7616
	if (!pre2.transport) {
7605
		transport = SIP_TRANSPORT_UDP;
7617
		transport = SIP_TRANSPORT_UDP;
7606
	} else if (!strncasecmp(pre2.transport, "tcp", 3)) {
7618
	} else if (!strncasecmp(pre2.transport, "tcp", 3)) {
7607
		transport = SIP_TRANSPORT_TCP;
7619
		transport = SIP_TRANSPORT_TCP;
7608
	} else if (!strncasecmp(pre2.transport, "tls", 3)) {
7620
	} else if (!strncasecmp(pre2.transport, "tls", 3)) {
7609
		transport = SIP_TRANSPORT_TLS;
7621
		transport = SIP_TRANSPORT_TLS;
7610
		if (portnum < 0) {

   
7611
			portnum = STANDARD_TLS_PORT;

   
7612
		}

   
7613
	} else if (!strncasecmp(pre2.transport, "udp", 3)) {
7622
	} else if (!strncasecmp(pre2.transport, "udp", 3)) {
7614
		transport = SIP_TRANSPORT_UDP;
7623
		transport = SIP_TRANSPORT_UDP;
7615
	} else {
7624
	} else {

    
   
7625
		transport = SIP_TRANSPORT_UDP;
7616
		ast_log(LOG_NOTICE, "'%.3s' is not a valid transport type on line %d of sip.conf. defaulting to udp.\n", pre2.transport, lineno);
7626
		ast_log(LOG_NOTICE, "'%.3s' is not a valid transport type on line %d of sip.conf. defaulting to udp.\n", pre2.transport, lineno);
7617
	}
7627
	}
7618

    
   
7628

   
7619
	if (portnum < 0) {
7629
	/* if no portnum specified, set default for transport */

    
   
7630
	if (!portnum) {

    
   
7631
		if (transport == SIP_TRANSPORT_TLS) {

    
   
7632
			portnum = STANDARD_TLS_PORT;

    
   
7633
		} else {
7620
		portnum = STANDARD_SIP_PORT;
7634
			portnum = STANDARD_SIP_PORT;
7621
	}
7635
		}

    
   
7636
	}
7622

    
   
7637

   
7623
	if (!(reg = ast_calloc(1, sizeof(*reg)))) {
7638
	if (!(reg = ast_calloc(1, sizeof(*reg)))) {
7624
		ast_log(LOG_ERROR, "Out of memory. Can't allocate SIP registry entry\n");
7639
		ast_log(LOG_ERROR, "Out of memory. Can't allocate SIP registry entry\n");
7625
		return -1;
7640
		return -1;
7626
	}
7641
	}
[+20] [20] 1723 lines
[+20] [+] static int respprep(struct sip_request *resp, struct sip_pvt *p, const char *msg, const struct sip_request *req)
9350

    
   
9365

   
9351
		snprintf(tmp, sizeof(tmp), "%d", p->expiry);
9366
		snprintf(tmp, sizeof(tmp), "%d", p->expiry);
9352
		add_header(resp, "Expires", tmp);
9367
		add_header(resp, "Expires", tmp);
9353
		if (p->expiry) {	/* Only add contact if we have an expiry time */
9368
		if (p->expiry) {	/* Only add contact if we have an expiry time */
9354
			char contact[SIPBUFSIZE];
9369
			char contact[SIPBUFSIZE];
9355
			snprintf(contact, sizeof(contact), "%s;expires=%d", p->our_contact, p->expiry);
9370
			snprintf(contact, sizeof(contact), "%s;expires=%d", (p->method == SIP_SUBSCRIBE ? p->our_contact : p->fullcontact), p->expiry);
9356
			add_header(resp, "Contact", contact);	/* Not when we unregister */
9371
			add_header(resp, "Contact", contact);	/* Not when we unregister */
9357
		}
9372
		}
9358
	} else if (!ast_strlen_zero(p->our_contact) && resp_needs_contact(msg, p->method)) {
9373
	} else if (!ast_strlen_zero(p->our_contact) && resp_needs_contact(msg, p->method)) {
9359
		add_header(resp, "Contact", p->our_contact);
9374
		add_header(resp, "Contact", p->our_contact);
9360
	}
9375
	}
[+20] [20] 25 lines
[+20] [+] static int reqprep(struct sip_request *req, struct sip_pvt *p, int sipmethod, int seqno, int newbranch)
9386
	if (!seqno) {
9401
	if (!seqno) {
9387
		p->ocseq++;
9402
		p->ocseq++;
9388
		seqno = p->ocseq;
9403
		seqno = p->ocseq;
9389
	}
9404
	}
9390
	
9405
	
9391
	/* A CANCEL must have the same branch as the INVITE that it is canceling.
9406
	/* A CANCEL must have the same branch as the INVITE that it is canceling. */
9392
	 * Similarly, if we need to re-send an INVITE with auth credentials, then we
9407
	if (sipmethod == SIP_CANCEL) {
9393
	 * need to use the same branch as we did the first time we sent the INVITE.

   
9394
	 */

   
9395
	if (sipmethod == SIP_CANCEL || (sipmethod == SIP_INVITE && p->options && !ast_strlen_zero(p->options->auth))) {

   
9396
		p->branch = p->invite_branch;
9408
		p->branch = p->invite_branch;
9397
		build_via(p);
9409
		build_via(p);

    
   
9410
	} else if (newbranch && (sipmethod == SIP_INVITE)) {

    
   
9411
		p->branch ^= ast_random();

    
   
9412
		p->invite_branch = p->branch;

    
   
9413
		build_via(p);
9398
	} else if (newbranch) {
9414
	} else if (newbranch) {
9399
		p->branch ^= ast_random();
9415
		p->branch ^= ast_random();
9400
		build_via(p);
9416
		build_via(p);
9401
	}
9417
	}
9402

    
   
9418

   
[+20] [20] 429 lines
[+20] [+] static int add_digit(struct sip_request *req, char digit, unsigned int duration, int mode)
9832
 * \brief Add Remote-Party-ID header to SIP message
9848
 * \brief Add Remote-Party-ID header to SIP message
9833
 */
9849
 */
9834
static int add_rpid(struct sip_request *req, struct sip_pvt *p)
9850
static int add_rpid(struct sip_request *req, struct sip_pvt *p)
9835
{
9851
{
9836
	struct ast_str *tmp = ast_str_alloca(256);
9852
	struct ast_str *tmp = ast_str_alloca(256);

    
   
9853
	char tmp2[256];
9837
	char *lid_num = NULL;
9854
	char *lid_num = NULL;
9838
	char *lid_name = NULL;
9855
	char *lid_name = NULL;
9839
	int lid_pres;
9856
	int lid_pres;
9840
	const char *fromdomain;
9857
	const char *fromdomain;
9841
	const char *privacy = NULL;
9858
	const char *privacy = NULL;
[+20] [20] 14 lines
[+20] static int add_rpid(struct sip_request *req, struct sip_pvt *p)
9856
		return 0;
9873
		return 0;
9857
	if (ast_strlen_zero(lid_name))
9874
	if (ast_strlen_zero(lid_name))
9858
		lid_name = lid_num;
9875
		lid_name = lid_num;
9859
	fromdomain = S_OR(p->fromdomain, ast_inet_ntoa(p->ourip.sin_addr));
9876
	fromdomain = S_OR(p->fromdomain, ast_inet_ntoa(p->ourip.sin_addr));
9860

    
   
9877

   

    
   
9878
	lid_num = ast_uri_encode(lid_num, tmp2, sizeof(tmp2), 1);

    
   
9879

   
9861
	if (ast_test_flag(&p->flags[0], SIP_SENDRPID_PAI)) {
9880
	if (ast_test_flag(&p->flags[0], SIP_SENDRPID_PAI)) {
9862
		if ((lid_pres & AST_PRES_RESTRICTION) != AST_PRES_ALLOWED) {
9881
		if ((lid_pres & AST_PRES_RESTRICTION) != AST_PRES_ALLOWED) {
9863
			ast_str_set(&tmp, -1, "%s", anonymous_string);
9882
			ast_str_set(&tmp, -1, "%s", anonymous_string);
9864
		} else {
9883
		} else {
9865
			ast_str_set(&tmp, -1, "\"%s\" <sip:%s@%s>", lid_name, lid_num, fromdomain);
9884
			ast_str_set(&tmp, -1, "\"%s\" <sip:%s@%s>", lid_name, lid_num, fromdomain);
[+20] [20] 927 lines
[+20] [+] static void initreqprep(struct sip_request *req, struct sip_pvt *p, int sipmethod)
10793
				n = tmp_n;
10812
				n = tmp_n;
10794
			}
10813
			}
10795
			ast_str_append(&invite, 0, "%s@", n);
10814
			ast_str_append(&invite, 0, "%s@", n);
10796
		}
10815
		}
10797
		ast_str_append(&invite, 0, "%s", p->tohost);
10816
		ast_str_append(&invite, 0, "%s", p->tohost);
10798
		if (ntohs(p->sa.sin_port) != STANDARD_SIP_PORT)
10817
		if (p->portinuri)
10799
			ast_str_append(&invite, 0, ":%d", ntohs(p->sa.sin_port));
10818
			ast_str_append(&invite, 0, ":%d", ntohs(p->sa.sin_port));
10800
		ast_str_append(&invite, 0, "%s", urioptions);
10819
		ast_str_append(&invite, 0, "%s", urioptions);
10801
	}
10820
	}
10802

    
   
10821

   
10803
	/* If custom URI options have been provided, append them */
10822
	/* If custom URI options have been provided, append them */
[+20] [20] 317 lines
[+20] [+] static int __sip_subscribe_mwi_do(struct sip_subscription_mwi *mwi)
11121
	transmit_invite(mwi->call, SIP_SUBSCRIBE, 0, 2);
11140
	transmit_invite(mwi->call, SIP_SUBSCRIBE, 0, 2);
11122

    
   
11141

   
11123
	return 0;
11142
	return 0;
11124
}
11143
}
11125

    
   
11144

   

    
   
11145
/*! \brief Find the channel that is causing the RINGING update */
11126
static int find_calling_channel(void *obj, void *arg, void *data, int flags)
11146
static int find_calling_channel(void *obj, void *arg, void *data, int flags)
11127
{
11147
{
11128
	struct ast_channel *c = obj;
11148
	struct ast_channel *c = obj;
11129
	struct sip_pvt *p = data;
11149
	struct sip_pvt *p = data;
11130
	int res;
11150
	int res;
[+20] [20] 7 lines
[+20] static int find_calling_channel(void *obj, void *arg, void *data, int flags)
11138
	ast_channel_unlock(c);
11158
	ast_channel_unlock(c);
11139

    
   
11159

   
11140
	return res ? CMP_MATCH | CMP_STOP : 0;
11160
	return res ? CMP_MATCH | CMP_STOP : 0;
11141
}
11161
}
11142

    
   
11162

   
11143
/*! \brief Builds XML portion of state NOTIFY messages */
11163
/*! \brief Builds XML portion of NOTIFY messages for presence or dialog updates */
11144
static void state_notify_build_xml(int state, int full, const char *exten, const char *context, struct ast_str **tmp, struct sip_pvt *p, int subscribed, const char *mfrom, const char *mto)
11164
static void state_notify_build_xml(int state, int full, const char *exten, const char *context, struct ast_str **tmp, struct sip_pvt *p, int subscribed, const char *mfrom, const char *mto)
11145
{
11165
{
11146
	enum state { NOTIFY_OPEN, NOTIFY_INUSE, NOTIFY_CLOSED } local_state = NOTIFY_OPEN;
11166
	enum state { NOTIFY_OPEN, NOTIFY_INUSE, NOTIFY_CLOSED } local_state = NOTIFY_OPEN;
11147
	const char *statestring = "terminated";
11167
	const char *statestring = "terminated";
11148
	const char *pidfstate = "--";
11168
	const char *pidfstate = "--";
[+20] [20] 1031 lines
[+20] [+] static int expire_register(const void *data)
12180

    
   
12200

   
12181
	if (!peer)		/* Hmmm. We have no peer. Weird. */
12201
	if (!peer)		/* Hmmm. We have no peer. Weird. */
12182
		return 0;
12202
		return 0;
12183

    
   
12203

   
12184
	peer->expire = -1;
12204
	peer->expire = -1;

    
   
12205
	peer->portinuri = 0;
12185
	memset(&peer->addr, 0, sizeof(peer->addr));
12206
	memset(&peer->addr, 0, sizeof(peer->addr));
12186

    
   
12207

   
12187
	destroy_association(peer);	/* remove registration data from storage */
12208
	destroy_association(peer);	/* remove registration data from storage */
12188
	set_socket_transport(&peer->socket, peer->default_outbound_transport);
12209
	set_socket_transport(&peer->socket, peer->default_outbound_transport);
12189

    
   
12210

   
[+20] [20] 241 lines
[+20] [+] static enum parse_register_result parse_register_contact(struct sip_pvt *pvt, struct sip_peer *peer, struct sip_request *req)
12431
		register_peer_exten(peer, FALSE);	/* Remove extension from regexten= setting in sip.conf */
12452
		register_peer_exten(peer, FALSE);	/* Remove extension from regexten= setting in sip.conf */
12432
		ast_string_field_set(peer, fullcontact, "");
12453
		ast_string_field_set(peer, fullcontact, "");
12433
		ast_string_field_set(peer, useragent, "");
12454
		ast_string_field_set(peer, useragent, "");
12434
		peer->sipoptions = 0;
12455
		peer->sipoptions = 0;
12435
		peer->lastms = 0;
12456
		peer->lastms = 0;

    
   
12457
		peer->portinuri = 0;
12436
		pvt->expiry = 0;
12458
		pvt->expiry = 0;
12437

    
   
12459

   
12438
		ast_verb(3, "Unregistered SIP '%s'\n", peer->name);
12460
		ast_verb(3, "Unregistered SIP '%s'\n", peer->name);
12439

    
   
12461

   
12440
		manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "ChannelType: SIP\r\nPeer: SIP/%s\r\nPeerStatus: Unregistered\r\n", peer->name);
12462
		manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "ChannelType: SIP\r\nPeer: SIP/%s\r\nPeerStatus: Unregistered\r\n", peer->name);
[+20] [20] 9 lines
[+20] static enum parse_register_result parse_register_contact(struct sip_pvt *pvt, struct sip_peer *peer, struct sip_request *req)
12450
	/* Make sure it's a SIP URL */
12472
	/* Make sure it's a SIP URL */
12451
	if (parse_uri(curi, "sip:,sips:", &curi, NULL, &host, &pt, NULL, &transport)) {
12473
	if (parse_uri(curi, "sip:,sips:", &curi, NULL, &host, &pt, NULL, &transport)) {
12452
		ast_log(LOG_NOTICE, "Not a valid SIP contact (missing sip:) trying to use anyway\n");
12474
		ast_log(LOG_NOTICE, "Not a valid SIP contact (missing sip:) trying to use anyway\n");
12453
	}
12475
	}
12454

    
   
12476

   

    
   
12477
	/* If we have a port number in the given URI, make sure we do remember to not check for NAPTR/SRV records. 

    
   
12478
	   The domain part is actually a host. */

    
   
12479
	peer->portinuri = !ast_strlen_zero(pt) ? TRUE : FALSE;

    
   
12480

   
12455
	/* handle the transport type specified in Contact header. */
12481
	/* handle the transport type specified in Contact header. */
12456
	if ((transport_type = get_transport_str2enum(transport))) {
12482
	if ((transport_type = get_transport_str2enum(transport))) {
12457
		/* if the port is not specified but the transport is, make sure to set the
12483
		/* if the port is not specified but the transport is, make sure to set the
12458
		 * default port to match the specified transport.  This may or may not be the
12484
		 * default port to match the specified transport.  This may or may not be the
12459
		 * same transport used by the pvt struct for the Register dialog. */
12485
		 * same transport used by the pvt struct for the Register dialog. */
[+20] [20] 715 lines
[+20] [+] static enum check_auth_result register_verify(struct sip_pvt *p, struct sockaddr_in *sin,
13175
						transmit_response_with_date(p, "400 Bad Request", req);
13201
						transmit_response_with_date(p, "400 Bad Request", req);
13176
						peer->lastmsgssent = -1;
13202
						peer->lastmsgssent = -1;
13177
						res = 0;
13203
						res = 0;
13178
						break;
13204
						break;
13179
					case PARSE_REGISTER_QUERY:
13205
					case PARSE_REGISTER_QUERY:

    
   
13206
						ast_string_field_set(p, fullcontact, peer->fullcontact);
13180
						transmit_response_with_date(p, "200 OK", req);
13207
						transmit_response_with_date(p, "200 OK", req);
13181
						peer->lastmsgssent = -1;
13208
						peer->lastmsgssent = -1;
13182
						res = 0;
13209
						res = 0;
13183
						break;
13210
						break;
13184
					case PARSE_REGISTER_UPDATE:
13211
					case PARSE_REGISTER_UPDATE:

    
   
13212
						ast_string_field_set(p, fullcontact, peer->fullcontact);
13185
						update_peer(peer, p->expiry);
13213
						update_peer(peer, p->expiry);
13186
						/* Say OK and ask subsystem to retransmit msg counter */
13214
						/* Say OK and ask subsystem to retransmit msg counter */
13187
						transmit_response_with_date(p, "200 OK", req);
13215
						transmit_response_with_date(p, "200 OK", req);
13188
						if (!ast_test_flag((&peer->flags[1]), SIP_PAGE2_SUBSCRIBEMWIONLY))
13216
						if (!ast_test_flag((&peer->flags[1]), SIP_PAGE2_SUBSCRIBEMWIONLY))
13189
							peer->lastmsgssent = -1;
13217
							peer->lastmsgssent = -1;
[+20] [20] 23 lines
[+20] static enum check_auth_result register_verify(struct sip_pvt *p, struct sockaddr_in *sin,
13213
				transmit_response_with_date(p, "400 Bad Request", req);
13241
				transmit_response_with_date(p, "400 Bad Request", req);
13214
				peer->lastmsgssent = -1;
13242
				peer->lastmsgssent = -1;
13215
				res = 0;
13243
				res = 0;
13216
				break;
13244
				break;
13217
			case PARSE_REGISTER_QUERY:
13245
			case PARSE_REGISTER_QUERY:

    
   
13246
				ast_string_field_set(p, fullcontact, peer->fullcontact);
13218
				transmit_response_with_date(p, "200 OK", req);
13247
				transmit_response_with_date(p, "200 OK", req);
13219
				peer->lastmsgssent = -1;
13248
				peer->lastmsgssent = -1;
13220
				res = 0;
13249
				res = 0;
13221
				break;
13250
				break;
13222
			case PARSE_REGISTER_UPDATE:
13251
			case PARSE_REGISTER_UPDATE:

    
   
13252
				ast_string_field_set(p, fullcontact, peer->fullcontact);
13223
				/* Say OK and ask subsystem to retransmit msg counter */
13253
				/* Say OK and ask subsystem to retransmit msg counter */
13224
				transmit_response_with_date(p, "200 OK", req);
13254
				transmit_response_with_date(p, "200 OK", req);
13225
				manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "ChannelType: SIP\r\nPeer: SIP/%s\r\nPeerStatus: Registered\r\nAddress: %s\r\nPort: %d\r\n", peer->name, ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port));
13255
				manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "ChannelType: SIP\r\nPeer: SIP/%s\r\nPeerStatus: Registered\r\nAddress: %s\r\nPort: %d\r\n", peer->name, ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port));
13226
				peer->lastmsgssent = -1;
13256
				peer->lastmsgssent = -1;
13227
				res = 0;
13257
				res = 0;
[+20] [20] 1588 lines
[+20] [+] static int manager_show_registry(struct mansession *s, const struct message *m)
14816

    
   
14846

   
14817
	ASTOBJ_CONTAINER_TRAVERSE(&regl, 1, do {
14847
	ASTOBJ_CONTAINER_TRAVERSE(&regl, 1, do {
14818
		ASTOBJ_RDLOCK(iterator);
14848
		ASTOBJ_RDLOCK(iterator);
14819
		astman_append(s,
14849
		astman_append(s,
14820
			"Event: RegistryEntry\r\n"
14850
			"Event: RegistryEntry\r\n"

    
   
14851
			"%s"
14821
			"Host: %s\r\n"
14852
			"Host: %s\r\n"
14822
			"Port: %d\r\n"
14853
			"Port: %d\r\n"
14823
			"Username: %s\r\n"
14854
			"Username: %s\r\n"
14824
			"Domain: %s\r\n"
14855
			"Domain: %s\r\n"
14825
			"Refresh: %d\r\n"
14856
			"Refresh: %d\r\n"
14826
			"State: %s\r\n"
14857
			"State: %s\r\n"
14827
			"RegistrationTime: %ld\r\n"
14858
			"RegistrationTime: %ld\r\n"
14828
			"\r\n", iterator->hostname, iterator->portno ? iterator->portno : STANDARD_SIP_PORT,
14859
			"\r\n", idtext, iterator->hostname, iterator->portno ? iterator->portno : STANDARD_SIP_PORT,
14829
					  iterator->username, iterator->regdomain, iterator->refresh, regstate2str(iterator->regstate), (long) iterator->regtime.tv_sec);
14860
					  iterator->username, iterator->regdomain, iterator->refresh, regstate2str(iterator->regstate), (long) iterator->regtime.tv_sec);
14830
		ASTOBJ_UNLOCK(iterator);
14861
		ASTOBJ_UNLOCK(iterator);
14831
		total++;
14862
		total++;
14832
	} while(0));
14863
	} while(0));
14833

    
   
14864

   
[+20] [20] 3882 lines
[+20] [+] static void stop_media_flows(struct sip_pvt *p)
18716
static void handle_response(struct sip_pvt *p, int resp, const char *rest, struct sip_request *req, int seqno)
18747
static void handle_response(struct sip_pvt *p, int resp, const char *rest, struct sip_request *req, int seqno)
18717
{
18748
{
18718
	struct ast_channel *owner;
18749
	struct ast_channel *owner;
18719
	int sipmethod;
18750
	int sipmethod;
18720
	int res = 1;
18751
	int res = 1;
18721
	int ack_res;

   
18722
	const char *c = get_header(req, "Cseq");
18752
	const char *c = get_header(req, "Cseq");
18723
	/* GCC 4.2 complains if I try to cast c as a char * when passing it to ast_skip_nonblanks, so make a copy of it */
18753
	/* GCC 4.2 complains if I try to cast c as a char * when passing it to ast_skip_nonblanks, so make a copy of it */
18724
	char *c_copy = ast_strdupa(c);
18754
	char *c_copy = ast_strdupa(c);
18725
	/* Skip the Cseq and its subsequent spaces */
18755
	/* Skip the Cseq and its subsequent spaces */
18726
	const char *msg = ast_skip_blanks(ast_skip_nonblanks(c_copy));
18756
	const char *msg = ast_skip_blanks(ast_skip_nonblanks(c_copy));
[+20] [20] 11 lines
[+20] static void handle_response(struct sip_pvt *p, int resp, const char *rest, struct sip_request *req, int seqno)
18738
		snprintf(causevar, sizeof(causevar), "MASTER_CHANNEL(HASH(SIP_CAUSE,%s))", owner->name);
18768
		snprintf(causevar, sizeof(causevar), "MASTER_CHANNEL(HASH(SIP_CAUSE,%s))", owner->name);
18739
		snprintf(causeval, sizeof(causeval), "SIP %s", REQ_OFFSET_TO_STR(req, rlPart2));
18769
		snprintf(causeval, sizeof(causeval), "SIP %s", REQ_OFFSET_TO_STR(req, rlPart2));
18740
		pbx_builtin_setvar_helper(owner, causevar, causeval);
18770
		pbx_builtin_setvar_helper(owner, causevar, causeval);
18741
	}
18771
	}
18742

    
   
18772

   

    
   
18773
	if (p->socket.type == SIP_TRANSPORT_UDP) {

    
   
18774
		int ack_res;

    
   
18775

   
18743
	/* Acknowledge whatever it is destined for */
18776
		/* Acknowledge whatever it is destined for */
18744
	if ((resp >= 100) && (resp <= 199)) {
18777
		if ((resp >= 100) && (resp <= 199)) {
18745
		ack_res = __sip_semi_ack(p, seqno, 0, sipmethod);
18778
			ack_res = __sip_semi_ack(p, seqno, 0, sipmethod);
18746
	} else {
18779
		} else {
18747
		ack_res = __sip_ack(p, seqno, 0, sipmethod);
18780
			ack_res = __sip_ack(p, seqno, 0, sipmethod);
18748
	}
18781
		}
18749

    
   
18782

   
18750
	if (ack_res == FALSE) {
18783
		if (ack_res == FALSE) {
18751
		append_history(p, "Ignore", "Ignoring this retransmit\n");
18784
			append_history(p, "Ignore", "Ignoring this retransmit\n");
18752
		return;
18785
			return;
18753
	}
18786
		}

    
   
18787
	}
18754

    
   
18788

   
18755
	/* If this is a NOTIFY for a subscription clear the flag that indicates that we have a NOTIFY pending */
18789
	/* If this is a NOTIFY for a subscription clear the flag that indicates that we have a NOTIFY pending */
18756
	if (!p->owner && sipmethod == SIP_NOTIFY && p->pendinginvite)
18790
	if (!p->owner && sipmethod == SIP_NOTIFY && p->pendinginvite)
18757
		p->pendinginvite = 0;
18791
		p->pendinginvite = 0;
18758

    
   
18792

   
[+20] [20] 767 lines
[+20] [+] static int handle_request_notify(struct sip_pvt *p, struct sip_request *req, struct sockaddr_in *sin, int seqno, const char *e)
19526
		respcode = atoi(code);
19560
		respcode = atoi(code);
19527
		switch (respcode) {
19561
		switch (respcode) {
19528
		case 100:	/* Trying: */
19562
		case 100:	/* Trying: */
19529
		case 101:	/* dialog establishment */
19563
		case 101:	/* dialog establishment */
19530
			/* Don't do anything yet */
19564
			/* Don't do anything yet */

    
   
19565
			success = -1;	/* Wait */
19531
			break;
19566
			break;
19532
		case 183:	/* Ringing: */
19567
		case 183:	/* Ringing: */
19533
			/* Don't do anything yet */
19568
			/* Don't do anything yet */

    
   
19569
			success = -1;	/* Wait */
19534
			break;
19570
			break;
19535
		case 200:	/* OK: The new call is up, hangup this call */
19571
		case 200:	/* OK: The new call is up, hangup this call */
19536
			/* Hangup the call that we are replacing */
19572
			/* Hangup the call that we are replacing */

    
   
19573
			success = -1;	/* Wait */
19537
			break;
19574
			break;
19538
		case 301: /* Moved permenantly */
19575
		case 301: /* Moved permenantly */
19539
		case 302: /* Moved temporarily */
19576
		case 302: /* Moved temporarily */
19540
			/* Do we get the header in the packet in this case? */
19577
			/* Do we get the header in the packet in this case? */
19541
			success = FALSE;
19578
			success = FALSE;
[+20] [20] 5 lines
[+20] static int handle_request_notify(struct sip_pvt *p, struct sip_request *req, struct sockaddr_in *sin, int seqno, const char *e)
19547
		case 603:	/* Declined: Not accepted */
19584
		case 603:	/* Declined: Not accepted */
19548
				/* Cancel transfer, continue the current call */
19585
				/* Cancel transfer, continue the current call */
19549
			success = FALSE;
19586
			success = FALSE;
19550
			break;
19587
			break;
19551
		}
19588
		}
19552
		if (!success) {
19589
		if (success == FALSE) {
19553
			ast_log(LOG_NOTICE, "Transfer failed. Sorry. Nothing further to do with this call\n");
19590
			ast_log(LOG_NOTICE, "Transfer failed. Sorry. Nothing further to do with this call\n");
19554
		}
19591
		}
19555

    
   
19592

   
19556
		if (p->owner) {
19593
		if (p->owner && success != -1) {
19557
			enum ast_control_transfer message = success ? AST_TRANSFER_SUCCESS : AST_TRANSFER_FAILED;
19594
			enum ast_control_transfer message = success ? AST_TRANSFER_SUCCESS : AST_TRANSFER_FAILED;
19558
			ast_queue_control_data(p->owner, AST_CONTROL_TRANSFER, &message, sizeof(message));
19595
			ast_queue_control_data(p->owner, AST_CONTROL_TRANSFER, &message, sizeof(message));
19559
		}
19596
		}
19560
		/* Confirm that we received this packet */
19597
		/* Confirm that we received this packet */
19561
		transmit_response(p, "200 OK", req);
19598
		transmit_response(p, "200 OK", req);
[+20] [20] 77 lines
[+20] [+] static int handle_request_options(struct sip_pvt *p, struct sip_request *req)
19639

    
   
19676

   
19640
/*! \brief Handle the transfer part of INVITE with a replaces: header,
19677
/*! \brief Handle the transfer part of INVITE with a replaces: header,
19641
    meaning a target pickup or an attended transfer.
19678
    meaning a target pickup or an attended transfer.
19642
    Used only once.
19679
    Used only once.
19643
	XXX 'ignore' is unused.
19680
	XXX 'ignore' is unused.

    
   
19681

   

    
   
19682
	\note this function is called by handle_request_invite(). Four locks

    
   
19683
	held at the beginning of this function, p, p->owner, p->refer->refer_call->owner...

    
   
19684
	only p's lock should remain at the end of this function.  p's lock is held by sipsock_read()
19644
 */
19685
 */
19645
static int handle_invite_replaces(struct sip_pvt *p, struct sip_request *req, int debug, int seqno, struct sockaddr_in *sin)
19686
static int handle_invite_replaces(struct sip_pvt *p, struct sip_request *req, int debug, int seqno, struct sockaddr_in *sin, int *nounlock)
19646
{
19687
{
19647
	struct ast_frame *f;

   
19648
	int earlyreplace = 0;
19688
	int earlyreplace = 0;
19649
	int oneleggedreplace = 0;		/* Call with no bridge, propably IVR or voice message */
19689
	int oneleggedreplace = 0;		/* Call with no bridge, propably IVR or voice message */
19650
	struct ast_channel *c = p->owner;	/* Our incoming call */
19690
	struct ast_channel *c = p->owner;	/* Our incoming call */
19651
	struct ast_channel *replacecall = p->refer->refer_call->owner;	/* The channel we're about to take over */
19691
	struct ast_channel *replacecall = p->refer->refer_call->owner;	/* The channel we're about to take over */
19652
	struct ast_channel *targetcall;		/* The bridge to the take-over target */
19692
	struct ast_channel *targetcall;		/* The bridge to the take-over target */
[+20] [20] 26 lines
[+20] static int handle_invite_replaces(struct sip_pvt *p, struct sip_request *req, int debug, int seqno, struct sockaddr_in *sin) [+] static int handle_invite_replaces(struct sip_pvt *p, struct sip_request *req, int debug, int seqno, struct sockaddr_in *sin, int *nounlock)
19679
			call we are replacing exists, so an accepted
19719
			call we are replacing exists, so an accepted
19680
			can't harm */
19720
			can't harm */
19681
		transmit_response_with_sdp(p, "200 OK", req, XMIT_RELIABLE, FALSE, FALSE);
19721
		transmit_response_with_sdp(p, "200 OK", req, XMIT_RELIABLE, FALSE, FALSE);
19682
		/* Do something more clever here */
19722
		/* Do something more clever here */
19683
		ast_channel_unlock(c);
19723
		ast_channel_unlock(c);

    
   
19724
		ast_channel_unlock(replacecall);
19684
		sip_pvt_unlock(p->refer->refer_call);
19725
		sip_pvt_unlock(p->refer->refer_call);
19685
		return 1;
19726
		return 1;
19686
	}
19727
	}
19687
	if (!c) {
19728
	if (!c) {
19688
		/* What to do if no channel ??? */
19729
		/* What to do if no channel ??? */
19689
		ast_log(LOG_ERROR, "Unable to create new channel.  Invite/replace failed.\n");
19730
		ast_log(LOG_ERROR, "Unable to create new channel.  Invite/replace failed.\n");
19690
		transmit_response_reliable(p, "503 Service Unavailable", req);
19731
		transmit_response_reliable(p, "503 Service Unavailable", req);
19691
		append_history(p, "Xfer", "INVITE/Replace Failed. No new channel.");
19732
		append_history(p, "Xfer", "INVITE/Replace Failed. No new channel.");
19692
		sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
19733
		sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);

    
   
19734
		ast_channel_unlock(replacecall);
19693
		sip_pvt_unlock(p->refer->refer_call);
19735
		sip_pvt_unlock(p->refer->refer_call);
19694
		return 1;
19736
		return 1;
19695
	}
19737
	}
19696
	append_history(p, "Xfer", "INVITE/Replace received");
19738
	append_history(p, "Xfer", "INVITE/Replace received");
19697
	/* We have three channels to play with
19739
	/* We have three channels to play with
[+20] [20] 20 lines
[+20] static int handle_invite_replaces(struct sip_pvt *p, struct sip_request *req, int debug, int seqno, struct sockaddr_in *sin) static int handle_invite_replaces(struct sip_pvt *p, struct sip_request *req, int debug, int seqno, struct sockaddr_in *sin, int *nounlock)
19718
	
19760
	
19719
	/* Stop music on hold and other generators */
19761
	/* Stop music on hold and other generators */
19720
	ast_quiet_chan(replacecall);
19762
	ast_quiet_chan(replacecall);
19721
	ast_quiet_chan(targetcall);
19763
	ast_quiet_chan(targetcall);
19722
	ast_debug(4, "Invite/Replaces: preparing to masquerade %s into %s\n", c->name, replacecall->name);
19764
	ast_debug(4, "Invite/Replaces: preparing to masquerade %s into %s\n", c->name, replacecall->name);
19723
	/* Unlock clone, but not original (replacecall) */

   
19724
	if (!oneleggedreplace)

   
19725
		ast_channel_unlock(c);

   
19726

    
   

   
19727
	/* Unlock PVT */

   
19728
	sip_pvt_unlock(p->refer->refer_call);

   
19729

    
   
19765

   
19730
	/* Make sure that the masq does not free our PVT for the old call */
19766
	/* Make sure that the masq does not free our PVT for the old call */
19731
	if (! earlyreplace && ! oneleggedreplace )
19767
	if (! earlyreplace && ! oneleggedreplace )
19732
		ast_set_flag(&p->refer->refer_call->flags[0], SIP_DEFER_BYE_ON_TRANSFER);	/* Delay hangup */
19768
		ast_set_flag(&p->refer->refer_call->flags[0], SIP_DEFER_BYE_ON_TRANSFER);	/* Delay hangup */
19733
		
19769

   
19734
	/* Prepare the masquerade - if this does not happen, we will be gone */
19770
	/* Prepare the masquerade - if this does not happen, we will be gone */
19735
	if(ast_channel_masquerade(replacecall, c))
19771
	if(ast_channel_masquerade(replacecall, c))
19736
		ast_log(LOG_ERROR, "Failed to masquerade C into Replacecall\n");
19772
		ast_log(LOG_ERROR, "Failed to masquerade C into Replacecall\n");
19737
	else
19773
	else
19738
		ast_debug(4, "Invite/Replaces: Going to masquerade %s into %s\n", c->name, replacecall->name);
19774
		ast_debug(4, "Invite/Replaces: Going to masquerade %s into %s\n", c->name, replacecall->name);
19739

    
   
19775

   
19740
	/* The masquerade will happen as soon as someone reads a frame from the channel */

   
19741

    
   

   
19742
	/* C should now be in place of replacecall */
19776
	/* C should now be in place of replacecall */
19743
	/* ast_read needs to lock channel */
19777
	if (ast_do_masquerade(replacecall)) {
19744
	ast_channel_unlock(c);
19778
		ast_log(LOG_WARNING, "Failed to perform masquerade with INVITE replaces\n");
19745
	

   
19746
	if (earlyreplace || oneleggedreplace ) {

   
19747
		/* Force the masq to happen */

   
19748
		if ((f = ast_read(replacecall))) {	/* Force the masq to happen */

   
19749
			ast_frfree(f);

   
19750
			f = NULL;

   
19751
			ast_debug(4, "Invite/Replace:  Could successfully read frame from RING channel!\n");

   
19752
		} else {

   
19753
			ast_log(LOG_WARNING, "Invite/Replace:  Could not read frame from RING channel \n");

   
19754
		}
19779
	}

    
   
19780

   

    
   
19781
	if (earlyreplace || oneleggedreplace ) {
19755
		c->hangupcause = AST_CAUSE_SWITCH_CONGESTION;
19782
		c->hangupcause = AST_CAUSE_SWITCH_CONGESTION;
19756
		if (!oneleggedreplace)

   
19757
			ast_channel_unlock(replacecall);

   
19758
	} else {	/* Bridged call, UP channel */

   
19759
		if ((f = ast_read(replacecall))) {	/* Force the masq to happen */

   
19760
			/* Masq ok */

   
19761
			ast_frfree(f);

   
19762
			f = NULL;

   
19763
			ast_debug(3, "Invite/Replace:  Could successfully read frame from channel! Masq done.\n");

   
19764
		} else {

   
19765
			ast_log(LOG_WARNING, "Invite/Replace:  Could not read frame from channel. Transfer failed\n");

   
19766
		}

   
19767
		ast_channel_unlock(replacecall);

   
19768
	}
19783
	}
19769
	sip_pvt_unlock(p->refer->refer_call);

   
19770

    
   
19784

   
19771
	ast_setstate(c, AST_STATE_DOWN);
19785
	ast_setstate(c, AST_STATE_DOWN);
19772
	ast_debug(4, "After transfer:----------------------------\n");
19786
	ast_debug(4, "After transfer:----------------------------\n");
19773
	ast_debug(4, " -- C:        %s State %s\n", c->name, ast_state2str(c->_state));
19787
	ast_debug(4, " -- C:        %s State %s\n", c->name, ast_state2str(c->_state));
19774
	if (replacecall)
19788
	if (replacecall)
[+20] [20] 7 lines
[+20] static int handle_invite_replaces(struct sip_pvt *p, struct sip_request *req, int debug, int seqno, struct sockaddr_in *sin) static int handle_invite_replaces(struct sip_pvt *p, struct sip_request *req, int debug, int seqno, struct sockaddr_in *sin, int *nounlock)
19782
			ast_debug(4, " -- No call bridged to C->owner \n");
19796
			ast_debug(4, " -- No call bridged to C->owner \n");
19783
	} else
19797
	} else
19784
		ast_debug(4, " -- No channel yet \n");
19798
		ast_debug(4, " -- No channel yet \n");
19785
	ast_debug(4, "End After transfer:----------------------------\n");
19799
	ast_debug(4, "End After transfer:----------------------------\n");
19786

    
   
19800

   
19787
	ast_channel_unlock(p->owner);	/* Unlock new owner */
19801
	/* unlock sip pvt and owner so hangup can do its thing */
19788
	if (!oneleggedreplace)
19802
	ast_channel_unlock(replacecall);
19789
		sip_pvt_unlock(p);	/* Unlock SIP structure */
19803
	ast_channel_unlock(c);

    
   
19804
	sip_pvt_unlock(p->refer->refer_call);

    
   
19805
	sip_pvt_unlock(p);

    
   
19806
	*nounlock = 1;
19790

    
   
19807

   
19791
	/* The call should be down with no ast_channel, so hang it up */
19808
	/* The call should be down with no ast_channel, so hang it up */
19792
	c->tech_pvt = dialog_unref(c->tech_pvt, "unref dialog c->tech_pvt");
19809
	c->tech_pvt = dialog_unref(c->tech_pvt, "unref dialog c->tech_pvt");
19793
	ast_hangup(c);
19810
	ast_hangup(c);

    
   
19811
	sip_pvt_lock(p); /* lock PVT structure again after hangup */

    
   
19812

   
19794
	return 0;
19813
	return 0;
19795
}
19814
}
19796

    
   
19815

   
19797
/*! \brief helper routine for sip_uri_cmp
19816
/*! \brief helper routine for sip_uri_cmp
19798
 *
19817
 *
[+20] [20] 434 lines
[+20] [+] static int handle_request_invite(struct sip_pvt *p, struct sip_request *req, int debug, int seqno, struct sockaddr_in *sin, int *recount, const char *e, int *nounlock)
20233
			 */
20252
			 */
20234
			char *uri = ast_strdupa(this_rlPart2);
20253
			char *uri = ast_strdupa(this_rlPart2);
20235
			char *at = strchr(uri, '@');
20254
			char *at = strchr(uri, '@');
20236
			char *peerorhost;
20255
			char *peerorhost;
20237
			ast_debug(2, "Potential spiral detected. Original RURI was %s, new RURI is %s\n", initial_rlPart2, this_rlPart2);
20256
			ast_debug(2, "Potential spiral detected. Original RURI was %s, new RURI is %s\n", initial_rlPart2, this_rlPart2);

    
   
20257
			transmit_response(p, "100 Trying", req);
20238
			if (at) {
20258
			if (at) {
20239
				*at = '\0';
20259
				*at = '\0';
20240
			}
20260
			}
20241
			/* Parse out "sip:" */
20261
			/* Parse out "sip:" */
20242
			if ((peerorhost = strchr(uri, ':'))) {
20262
			if ((peerorhost = strchr(uri, ':'))) {
[+20] [20] 214 lines
[+20] static int handle_request_invite(struct sip_pvt *p, struct sip_request *req, int debug, int seqno, struct sockaddr_in *sin, int *recount, const char *e, int *nounlock)
20457
					transmit_response_reliable(p, "488 Not acceptable here", req);
20477
					transmit_response_reliable(p, "488 Not acceptable here", req);
20458
					if (!p->lastinvite)
20478
					if (!p->lastinvite)
20459
						sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
20479
						sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
20460
					return -1;
20480
					return -1;
20461
				}
20481
				}

    
   
20482
				ast_queue_control(p->owner, AST_CONTROL_SRCUPDATE);
20462
			} else {
20483
			} else {
20463
				p->jointcapability = p->capability;
20484
				p->jointcapability = p->capability;
20464
				ast_debug(1, "Hm....  No sdp for the moment\n");
20485
				ast_debug(1, "Hm....  No sdp for the moment\n");
20465
			}
20486
			}
20466
			if (p->do_history) /* This is a response, note what it was for */
20487
			if (p->do_history) /* This is a response, note what it was for */
[+20] [20] 40 lines
[+20] static int handle_request_invite(struct sip_pvt *p, struct sip_request *req, int debug, int seqno, struct sockaddr_in *sin, int *recount, const char *e, int *nounlock)
20507
				p->invitestate = INV_COMPLETED;	
20528
				p->invitestate = INV_COMPLETED;	
20508
				sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
20529
				sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
20509
				ast_debug(1, "No compatible codecs for this SIP call.\n");
20530
				ast_debug(1, "No compatible codecs for this SIP call.\n");
20510
				return -1;
20531
				return -1;
20511
			}
20532
			}

    
   
20533
			if (p->rtp) {

    
   
20534
				ast_rtp_instance_set_prop(p->rtp, AST_RTP_PROPERTY_CONSTANT_SSRC, ast_test_flag(&p->flags[1], SIP_PAGE2_CONSTANT_SSRC));

    
   
20535
			}

    
   
20536
			if (p->vrtp) {

    
   
20537
				ast_rtp_instance_set_prop(p->vrtp, AST_RTP_PROPERTY_CONSTANT_SSRC, ast_test_flag(&p->flags[1], SIP_PAGE2_CONSTANT_SSRC));

    
   
20538
			}
20512
		} else {	/* No SDP in invite, call control session */
20539
		} else {	/* No SDP in invite, call control session */
20513
			p->jointcapability = p->capability;
20540
			p->jointcapability = p->capability;
20514
			ast_debug(2, "No SDP in Invite, third party call control\n");
20541
			ast_debug(2, "No SDP in Invite, third party call control\n");
20515
		}
20542
		}
20516

    
   
20543

   
[+20] [20] 230 lines
[+20] static int handle_request_invite(struct sip_pvt *p, struct sip_request *req, int debug, int seqno, struct sockaddr_in *sin, int *recount, const char *e, int *nounlock)
20747
			ast_channel_unlock(c);
20774
			ast_channel_unlock(c);
20748
			*nounlock = 1;
20775
			*nounlock = 1;
20749
			do_magic_pickup(c, pickup.exten, pickup.context);
20776
			do_magic_pickup(c, pickup.exten, pickup.context);
20750

    
   
20777

   
20751
			/* Now we're either masqueraded or we failed to pickup, in either case we... */
20778
			/* Now we're either masqueraded or we failed to pickup, in either case we... */

    
   
20779
			sip_pvt_unlock(p);
20752
			ast_hangup(c);
20780
			ast_hangup(c);

    
   
20781
			sip_pvt_lock(p);
20753

    
   
20782

   
20754
			return 0;
20783
			return 0;
20755
		} else {
20784
		} else {
20756
			/* Go and take over the target call */
20785
			/* Go and take over the target call */
20757
			if (sipdebug)
20786
			if (sipdebug)
20758
				ast_debug(4, "Sending this call to the invite/replcaes handler %s\n", p->callid);
20787
				ast_debug(4, "Sending this call to the invite/replcaes handler %s\n", p->callid);
20759
			return handle_invite_replaces(p, req, debug, seqno, sin);
20788
			return handle_invite_replaces(p, req, debug, seqno, sin, nounlock);
20760
		}
20789
		}
20761
	}
20790
	}
20762

    
   
20791

   
20763

    
   
20792

   
20764
	if (c) {	/* We have a call  -either a new call or an old one (RE-INVITE) */
20793
	if (c) {	/* We have a call  -either a new call or an old one (RE-INVITE) */
[+20] [20] 2397 lines
[+20] [+] int parse_session_expires(const char *p_hdrval, int *const p_interval, enum st_refresher *const p_ref)
23162

    
   
23191

   
23163
		ast_debug(2, "Session-Expires: %d\n", *p_interval);
23192
		ast_debug(2, "Session-Expires: %d\n", *p_interval);
23164

    
   
23193

   
23165
		if (!p_se_hdr)
23194
		if (!p_se_hdr)
23166
			continue;
23195
			continue;
23167
		
23196

   

    
   
23197
		p_se_hdr = ast_skip_blanks(p_se_hdr);
23168
		ref_idx = strlen("refresher=");
23198
		ref_idx = strlen("refresher=");
23169
		if (!strncasecmp(p_se_hdr, "refresher=", ref_idx)) {
23199
		if (!strncasecmp(p_se_hdr, "refresher=", ref_idx)) {
23170
			p_se_hdr += ref_idx;
23200
			p_se_hdr += ref_idx;
23171
			p_se_hdr = ast_skip_blanks(p_se_hdr);
23201
			p_se_hdr = ast_skip_blanks(p_se_hdr);
23172

    
   
23202

   
[+20] [20] 698 lines
[+20] [+] static int handle_common_options(struct ast_flags *flags, struct ast_flags *mask, struct ast_variable *v)
23871
		ast_set_flag(&mask[1], SIP_PAGE2_BUGGY_MWI);
23901
		ast_set_flag(&mask[1], SIP_PAGE2_BUGGY_MWI);
23872
		ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_BUGGY_MWI);
23902
		ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_BUGGY_MWI);
23873
	} else if (!strcasecmp(v->name, "t38pt_usertpsource")) {
23903
	} else if (!strcasecmp(v->name, "t38pt_usertpsource")) {
23874
		ast_set_flag(&mask[1], SIP_PAGE2_UDPTL_DESTINATION);
23904
		ast_set_flag(&mask[1], SIP_PAGE2_UDPTL_DESTINATION);
23875
		ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_UDPTL_DESTINATION);
23905
		ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_UDPTL_DESTINATION);

    
   
23906
	} else if (!strcasecmp(v->name, "constantssrc")) {

    
   
23907
		ast_set_flag(&mask[1], SIP_PAGE2_CONSTANT_SSRC);

    
   
23908
		ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_CONSTANT_SSRC);
23876
	} else
23909
	} else
23877
		res = 0;
23910
		res = 0;
23878

    
   
23911

   
23879
	return res;
23912
	return res;
23880
}
23913
}
[+20] [20] 195 lines
[+20] [+] static void set_peer_defaults(struct sip_peer *peer)
24076
	peer->rtpkeepalive = global_rtpkeepalive;
24109
	peer->rtpkeepalive = global_rtpkeepalive;
24077
	peer->allowtransfer = sip_cfg.allowtransfer;
24110
	peer->allowtransfer = sip_cfg.allowtransfer;
24078
	peer->autoframing = global_autoframing;
24111
	peer->autoframing = global_autoframing;
24079
	peer->qualifyfreq = global_qualifyfreq;
24112
	peer->qualifyfreq = global_qualifyfreq;
24080
	if (global_callcounter)
24113
	if (global_callcounter)
24081
		peer->call_limit=UINT_MAX;
24114
		peer->call_limit=INT_MAX;
24082
	ast_string_field_set(peer, vmexten, default_vmexten);
24115
	ast_string_field_set(peer, vmexten, default_vmexten);
24083
	ast_string_field_set(peer, secret, "");
24116
	ast_string_field_set(peer, secret, "");
24084
	ast_string_field_set(peer, remotesecret, "");
24117
	ast_string_field_set(peer, remotesecret, "");
24085
	ast_string_field_set(peer, md5secret, "");
24118
	ast_string_field_set(peer, md5secret, "");
24086
	ast_string_field_set(peer, cid_num, "");
24119
	ast_string_field_set(peer, cid_num, "");
[+20] [20] 66 lines
[+20] [+] static void add_peer_mailboxes(struct sip_peer *peer, const char *value)
24153
		AST_LIST_INSERT_TAIL(&peer->mailboxes, mailbox, entry);
24186
		AST_LIST_INSERT_TAIL(&peer->mailboxes, mailbox, entry);
24154
	}
24187
	}
24155
}
24188
}
24156

    
   
24189

   
24157
/*! \brief Build peer from configuration (file or realtime static/dynamic) */
24190
/*! \brief Build peer from configuration (file or realtime static/dynamic) */
24158
static struct sip_peer *build_peer(const char *name, struct ast_variable *v, struct ast_variable *alt, int realtime)
24191
static struct sip_peer *build_peer(const char *name, struct ast_variable *v, struct ast_variable *alt, int realtime, int devstate_only)
24159
{
24192
{
24160
	struct sip_peer *peer = NULL;
24193
	struct sip_peer *peer = NULL;
24161
	struct ast_ha *oldha = NULL;
24194
	struct ast_ha *oldha = NULL;
24162
	int found = 0;
24195
	int found = 0;
24163
	int firstpass = 1;
24196
	int firstpass = 1;

    
   
24197
	uint16_t port = 0;
24164
	int format = 0;		/* Ama flags */
24198
	int format = 0;		/* Ama flags */
24165
	time_t regseconds = 0;
24199
	time_t regseconds = 0;
24166
	struct ast_flags peerflags[2] = {{(0)}};
24200
	struct ast_flags peerflags[2] = {{(0)}};
24167
	struct ast_flags mask[2] = {{(0)}};
24201
	struct ast_flags mask[2] = {{(0)}};
24168
	struct sip_peer tmp_peer;
24202
	struct sip_peer tmp_peer;
[+20] [20] 49 lines
[+20] static struct sip_peer *build_peer(const char *name, struct ast_variable *v, struct ast_variable *alt, int realtime) [+] static struct sip_peer *build_peer(const char *name, struct ast_variable *v, struct ast_variable *alt, int realtime, int devstate_only)
24218
		ast_variables_destroy(peer->chanvars);
24252
		ast_variables_destroy(peer->chanvars);
24219
		peer->chanvars = NULL;
24253
		peer->chanvars = NULL;
24220
		/* XXX should unregister ? */
24254
		/* XXX should unregister ? */
24221
	}
24255
	}
24222

    
   
24256

   

    
   
24257
	if (found)

    
   
24258
		peer->portinuri = 0;

    
   
24259

   
24223
	/* If we have realm authentication information, remove them (reload) */
24260
	/* If we have realm authentication information, remove them (reload) */
24224
	clear_realm_authentication(peer->auth);
24261
	clear_realm_authentication(peer->auth);
24225
	peer->auth = NULL;
24262
	peer->auth = NULL;
24226
	peer->default_outbound_transport = 0;
24263
	peer->default_outbound_transport = 0;
24227
	peer->transports = 0;
24264
	peer->transports = 0;
24228

    
   
24265

   
24229
	for (; v || ((v = alt) && !(alt=NULL)); v = v->next) {
24266
	for (; v || ((v = alt) && !(alt=NULL)); v = v->next) {
24230
		if (handle_common_options(&peerflags[0], &mask[0], v))
24267
		if (!devstate_only) {

    
   
24268
			if (handle_common_options(&peerflags[0], &mask[0], v)) {
24231
			continue;
24269
				continue;

    
   
24270
			}
24232
		if (!strcasecmp(v->name, "transport") && !ast_strlen_zero(v->value)) {
24271
			if (!strcasecmp(v->name, "transport") && !ast_strlen_zero(v->value)) {
24233
			char *val = ast_strdupa(v->value);
24272
				char *val = ast_strdupa(v->value);
24234
			char *trans;
24273
				char *trans;
24235

    
   
24274

   
24236
			while ((trans = strsep(&val, ","))) {
24275
				while ((trans = strsep(&val, ","))) {
24237
				trans = ast_skip_blanks(trans);
24276
					trans = ast_skip_blanks(trans);
24238

    
   
24277

   
24239
				if (!strncasecmp(trans, "udp", 3))
24278
					if (!strncasecmp(trans, "udp", 3)) {
24240
					peer->transports |= SIP_TRANSPORT_UDP;
24279
						peer->transports |= SIP_TRANSPORT_UDP;
24241
				else if (!strncasecmp(trans, "tcp", 3))
24280
					} else if (!strncasecmp(trans, "tcp", 3)) {
24242
					peer->transports |= SIP_TRANSPORT_TCP;
24281
						peer->transports |= SIP_TRANSPORT_TCP;
24243
				else if (!strncasecmp(trans, "tls", 3))
24282
					} else if (!strncasecmp(trans, "tls", 3)) {
24244
					peer->transports |= SIP_TRANSPORT_TLS;
24283
						peer->transports |= SIP_TRANSPORT_TLS;
24245
				else
24284
					} else {
24246
					ast_log(LOG_NOTICE, "'%s' is not a valid transport type. if no other is specified, udp will be used.\n", trans);
24285
						ast_log(LOG_NOTICE, "'%s' is not a valid transport type. if no other is specified, udp will be used.\n", trans);

    
   
24286
					}
24247

    
   
24287

   
24248
				if (!peer->default_outbound_transport) { /*!< The first transport listed should be default outbound */
24288
					if (!peer->default_outbound_transport) { /*!< The first transport listed should be default outbound */
24249
					peer->default_outbound_transport = peer->transports;
24289
						peer->default_outbound_transport = peer->transports;
24250
				}
24290
					}
24251
			}
24291
				}
24252
		} else if (realtime && !strcasecmp(v->name, "regseconds")) {
24292
			} else if (realtime && !strcasecmp(v->name, "regseconds")) {
24253
			ast_get_time_t(v->value, &regseconds, 0, NULL);
24293
				ast_get_time_t(v->value, &regseconds, 0, NULL);
24254
		} else if (realtime && !strcasecmp(v->name, "lastms")) {
24294
			} else if (realtime && !strcasecmp(v->name, "name")) {
24255
			sscanf(v->value, "%30d", &peer->lastms);
Moved to 24566

   
24256
		} else if (realtime && !strcasecmp(v->name, "ipaddr") && !ast_strlen_zero(v->value) ) {
Moved to 24567

   
24257
			inet_aton(v->value, &(peer->addr.sin_addr));
Moved to 24568

   
24258
		} else if (realtime && !strcasecmp(v->name, "name"))

   
24259
			ast_copy_string(peer->name, v->value, sizeof(peer->name));
24295
				ast_copy_string(peer->name, v->value, sizeof(peer->name));
24260
		else if (realtime && !strcasecmp(v->name, "fullcontact")) {

   
24261
			if (alt_fullcontact && !alt) {

   
24262
				/* Reset, because the alternate also has a fullcontact and we

   
24263
				 * do NOT want the field value to be doubled. It might be

   
24264
				 * tempting to skip this, but the first table might not have

   
24265
				 * fullcontact and since we're here, we know that the alternate

   
24266
				 * absolutely does. */

   
24267
				alt_fullcontact = 0;

   
24268
				ast_str_reset(fullcontact);

   
24269
			}

   
24270
			/* Reconstruct field, because realtime separates our value at the ';' */

   
24271
			if (fullcontact->used > 0) {

   
24272
				ast_str_append(&fullcontact, 0, ";%s", v->value);

   
24273
			} else {

   
24274
				ast_str_set(&fullcontact, 0, "%s", v->value);

   
24275
			}

   
24276
		} else if (!strcasecmp(v->name, "type")) {
24296
			} else if (!strcasecmp(v->name, "type")) {
24277
			if (!strcasecmp(v->value, "peer")) {
24297
				if (!strcasecmp(v->value, "peer")) {
24278
				peer->type |= SIP_TYPE_PEER;
24298
					peer->type |= SIP_TYPE_PEER;
24279
			} else if (!strcasecmp(v->value, "user")) {
24299
				} else if (!strcasecmp(v->value, "user")) {
24280
				peer->type |= SIP_TYPE_USER;
24300
					peer->type |= SIP_TYPE_USER;
24281
			} else if (!strcasecmp(v->value, "friend")) {
24301
				} else if (!strcasecmp(v->value, "friend")) {
24282
				peer->type = SIP_TYPE_USER | SIP_TYPE_PEER;
24302
					peer->type = SIP_TYPE_USER | SIP_TYPE_PEER;
24283
			}
24303
				}
24284
		} else if (!strcasecmp(v->name, "remotesecret")) {
24304
			} else if (!strcasecmp(v->name, "remotesecret")) {
24285
			ast_string_field_set(peer, remotesecret, v->value);
24305
				ast_string_field_set(peer, remotesecret, v->value);
24286
		} else if (!strcasecmp(v->name, "secret")) {
24306
			} else if (!strcasecmp(v->name, "secret")) {
24287
			ast_string_field_set(peer, secret, v->value);
24307
				ast_string_field_set(peer, secret, v->value);
24288
		} else if (!strcasecmp(v->name, "md5secret"))
24308
			} else if (!strcasecmp(v->name, "md5secret")) {
24289
			ast_string_field_set(peer, md5secret, v->value);
24309
				ast_string_field_set(peer, md5secret, v->value);
24290
		else if (!strcasecmp(v->name, "auth"))
24310
			} else if (!strcasecmp(v->name, "auth")) {
24291
			peer->auth = add_realm_authentication(peer->auth, v->value, v->lineno);
24311
				peer->auth = add_realm_authentication(peer->auth, v->value, v->lineno);
24292
		else if (!strcasecmp(v->name, "callerid")) {
24312
			} else if (!strcasecmp(v->name, "callerid")) {
24293
			char cid_name[80] = { '\0' }, cid_num[80] = { '\0' };
24313
				char cid_name[80] = { '\0' }, cid_num[80] = { '\0' };
24294

    
   
24314

   
24295
			ast_callerid_split(v->value, cid_name, sizeof(cid_name), cid_num, sizeof(cid_num));
24315
				ast_callerid_split(v->value, cid_name, sizeof(cid_name), cid_num, sizeof(cid_num));
24296
			ast_string_field_set(peer, cid_name, cid_name);
24316
				ast_string_field_set(peer, cid_name, cid_name);
24297
			ast_string_field_set(peer, cid_num, cid_num);
24317
				ast_string_field_set(peer, cid_num, cid_num);
[+20] [20] 33 lines
[+20] static struct sip_peer *build_peer(const char *name, struct ast_variable *v, struct ast_variable *alt, int realtime) static struct sip_peer *build_peer(const char *name, struct ast_variable *v, struct ast_variable *alt, int realtime, int devstate_only)
24331
				/* They'll register with us */
24351
					/* They'll register with us */
24332
				if (!found || !peer->host_dynamic) {
24352
					if (!found || !peer->host_dynamic) {
24333
					/* Initialize stuff if this is a new peer, or if it used to
24353
						/* Initialize stuff if this is a new peer, or if it used to
24334
					 * not be dynamic before the reload. */
24354
						 * not be dynamic before the reload. */
24335
					memset(&peer->addr.sin_addr, 0, 4);
24355
						memset(&peer->addr.sin_addr, 0, 4);
24336
					if (peer->addr.sin_port) {

   
24337
						/* If we've already got a port, make it the default rather than absolute */

   
24338
						peer->defaddr.sin_port = peer->addr.sin_port;

   
24339
						peer->addr.sin_port = 0;
24356
						peer->addr.sin_port = 0;
24340
					}
24357
					}
24341
				}

   
24342
				peer->host_dynamic = TRUE;
24358
					peer->host_dynamic = TRUE;
24343
			} else {
24359
				} else {
24344
				/* Non-dynamic.  Make sure we become that way if we're not */
24360
					/* Non-dynamic.  Make sure we become that way if we're not */
24345
				AST_SCHED_DEL_UNREF(sched, peer->expire,
24361
					AST_SCHED_DEL_UNREF(sched, peer->expire,
24346
						unref_peer(peer, "removing register expire ref"));
24362
							unref_peer(peer, "removing register expire ref"));

    
   
24363
					/* the port will either be set to a default value or a config specified value once all option parsing is complete */

    
   
24364
					peer->addr.sin_port = 0;
24347
				peer->host_dynamic = FALSE;
24365
					peer->host_dynamic = FALSE;
24348
				srvlookup = v->value;
24366
					srvlookup = v->value;
24349
				if (global_dynamic_exclude_static) {
24367
					if (global_dynamic_exclude_static) {
24350
					int err = 0;
24368
						int err = 0;
24351
					sip_cfg.contact_ha = ast_append_ha("deny", (char *)ast_inet_ntoa(peer->addr.sin_addr), sip_cfg.contact_ha, &err);
24369
						sip_cfg.contact_ha = ast_append_ha("deny", (char *)ast_inet_ntoa(peer->addr.sin_addr), sip_cfg.contact_ha, &err);
[+20] [20] 7 lines
[+20] static struct sip_peer *build_peer(const char *name, struct ast_variable *v, struct ast_variable *alt, int realtime) static struct sip_peer *build_peer(const char *name, struct ast_variable *v, struct ast_variable *alt, int realtime, int devstate_only)
24359
				unref_peer(peer, "unref_peer: from build_peer defaultip");
24377
					unref_peer(peer, "unref_peer: from build_peer defaultip");
24360
				return NULL;
24378
					return NULL;
24361
			}
24379
				}
24362
		} else if (!strcasecmp(v->name, "permit") || !strcasecmp(v->name, "deny")) {
24380
			} else if (!strcasecmp(v->name, "permit") || !strcasecmp(v->name, "deny")) {
24363
			int ha_error = 0;
24381
				int ha_error = 0;
24364

    
   

   
24365
			peer->ha = ast_append_ha(v->name, v->value, peer->ha, &ha_error);
24382
				peer->ha = ast_append_ha(v->name, v->value, peer->ha, &ha_error);
24366
			if (ha_error)
24383
				if (ha_error) {
24367
				ast_log(LOG_ERROR, "Bad ACL entry in configuration line %d : %s\n", v->lineno, v->value);
24384
					ast_log(LOG_ERROR, "Bad ACL entry in configuration line %d : %s\n", v->lineno, v->value);

    
   
24385
				}
24368
		} else if (!strcasecmp(v->name, "contactpermit") || !strcasecmp(v->name, "contactdeny")) {
24386
			} else if (!strcasecmp(v->name, "contactpermit") || !strcasecmp(v->name, "contactdeny")) {
24369
			int ha_error = 0;
24387
				int ha_error = 0;
24370
			peer->contactha = ast_append_ha(v->name + 7, v->value, peer->contactha, &ha_error);
24388
				peer->contactha = ast_append_ha(v->name + 7, v->value, peer->contactha, &ha_error);
24371
			if (ha_error) {
24389
				if (ha_error) {
24372
				ast_log(LOG_ERROR, "Bad ACL entry in configuration line %d : %s\n", v->lineno, v->value);
24390
					ast_log(LOG_ERROR, "Bad ACL entry in configuration line %d : %s\n", v->lineno, v->value);
24373
			}
24391
				}
24374
		} else if (!strcasecmp(v->name, "port")) {
24392
			} else if (!strcasecmp(v->name, "port")) {
24375
			if (!realtime && peer->host_dynamic)
24393
				peer->portinuri = 1;
24376
				peer->defaddr.sin_port = htons(atoi(v->value));
24394
				if (!(port = port_str2int(v->value, 0))) {
24377
			else
24395
					ast_log(LOG_WARNING, "Invalid peer port configuration at line %d : %s\n", v->lineno, v->value);
24378
				peer->addr.sin_port = htons(atoi(v->value));
24396
				}
24379
		} else if (!strcasecmp(v->name, "callingpres")) {
24397
			} else if (!strcasecmp(v->name, "callingpres")) {
24380
			peer->callingpres = ast_parse_caller_presentation(v->value);
24398
				peer->callingpres = ast_parse_caller_presentation(v->value);
24381
			if (peer->callingpres == -1)
24399
				if (peer->callingpres == -1) {
24382
				peer->callingpres = atoi(v->value);
24400
					peer->callingpres = atoi(v->value);

    
   
24401
				}
24383
		} else if (!strcasecmp(v->name, "username") || !strcmp(v->name, "defaultuser")) {	/* "username" is deprecated */
24402
			} else if (!strcasecmp(v->name, "username") || !strcmp(v->name, "defaultuser")) {	/* "username" is deprecated */
24384
			ast_string_field_set(peer, username, v->value);
24403
				ast_string_field_set(peer, username, v->value);
24385
			if (!strcasecmp(v->name, "username")) {
24404
				if (!strcasecmp(v->name, "username")) {
24386
				if (deprecation_warning) {
24405
					if (deprecation_warning) {
24387
					ast_log(LOG_NOTICE, "The 'username' field for sip peers has been deprecated in favor of the term 'defaultuser'\n");
24406
						ast_log(LOG_NOTICE, "The 'username' field for sip peers has been deprecated in favor of the term 'defaultuser'\n");
[+20] [20] 5 lines
[+20] static struct sip_peer *build_peer(const char *name, struct ast_variable *v, struct ast_variable *alt, int realtime) static struct sip_peer *build_peer(const char *name, struct ast_variable *v, struct ast_variable *alt, int realtime, int devstate_only)
24393
			ast_string_field_set(peer, language, v->value);
24412
				ast_string_field_set(peer, language, v->value);
24394
		} else if (!strcasecmp(v->name, "regexten")) {
24413
			} else if (!strcasecmp(v->name, "regexten")) {
24395
			ast_string_field_set(peer, regexten, v->value);
24414
				ast_string_field_set(peer, regexten, v->value);
24396
		} else if (!strcasecmp(v->name, "callbackextension")) {
24415
			} else if (!strcasecmp(v->name, "callbackextension")) {
24397
			ast_string_field_set(peer, callback, v->value);
24416
				ast_string_field_set(peer, callback, v->value);
24398
		} else if (!strcasecmp(v->name, "callcounter")) {

   
24399
			peer->call_limit = ast_true(v->value) ? UINT_MAX : 0;

   
24400
		} else if (!strcasecmp(v->name, "call-limit")) {
Moved to 24604

   
24401
			peer->call_limit = atoi(v->value);
Moved to 24605

   
24402
			if (peer->call_limit < 0)

   
24403
				peer->call_limit = 0;
Moved to 24607

   
24404
		} else if (!strcasecmp(v->name, "busylevel")) {
Moved to 24608

   
24405
			peer->busy_level = atoi(v->value);
Moved to 24609

   
24406
			if (peer->busy_level < 0)

   
24407
				peer->busy_level = 0;

   
24408
		} else if (!strcasecmp(v->name, "amaflags")) {
24417
			} else if (!strcasecmp(v->name, "amaflags")) {
24409
			format = ast_cdr_amaflags2int(v->value);
24418
				format = ast_cdr_amaflags2int(v->value);
24410
			if (format < 0) {
24419
				if (format < 0) {
24411
				ast_log(LOG_WARNING, "Invalid AMA Flags for peer: %s at line %d\n", v->value, v->lineno);
24420
					ast_log(LOG_WARNING, "Invalid AMA Flags for peer: %s at line %d\n", v->value, v->lineno);
24412
			} else {
24421
				} else {
[+20] [20] 27 lines
[+20] static struct sip_peer *build_peer(const char *name, struct ast_variable *v, struct ast_variable *alt, int realtime) static struct sip_peer *build_peer(const char *name, struct ast_variable *v, struct ast_variable *alt, int realtime, int devstate_only)
24440
			peer->allowtransfer = ast_true(v->value) ? TRANSFER_OPENFORALL : TRANSFER_CLOSED;
24449
				peer->allowtransfer = ast_true(v->value) ? TRANSFER_OPENFORALL : TRANSFER_CLOSED;
24441
		} else if (!strcasecmp(v->name, "pickupgroup")) {
24450
			} else if (!strcasecmp(v->name, "pickupgroup")) {
24442
			peer->pickupgroup = ast_get_group(v->value);
24451
				peer->pickupgroup = ast_get_group(v->value);
24443
		} else if (!strcasecmp(v->name, "allow")) {
24452
			} else if (!strcasecmp(v->name, "allow")) {
24444
			int error =  ast_parse_allow_disallow(&peer->prefs, &peer->capability, v->value, TRUE);
24453
				int error =  ast_parse_allow_disallow(&peer->prefs, &peer->capability, v->value, TRUE);
24445
			if (error)
24454
				if (error) {
24446
				ast_log(LOG_WARNING, "Codec configuration errors found in line %d : %s = %s\n", v->lineno, v->name, v->value);
24455
					ast_log(LOG_WARNING, "Codec configuration errors found in line %d : %s = %s\n", v->lineno, v->name, v->value);

    
   
24456
				}
24447
		} else if (!strcasecmp(v->name, "disallow")) {
24457
			} else if (!strcasecmp(v->name, "disallow")) {
24448
			int error =  ast_parse_allow_disallow(&peer->prefs, &peer->capability, v->value, FALSE);
24458
				int error =  ast_parse_allow_disallow(&peer->prefs, &peer->capability, v->value, FALSE);
24449
			if (error)
24459
				if (error) {
24450
				ast_log(LOG_WARNING, "Codec configuration errors found in line %d : %s = %s\n", v->lineno, v->name, v->value);
24460
					ast_log(LOG_WARNING, "Codec configuration errors found in line %d : %s = %s\n", v->lineno, v->name, v->value);

    
   
24461
				}
24451
		} else if (!strcasecmp(v->name, "preferred_codec_only")) {
24462
			} else if (!strcasecmp(v->name, "preferred_codec_only")) {
24452
			ast_set2_flag(&peer->flags[1], ast_true(v->value), SIP_PAGE2_PREFERRED_CODEC);
24463
				ast_set2_flag(&peer->flags[1], ast_true(v->value), SIP_PAGE2_PREFERRED_CODEC);
24453
		} else if (!strcasecmp(v->name, "registertrying")) {
24464
			} else if (!strcasecmp(v->name, "registertrying")) {
24454
			ast_set2_flag(&peer->flags[1], ast_true(v->value), SIP_PAGE2_REGISTERTRYING);
24465
				ast_set2_flag(&peer->flags[1], ast_true(v->value), SIP_PAGE2_REGISTERTRYING);
24455
		} else if (!strcasecmp(v->name, "autoframing")) {
24466
			} else if (!strcasecmp(v->name, "autoframing")) {
[+20] [20] 32 lines
[+20] static struct sip_peer *build_peer(const char *name, struct ast_variable *v, struct ast_variable *alt, int realtime) static struct sip_peer *build_peer(const char *name, struct ast_variable *v, struct ast_variable *alt, int realtime, int devstate_only)
24488
				static int warning = 0;
24499
					static int warning = 0;
24489
				if (warning++ % 20 == 0) {
24500
					if (warning++ % 20 == 0) {
24490
					ast_log(LOG_WARNING, "Timer B has been set lower than recommended. (RFC 3261, 17.1.1.2)\n");
24501
						ast_log(LOG_WARNING, "Timer B has been set lower than recommended. (RFC 3261, 17.1.1.2)\n");
24491
				}
24502
					}
24492
			}
24503
				}

    
   
24504
			} else if (!strcasecmp(v->name, "rtpkeepalive")) {

    
   
24505
				if ((sscanf(v->value, "%30d", &peer->rtpkeepalive) != 1) || (peer->rtpkeepalive < 0)) {

    
   
24506
					ast_log(LOG_WARNING, "'%s' is not a valid RTP keepalive time at line %d.  Using default.\n", v->value, v->lineno);

    
   
24507
					peer->rtpkeepalive = global_rtpkeepalive;

    
   
24508
				}
24493
		} else if (!strcasecmp(v->name, "setvar")) {
24509
			} else if (!strcasecmp(v->name, "setvar")) {
24494
			peer->chanvars = add_var(v->value, peer->chanvars);
24510
				peer->chanvars = add_var(v->value, peer->chanvars);
24495
		} else if (!strcasecmp(v->name, "header")) {
24511
			} else if (!strcasecmp(v->name, "header")) {
24496
			char tmp[4096];
24512
				char tmp[4096];
24497
			snprintf(tmp, sizeof(tmp), "__SIPADDHEADERpre%2d=%s", ++headercount, v->value);
24513
				snprintf(tmp, sizeof(tmp), "__SIPADDHEADERpre%2d=%s", ++headercount, v->value);
24498
			peer->chanvars = add_var(tmp, peer->chanvars);
24514
				peer->chanvars = add_var(tmp, peer->chanvars);
24499
		} else if (!strcasecmp(v->name, "qualify")) {

   
24500
			if (!strcasecmp(v->value, "no")) {

   
24501
				peer->maxms = 0;

   
24502
			} else if (!strcasecmp(v->value, "yes")) {

   
24503
				peer->maxms = default_qualify ? default_qualify : DEFAULT_MAXMS;

   
24504
			} else if (sscanf(v->value, "%30d", &peer->maxms) != 1) {

   
24505
				ast_log(LOG_WARNING, "Qualification of peer '%s' should be 'yes', 'no', or a number of milliseconds at line %d of sip.conf\n", peer->name, v->lineno);

   
24506
				peer->maxms = 0;

   
24507
			}

   
24508
			if (realtime && !ast_test_flag(&global_flags[1], SIP_PAGE2_RTCACHEFRIENDS) && peer->maxms > 0) {

   
24509
				/* This would otherwise cause a network storm, where the

   
24510
				 * qualify response refreshes the peer from the database,

   
24511
				 * which in turn causes another qualify to be sent, ad

   
24512
				 * infinitum. */

   
24513
				ast_log(LOG_WARNING, "Qualify is incompatible with dynamic uncached realtime.  Please either turn rtcachefriends on or turn qualify off on peer '%s'\n", peer->name);

   
24514
				peer->maxms = 0;

   
24515
			}

   
24516
		} else if (!strcasecmp(v->name, "qualifyfreq")) {
24515
			} else if (!strcasecmp(v->name, "qualifyfreq")) {
24517
			int i;
24516
				int i;
24518
			if (sscanf(v->value, "%30d", &i) == 1)
24517
				if (sscanf(v->value, "%30d", &i) == 1) {
24519
				peer->qualifyfreq = i * 1000;
24518
					peer->qualifyfreq = i * 1000;
24520
			else {
24519
				} else {
24521
				ast_log(LOG_WARNING, "Invalid qualifyfreq number '%s' at line %d of %s\n", v->value, v->lineno, config);
24520
					ast_log(LOG_WARNING, "Invalid qualifyfreq number '%s' at line %d of %s\n", v->value, v->lineno, config);
24522
				peer->qualifyfreq = global_qualifyfreq;
24521
					peer->qualifyfreq = global_qualifyfreq;
24523
			}
24522
				}
24524
		} else if (!strcasecmp(v->name, "maxcallbitrate")) {
24523
			} else if (!strcasecmp(v->name, "maxcallbitrate")) {
24525
			peer->maxcallbitrate = atoi(v->value);
24524
				peer->maxcallbitrate = atoi(v->value);
24526
			if (peer->maxcallbitrate < 0)
24525
				if (peer->maxcallbitrate < 0) {
24527
				peer->maxcallbitrate = default_maxcallbitrate;
24526
					peer->maxcallbitrate = default_maxcallbitrate;

    
   
24527
				}
24528
		} else if (!strcasecmp(v->name, "session-timers")) {
24528
			} else if (!strcasecmp(v->name, "session-timers")) {
24529
			int i = (int) str2stmode(v->value);
24529
				int i = (int) str2stmode(v->value);
24530
			if (i < 0) {
24530
				if (i < 0) {
24531
				ast_log(LOG_WARNING, "Invalid session-timers '%s' at line %d of %s\n", v->value, v->lineno, config);
24531
					ast_log(LOG_WARNING, "Invalid session-timers '%s' at line %d of %s\n", v->value, v->lineno, config);
24532
				peer->stimer.st_mode_oper = global_st_mode;
24532
					peer->stimer.st_mode_oper = global_st_mode;
[+20] [20] 26 lines
[+20] static struct sip_peer *build_peer(const char *name, struct ast_variable *v, struct ast_variable *alt, int realtime) static struct sip_peer *build_peer(const char *name, struct ast_variable *v, struct ast_variable *alt, int realtime, int devstate_only)
24559
			char *disallow = ast_strdupa(v->value);
24559
				char *disallow = ast_strdupa(v->value);
24560
			mark_parsed_methods(&peer->disallowed_methods, disallow);
24560
				mark_parsed_methods(&peer->disallowed_methods, disallow);
24561
		}
24561
			}
24562
	}
24562
		}
24563

    
   
24563

   

    
   
24564
		/* These apply to devstate lookups */

    
   
24565
		if (realtime && !strcasecmp(v->name, "lastms")) {
Moved from 24255

    
   
24566
			sscanf(v->value, "%30d", &peer->lastms);
Moved from 24256

    
   
24567
		} else if (realtime && !strcasecmp(v->name, "ipaddr") && !ast_strlen_zero(v->value) ) {
Moved from 24257

    
   
24568
			inet_aton(v->value, &(peer->addr.sin_addr));

    
   
24569
		} else if (realtime && !strcasecmp(v->name, "fullcontact")) {
Moved from 24261

    
   
24570
			if (alt_fullcontact && !alt) {
Moved from 24262

    
   
24571
				/* Reset, because the alternate also has a fullcontact and we
Moved from 24263

    
   
24572
				 * do NOT want the field value to be doubled. It might be
Moved from 24264

    
   
24573
				 * tempting to skip this, but the first table might not have
Moved from 24265

    
   
24574
				 * fullcontact and since we're here, we know that the alternate
Moved from 24266

    
   
24575
				 * absolutely does. */
Moved from 24267

    
   
24576
				alt_fullcontact = 0;
Moved from 24268

    
   
24577
				ast_str_reset(fullcontact);
Moved from 24269

    
   
24578
			}
Moved from 24270

    
   
24579
			/* Reconstruct field, because realtime separates our value at the ';' */
Moved from 24271

    
   
24580
			if (fullcontact->used > 0) {
Moved from 24272

    
   
24581
				ast_str_append(&fullcontact, 0, ";%s", v->value);
Moved from 24273

    
   
24582
			} else {
Moved from 24274

    
   
24583
				ast_str_set(&fullcontact, 0, "%s", v->value);
Moved from 24275

    
   
24584
			}

    
   
24585
		} else if (!strcasecmp(v->name, "qualify")) {

    
   
24586
			if (!strcasecmp(v->value, "no")) {

    
   
24587
				peer->maxms = 0;

    
   
24588
			} else if (!strcasecmp(v->value, "yes")) {

    
   
24589
				peer->maxms = default_qualify ? default_qualify : DEFAULT_MAXMS;

    
   
24590
			} else if (sscanf(v->value, "%30d", &peer->maxms) != 1) {

    
   
24591
				ast_log(LOG_WARNING, "Qualification of peer '%s' should be 'yes', 'no', or a number of milliseconds at line %d of sip.conf\n", peer->name, v->lineno);

    
   
24592
				peer->maxms = 0;

    
   
24593
			}

    
   
24594
			if (realtime && !ast_test_flag(&global_flags[1], SIP_PAGE2_RTCACHEFRIENDS) && peer->maxms > 0) {

    
   
24595
				/* This would otherwise cause a network storm, where the

    
   
24596
				 * qualify response refreshes the peer from the database,

    
   
24597
				 * which in turn causes another qualify to be sent, ad

    
   
24598
				 * infinitum. */

    
   
24599
				ast_log(LOG_WARNING, "Qualify is incompatible with dynamic uncached realtime.  Please either turn rtcachefriends on or turn qualify off on peer '%s'\n", peer->name);

    
   
24600
				peer->maxms = 0;

    
   
24601
			}

    
   
24602
		} else if (!strcasecmp(v->name, "callcounter")) {

    
   
24603
			peer->call_limit = ast_true(v->value) ? INT_MAX : 0;
Moved from 24400

    
   
24604
		} else if (!strcasecmp(v->name, "call-limit")) {
Moved from 24401

    
   
24605
			peer->call_limit = atoi(v->value);

    
   
24606
			if (peer->call_limit < 0) {
Moved from 24403

    
   
24607
				peer->call_limit = 0;
Moved from 24404

    
   
24608
			}
Moved from 24405

    
   
24609
		} else if (!strcasecmp(v->name, "busylevel")) {

    
   
24610
			peer->busy_level = atoi(v->value);

    
   
24611
			if (peer->busy_level < 0) {

    
   
24612
				peer->busy_level = 0;

    
   
24613
			}

    
   
24614
		}

    
   
24615
	}

    
   
24616

   
24564
	if (!peer->default_outbound_transport) {
24617
	if (!peer->default_outbound_transport) {
24565
		/* Set default set of transports */
24618
		/* Set default set of transports */
24566
		peer->transports = default_transports;
24619
		peer->transports = default_transports;
24567
		/* Set default primary transport */
24620
		/* Set default primary transport */
24568
		peer->default_outbound_transport = default_primary_transport;
24621
		peer->default_outbound_transport = default_primary_transport;
[+20] [20] 7 lines
[+20] static struct sip_peer *build_peer(const char *name, struct ast_variable *v, struct ast_variable *alt, int realtime) static struct sip_peer *build_peer(const char *name, struct ast_variable *v, struct ast_variable *alt, int realtime, int devstate_only)
24576
		!(peer->socket.type & peer->transports) || !(peer->socket.type)) {
24629
		!(peer->socket.type & peer->transports) || !(peer->socket.type)) {
24577

    
   
24630

   
24578
		set_socket_transport(&peer->socket, peer->default_outbound_transport);
24631
		set_socket_transport(&peer->socket, peer->default_outbound_transport);
24579
	}
24632
	}
24580

    
   
24633

   
24581
	if (fullcontact->used > 0) {
24634
	if (port && !realtime && peer->host_dynamic) {
24582
		ast_string_field_set(peer, fullcontact, fullcontact->str);
24635
		peer->defaddr.sin_port = htons(port);

    
   
24636
	} else if (port) {

    
   
24637
		peer->addr.sin_port = htons(port);

    
   
24638
	}

    
   
24639

   

    
   
24640
	if (ast_str_strlen(fullcontact)) {

    
   
24641
		ast_string_field_set(peer, fullcontact, ast_str_buffer(fullcontact));
24583
		peer->rt_fromcontact = TRUE;
24642
		peer->rt_fromcontact = TRUE;
24584
		/* We have a hostname in the fullcontact, but if we don't have an
24643
		/* We have a hostname in the fullcontact, but if we don't have an
24585
		 * address listed on the entry (or if it's 'dynamic'), then we need to
24644
		 * address listed on the entry (or if it's 'dynamic'), then we need to
24586
		 * parse the entry to obtain the IP address, so a dynamic host can be
24645
		 * parse the entry to obtain the IP address, so a dynamic host can be
24587
		 * contacted immediately after reload (as opposed to waiting for it to
24646
		 * contacted immediately after reload (as opposed to waiting for it to
[+20] [20] 16 lines
[+20] static struct sip_peer *build_peer(const char *name, struct ast_variable *v, struct ast_variable *alt, int realtime) static struct sip_peer *build_peer(const char *name, struct ast_variable *v, struct ast_variable *alt, int realtime, int devstate_only)
24604
			*params++ = '\0';
24663
			*params++ = '\0';
24605
		}
24664
		}
24606

    
   
24665

   
24607
		snprintf(transport, sizeof(transport), "_sip._%s", get_transport(peer->socket.type));
24666
		snprintf(transport, sizeof(transport), "_sip._%s", get_transport(peer->socket.type));
24608

    
   
24667

   
24609
		if (ast_dnsmgr_lookup(_srvlookup, &peer->addr, &peer->dnsmgr, sip_cfg.srvlookup ? transport : NULL)) {
24668
		if (ast_dnsmgr_lookup(_srvlookup, &peer->addr, &peer->dnsmgr, sip_cfg.srvlookup && !peer->portinuri ? transport : NULL)) {
24610
			ast_log(LOG_ERROR, "srvlookup failed for host: %s, on peer %s, removing peer\n", _srvlookup, peer->name);
24669
			ast_log(LOG_ERROR, "srvlookup failed for host: %s, on peer %s, removing peer\n", _srvlookup, peer->name);
24611
			unref_peer(peer, "getting rid of a peer pointer");
24670
			unref_peer(peer, "getting rid of a peer pointer");
24612
			return NULL;
24671
			return NULL;
24613
		}
24672
		}
24614

    
   
24673

   
24615
		ast_string_field_set(peer, tohost, srvlookup);
24674
		ast_string_field_set(peer, tohost, srvlookup);
24616
	}
24675
	}
24617

    
   
24676

   
24618
	if (!peer->addr.sin_port)
24677
	if (!peer->addr.sin_port) {
24619
		peer->addr.sin_port = htons(((peer->socket.type & SIP_TRANSPORT_TLS) ? STANDARD_TLS_PORT : STANDARD_SIP_PORT));
24678
		peer->addr.sin_port = htons(((peer->socket.type & SIP_TRANSPORT_TLS) ? STANDARD_TLS_PORT : STANDARD_SIP_PORT));
24620

    
   
24679
	}
24621
	if (!peer->socket.port)
24680
	if (!peer->defaddr.sin_port) {

    
   
24681
		peer->defaddr.sin_port = htons(((peer->socket.type & SIP_TRANSPORT_TLS) ? STANDARD_TLS_PORT : STANDARD_SIP_PORT));

    
   
24682
	}

    
   
24683
	if (!peer->socket.port) {
24622
		peer->socket.port = htons(((peer->socket.type & SIP_TRANSPORT_TLS) ? STANDARD_TLS_PORT : STANDARD_SIP_PORT));
24684
		peer->socket.port = htons(((peer->socket.type & SIP_TRANSPORT_TLS) ? STANDARD_TLS_PORT : STANDARD_SIP_PORT));

    
   
24685
	}
24623

    
   
24686

   
24624
	if (!sip_cfg.ignore_regexpire && peer->host_dynamic && realtime) {
24687
	if (!sip_cfg.ignore_regexpire && peer->host_dynamic && realtime) {
24625
		time_t nowtime = time(NULL);
24688
		time_t nowtime = time(NULL);
24626

    
   
24689

   
24627
		if ((nowtime - regseconds) > 0) {
24690
		if ((nowtime - regseconds) > 0) {
24628
			destroy_association(peer);
24691
			destroy_association(peer);
24629
			memset(&peer->addr, 0, sizeof(peer->addr));
24692
			memset(&peer->addr, 0, sizeof(peer->addr));
24630
			peer->lastms = -1;
24693
			peer->lastms = -1;
24631
			ast_debug(1, "Bah, we're expired (%d/%d/%d)!\n", (int)(nowtime - regseconds), (int)regseconds, (int)nowtime);
24694
			ast_debug(1, "Bah, we're expired (%d/%d/%d)!\n", (int)(nowtime - regseconds), (int)regseconds, (int)nowtime);
24632
		}
24695
		}
24633
	}
24696
	}
24634

    
   
24697

   
24635
	/* Startup regular pokes */
24698
	/* Startup regular pokes */
24636
	if (realtime && peer->lastms > 0) {
24699
	if (!devstate_only && realtime && peer->lastms > 0) {
24637
		ref_peer(peer, "schedule qualify");
24700
		ref_peer(peer, "schedule qualify");
24638
		sip_poke_peer(peer, 0);
24701
		sip_poke_peer(peer, 0);
24639
	}
24702
	}
24640

    
   
24703

   
24641
	ast_copy_flags(&peer->flags[0], &peerflags[0], mask[0].flags);
24704
	ast_copy_flags(&peer->flags[0], &peerflags[0], mask[0].flags);
24642
	ast_copy_flags(&peer->flags[1], &peerflags[1], mask[1].flags);
24705
	ast_copy_flags(&peer->flags[1], &peerflags[1], mask[1].flags);
24643
	if (ast_test_flag(&peer->flags[1], SIP_PAGE2_ALLOWSUBSCRIBE))
24706
	if (ast_test_flag(&peer->flags[1], SIP_PAGE2_ALLOWSUBSCRIBE)) {
24644
		sip_cfg.allowsubscribe = TRUE;	/* No global ban any more */
24707
		sip_cfg.allowsubscribe = TRUE;	/* No global ban any more */
24645
	if (!found && peer->host_dynamic && !peer->is_realtime)
24708
	}

    
   
24709
	if (!found && peer->host_dynamic && !peer->is_realtime) {
24646
		reg_source_db(peer);
24710
		reg_source_db(peer);

    
   
24711
	}
24647

    
   
24712

   
24648
	/* If they didn't request that MWI is sent *only* on subscribe, go ahead and
24713
	/* If they didn't request that MWI is sent *only* on subscribe, go ahead and
24649
	 * subscribe to it now. */
24714
	 * subscribe to it now. */
24650
	if (!ast_test_flag(&peer->flags[1], SIP_PAGE2_SUBSCRIBEMWIONLY) &&
24715
	if (!devstate_only && !ast_test_flag(&peer->flags[1], SIP_PAGE2_SUBSCRIBEMWIONLY) &&
24651
		!AST_LIST_EMPTY(&peer->mailboxes)) {
24716
		!AST_LIST_EMPTY(&peer->mailboxes)) {
24652
		add_peer_mwi_subs(peer);
24717
		add_peer_mwi_subs(peer);
24653
		/* Send MWI from the event cache only.  This is so we can send initial
24718
		/* Send MWI from the event cache only.  This is so we can send initial
24654
		 * MWI if app_voicemail got loaded before chan_sip.  If it is the other
24719
		 * MWI if app_voicemail got loaded before chan_sip.  If it is the other
24655
		 * way, then we will get events when app_voicemail gets loaded. */
24720
		 * way, then we will get events when app_voicemail gets loaded. */
24656
		sip_send_mwi_to_peer(peer, NULL, 1);
24721
		sip_send_mwi_to_peer(peer, NULL, 1);
24657
	}
24722
	}

    
   
24723

   
24658
	peer->the_mark = 0;
24724
	peer->the_mark = 0;
24659

    
   
24725

   
24660
	ast_free_ha(oldha);
24726
	ast_free_ha(oldha);
24661
	if (!ast_strlen_zero(peer->callback)) { /* build string from peer info */
24727
	if (!ast_strlen_zero(peer->callback)) { /* build string from peer info */
24662
		char *reg_string;
24728
		char *reg_string;
24663
		if (asprintf(&reg_string, "%s?%s:%s@%s/%s", peer->name, peer->username, peer->remotesecret ? peer->remotesecret : peer->secret, peer->tohost, peer->callback) < 0) {
24729
		if (asprintf(&reg_string, "%s?%s:%s@%s/%s", peer->name, peer->username, !ast_strlen_zero(peer->remotesecret) ? peer->remotesecret : peer->secret, peer->tohost, peer->callback) < 0) {
24664
			ast_log(LOG_WARNING, "asprintf() failed: %s\n", strerror(errno));
24730
			ast_log(LOG_WARNING, "asprintf() failed: %s\n", strerror(errno));
24665
		} else	if (reg_string) {
24731
		} else if (reg_string) {
24666
			sip_register(reg_string, 0); /* XXX TODO: count in registry_count */
24732
			sip_register(reg_string, 0); /* XXX TODO: count in registry_count */
24667
			ast_free(reg_string);
24733
			ast_free(reg_string);
24668
		}
24734
		}
24669
	}
24735
	}
24670
	return peer;
24736
	return peer;
[+20] [20] 677 lines
[+20] [+] static int reload_config(enum channelreloadreason reason)
25348
				global_qualify_peers = DEFAULT_QUALIFY_PEERS;
25414
				global_qualify_peers = DEFAULT_QUALIFY_PEERS;
25349
			}
25415
			}
25350
		} else if (!strcasecmp(v->name, "disallowed_methods")) {
25416
		} else if (!strcasecmp(v->name, "disallowed_methods")) {
25351
			char *disallow = ast_strdupa(v->value);
25417
			char *disallow = ast_strdupa(v->value);
25352
			mark_parsed_methods(&sip_cfg.disallowed_methods, disallow);
25418
			mark_parsed_methods(&sip_cfg.disallowed_methods, disallow);

    
   
25419
		} else if (!strcasecmp(v->name, "constantssrc")) {

    
   
25420
			ast_set2_flag(&global_flags[1], ast_true(v->value), SIP_PAGE2_CONSTANT_SSRC);
25353
		}
25421
		}
25354
	}
25422
	}
25355

    
   
25423

   
25356
	if (!sip_cfg.allow_external_domains && AST_LIST_EMPTY(&domain_list)) {
25424
	if (!sip_cfg.allow_external_domains && AST_LIST_EMPTY(&domain_list)) {
25357
		ast_log(LOG_WARNING, "To disallow external domains, you need to configure local SIP domains.\n");
25425
		ast_log(LOG_WARNING, "To disallow external domains, you need to configure local SIP domains.\n");
[+20] [20] 23 lines
[+20] static int reload_config(enum channelreloadreason reason)
25381
		while (cat) {
25449
		while (cat) {
25382
			if (strcasecmp(cat, "general")) {
25450
			if (strcasecmp(cat, "general")) {
25383
				hassip = ast_variable_retrieve(ucfg, cat, "hassip");
25451
				hassip = ast_variable_retrieve(ucfg, cat, "hassip");
25384
				registersip = ast_variable_retrieve(ucfg, cat, "registersip");
25452
				registersip = ast_variable_retrieve(ucfg, cat, "registersip");
25385
				if (ast_true(hassip) || (!hassip && genhassip)) {
25453
				if (ast_true(hassip) || (!hassip && genhassip)) {
25386
					peer = build_peer(cat, gen, ast_variable_browse(ucfg, cat), 0);
25454
					peer = build_peer(cat, gen, ast_variable_browse(ucfg, cat), 0, 0);
25387
					if (peer) {
25455
					if (peer) {
25388
						ao2_t_link(peers, peer, "link peer into peer table");
25456
						ao2_t_link(peers, peer, "link peer into peer table");
25389
						if ((peer->type & SIP_TYPE_PEER) && peer->addr.sin_addr.s_addr) {
25457
						if ((peer->type & SIP_TYPE_PEER) && peer->addr.sin_addr.s_addr) {
25390
							ao2_t_link(peers_by_ip, peer, "link peer into peers_by_ip table");
25458
							ao2_t_link(peers_by_ip, peer, "link peer into peers_by_ip table");
25391
						}
25459
						}
[+20] [20] 51 lines
[+20] static int reload_config(enum channelreloadreason reason)
25443
				;
25511
				;
25444
			} else {
25512
			} else {
25445
				ast_log(LOG_WARNING, "Unknown type '%s' for '%s' in %s\n", utype, cat, "sip.conf");
25513
				ast_log(LOG_WARNING, "Unknown type '%s' for '%s' in %s\n", utype, cat, "sip.conf");
25446
				continue;
25514
				continue;
25447
			}
25515
			}
25448
			peer = build_peer(cat, ast_variable_browse(cfg, cat), NULL, 0);
25516
			peer = build_peer(cat, ast_variable_browse(cfg, cat), NULL, 0, 0);
25449
			if (peer) {
25517
			if (peer) {
25450
				ao2_t_link(peers, peer, "link peer into peers table");
25518
				ao2_t_link(peers, peer, "link peer into peers table");
25451
				if ((peer->type & SIP_TYPE_PEER) && peer->addr.sin_addr.s_addr) {
25519
				if ((peer->type & SIP_TYPE_PEER) && peer->addr.sin_addr.s_addr) {
25452
					ao2_t_link(peers_by_ip, peer, "link peer into peers_by_ip table");
25520
					ao2_t_link(peers_by_ip, peer, "link peer into peers_by_ip table");
25453
				}
25521
				}
[+20] [20] 924 lines
  1. /trunk/channels/chan_sip.c: Loading...

https://reviewboard.asterisk.org/ runs on a server provided by Digium, Inc. and uses bandwidth donated to the open source Asterisk community by API Digital Communications in Huntsville, AL USA.
Please report problems with this site to asteriskteam@digium.com.