[asterisk-commits] rizzo: branch rizzo/astobj2 r72798 - /team/rizzo/astobj2/channels/chan_sip.c
SVN commits to the Asterisk project
asterisk-commits at lists.digium.com
Sat Jun 30 15:37:08 CDT 2007
Author: rizzo
Date: Sat Jun 30 15:37:08 2007
New Revision: 72798
URL: http://svn.digium.com/view/asterisk?view=rev&rev=72798
Log:
blind merge from trunk up to rev 59083
Modified:
team/rizzo/astobj2/channels/chan_sip.c
Modified: team/rizzo/astobj2/channels/chan_sip.c
URL: http://svn.digium.com/view/asterisk/team/rizzo/astobj2/channels/chan_sip.c?view=diff&rev=72798&r1=72797&r2=72798
==============================================================================
--- team/rizzo/astobj2/channels/chan_sip.c (original)
+++ team/rizzo/astobj2/channels/chan_sip.c Sat Jun 30 15:37:08 2007
@@ -568,6 +568,8 @@
static int global_autoframing; /*!< Turn autoframing on or off. */
static enum transfermodes global_allowtransfer; /*!< SIP Refer restriction scheme */
static struct sip_proxy global_outboundproxy; /*!< Outbound proxy */
+
+static int global_matchexterniplocally; /*!< Match externip/externhost setting against localnet setting */
/*! \brief Codecs that we support by default: */
static int global_capability = AST_FORMAT_ULAW | AST_FORMAT_ALAW | AST_FORMAT_GSM | AST_FORMAT_H263;
@@ -2170,7 +2172,7 @@
if (localaddr && externip.sin_addr.s_addr &&
ast_apply_ha(localaddr, &theirs) &&
- !ast_apply_ha(localaddr, &ours)) {
+ (!global_matchexterniplocally || !ast_apply_ha(localaddr, &ours))) {
if (externexpire && time(NULL) >= externexpire) {
struct ast_hostent ahp;
struct hostent *hp;
@@ -5472,7 +5474,7 @@
int codec;
int destiterator = 0;
int iterator;
- int sendonly = 0;
+ int sendonly = -1;
int numberofports;
struct ast_rtp *newaudiortp, *newvideortp, *newtextrtp; /* Buffers for codec handling */
int newjointcapability; /* Negotiated capability */
@@ -5629,14 +5631,20 @@
} else {
/* XXX This could block for a long time, and block the main thread! XXX */
if (audio) {
- if ( !(hp = ast_gethostbyname(host, &audiohp)))
+ if ( !(hp = ast_gethostbyname(host, &audiohp))) {
ast_log(LOG_WARNING, "Unable to lookup RTP Audio host in secondary c= line, '%s'\n", c);
+ return -2;
+ }
} else if (video) {
- if (!(vhp = ast_gethostbyname(host, &videohp)))
+ if (!(vhp = ast_gethostbyname(host, &videohp))) {
ast_log(LOG_WARNING, "Unable to lookup RTP video host in secondary c= line, '%s'\n", c);
+ return -2;
+ }
} else if (text) {
- if (!(thp = ast_gethostbyname(host, &texthp)))
+ if (!(thp = ast_gethostbyname(host, &texthp))) {
ast_log(LOG_WARNING, "Unable to lookup RTP text host in secondary c= line, '%s'\n", c);
+ return -2;
+ }
}
}
@@ -5744,13 +5752,16 @@
continue;
}
if (!strcasecmp(a, "sendonly")) {
- sendonly = 1;
+ if (sendonly == -1)
+ sendonly = 1;
continue;
} else if (!strcasecmp(a, "inactive")) {
- sendonly = 2;
+ if (sendonly == -1)
+ sendonly = 2;
continue;
} else if (!strcasecmp(a, "sendrecv")) {
- sendonly = 0;
+ if (sendonly == -1)
+ sendonly = 0;
continue;
} else if (strlen(a) > 5 && !strncasecmp(a, "ptime", 5)) {
char *tmp = strrchr(a, ':');
@@ -6024,39 +6035,32 @@
ast_set_write_format(p->owner, p->owner->writeformat);
}
- if (sin.sin_addr.s_addr && !sendonly) {
- ast_queue_control(p->owner, AST_CONTROL_UNHOLD);
- /* Activate a re-invite */
- ast_queue_frame(p->owner, &ast_null_frame);
- } else if (!sin.sin_addr.s_addr || sendonly) {
- ast_queue_control_data(p->owner, AST_CONTROL_HOLD,
+ if (ast_test_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD) && sin.sin_addr.s_addr && (!sendonly || sendonly == -1)) {
+ ast_queue_control(p->owner, AST_CONTROL_UNHOLD);
+ /* Activate a re-invite */
+ ast_queue_frame(p->owner, &ast_null_frame);
+ /* Queue Manager Unhold event */
+ append_history(p, "Unhold", "%s", req->data);
+ if (global_callevents)
+ manager_event(EVENT_FLAG_CALL, "Unhold",
+ "Channel: %s\r\n"
+ "Uniqueid: %s\r\n",
+ p->owner->name,
+ p->owner->uniqueid);
+ if (global_notifyhold)
+ sip_peer_hold(p, FALSE);
+ ast_clear_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD); /* Clear both flags */
+ } else if (!sin.sin_addr.s_addr || (sendonly && sendonly != -1)) {
+ ast_queue_control_data(p->owner, AST_CONTROL_HOLD,
S_OR(p->mohsuggest, NULL),
!ast_strlen_zero(p->mohsuggest) ? strlen(p->mohsuggest) + 1 : 0);
- if (sendonly)
- ast_rtp_stop(p->rtp);
- /* RTCP needs to go ahead, even if we're on hold!!! */
- /* Activate a re-invite */
- ast_queue_frame(p->owner, &ast_null_frame);
- }
-
- /* Manager Hold and Unhold events must be generated, if necessary */
- if (sin.sin_addr.s_addr && !sendonly) {
- if (ast_test_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD)) {
- append_history(p, "Unhold", "%s", req->data);
- if (global_callevents)
- manager_event(EVENT_FLAG_CALL, "Unhold",
- "Channel: %s\r\n"
- "Uniqueid: %s\r\n",
- p->owner->name,
- p->owner->uniqueid);
- if (global_notifyhold)
- sip_peer_hold(p, FALSE);
- }
- ast_clear_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD); /* Clear both flags */
- } else if (!sin.sin_addr.s_addr || sendonly ) {
- /* No address for RTP, we're on hold */
+ if (sendonly)
+ ast_rtp_stop(p->rtp);
+ /* RTCP needs to go ahead, even if we're on hold!!! */
+ /* Activate a re-invite */
+ ast_queue_frame(p->owner, &ast_null_frame);
+ /* Queue Manager Hold event */
append_history(p, "Hold", "%s", req->data);
-
if (global_callevents && !ast_test_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD)) {
manager_event(EVENT_FLAG_CALL, "Hold",
"Channel: %s\r\n"
@@ -8172,7 +8176,18 @@
/* Fromdomain is what we are registering to, regardless of actual
host name from SRV */
- snprintf(addr, sizeof(addr), "sip:%s", S_OR(p->fromdomain, r->hostname));
+ if (!ast_strlen_zero(p->fromdomain)) {
+ if (r->portno && r->portno != STANDARD_SIP_PORT)
+ snprintf(addr, sizeof(addr), "sip:%s:%d", p->fromdomain, r->portno);
+ else
+ snprintf(addr, sizeof(addr), "sip:%s", p->fromdomain);
+ } else {
+ if (r->portno && r->portno != STANDARD_SIP_PORT)
+ snprintf(addr, sizeof(addr), "sip:%s:%d", r->hostname, r->portno);
+ else
+ snprintf(addr, sizeof(addr), "sip:%s", r->hostname);
+ }
+
ast_string_field_set(p, uri, addr);
p->branch ^= ast_random();
@@ -10239,6 +10254,10 @@
}
{
char *tmp = ast_strdupa(of);
+ /* We need to be able to handle auth-headers looking like
+ <sip:8164444422;phone-context=+1 at 1.2.3.4:5060;user=phone;tag=SDadkoa01-gK0c3bdb43>
+ */
+ tmp = strsep(&tmp, ";");
if (ast_is_shrinkable_phonenumber(tmp))
ast_shrink_phone_number(tmp);
ast_string_field_set(p, cid_num, tmp);
@@ -13378,9 +13397,10 @@
case 200: /* 200 OK */
p->authtries = 0; /* Reset authentication counter */
- if (sipmethod == SIP_MESSAGE) {
- /* We successfully transmitted a message */
- set_destroy(p);
+ if (sipmethod == SIP_MESSAGE || sipmethod == SIP_INFO) {
+ /* We successfully transmitted a message
+ or a video update request in INFO */
+ /* Nothing happens here - the message is inside a dialog */
} else if (sipmethod == SIP_INVITE) {
handle_response_invite(p, resp, rest, req, seqno);
} else if (sipmethod == SIP_NOTIFY) {
@@ -13517,7 +13537,8 @@
if ((option_verbose > 2) && (resp != 487))
ast_verbose(VERBOSE_PREFIX_3 "Got SIP response %d \"%s\" back from %s\n", resp, rest, ast_inet_ntoa(p->sa.sin_addr));
- stop_media_flows(p); /* Immediately stop RTP, VRTP and UDPTL as applicable */
+ if (sipmethod == SIP_INVITE)
+ stop_media_flows(p); /* Immediately stop RTP, VRTP and UDPTL as applicable */
/* XXX Locking issues?? XXX */
switch(resp) {
@@ -13561,14 +13582,15 @@
break;
default:
/* Send hangup */
- if (owner)
+ if (owner && sipmethod != SIP_MESSAGE && sipmethod != SIP_INFO)
ast_queue_hangup(p->owner);
break;
}
/* ACK on invite */
if (sipmethod == SIP_INVITE)
transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE);
- sip_alreadygone(p);
+ if (sipmethod != SIP_MESSAGE && sipmethod != SIP_INFO)
+ sip_alreadygone(p);
if (!p->owner)
set_destroy(p);
} else if ((resp >= 100) && (resp < 200)) {
@@ -13624,10 +13646,10 @@
}
} else if (sipmethod == SIP_BYE)
set_destroy(p);
- else if (sipmethod == SIP_MESSAGE)
- /* We successfully transmitted a message */
- /* XXX Why destroy this pvt after message transfer? Bad */
- set_destroy(p);
+ else if (sipmethod == SIP_MESSAGE || sipmethod == SIP_INFO)
+ /* We successfully transmitted a message or
+ a video update request in INFO */
+ ;
else if (sipmethod == SIP_BYE)
/* Ok, we're ready to go */
set_destroy(p);
@@ -15526,9 +15548,25 @@
p->subscribed = CPIM_PIDF_XML; /* RFC 3863 format */
} else if (strstr(accept, "application/xpidf+xml")) {
p->subscribed = XPIDF_XML; /* Early pre-RFC 3863 format with MSN additions (Microsoft Messenger) */
+ } else if (ast_strlen_zero(accept)) {
+ if (p->subscribed == NONE) { /* if the subscribed field is not already set, and there is no accept header... */
+ transmit_response(p, "489 Bad Event", req);
+
+ ast_log(LOG_WARNING,"SUBSCRIBE failure: no Accept header: pvt: stateid: %d, laststate: %d, dialogver: %d, subscribecont: '%s', subscribeuri: '%s'\n",
+ p->stateid, p->laststate, p->dialogver, p->subscribecontext, p->subscribeuri);
+ ast_set_flag(&p->flags[0], SIP_NEEDDESTROY);
+ return 0;
+ }
+ /* if p->subscribed is non-zero, then accept is not obligatory; according to rfc 3265 section 3.1.3, at least.
+ so, we'll just let it ride, keeping the value from a previous subscription, and not abort the subscription */
+
} else {
/* Can't find a format for events that we know about */
- transmit_response(p, "489 Bad Event", req);
+ char mybuf[200];
+ snprintf(mybuf,sizeof(mybuf),"489 Bad Event (format %s)", accept);
+ transmit_response(p, mybuf, req);
+ ast_log(LOG_WARNING,"SUBSCRIBE failure: unrecognized format: '%s' pvt: subscribed: %d, stateid: %d, laststate: %d, dialogver: %d, subscribecont: '%s', subscribeuri: '%s'\n",
+ accept, (int)p->subscribed, p->stateid, p->laststate, p->dialogver, p->subscribecontext, p->subscribeuri);
set_destroy(p);
return 0;
}
@@ -15789,6 +15827,10 @@
if (sscanf(e, "%d %n", &respid, &len) != 1) {
ast_log(LOG_WARNING, "Invalid response: '%s'\n", e);
} else {
+ if (respid <= 0) {
+ ast_log(LOG_WARNING, "Invalid SIP response code: '%d'\n", respid);
+ return 0;
+ }
/* More SIP ridiculousness, we have to ignore bogus contacts in 100 etc responses */
if ((respid == 200) || ((respid >= 300) && (respid <= 399)))
extract_uri(p, req);
@@ -15861,7 +15903,7 @@
}
if (!e && (p->method == SIP_INVITE || p->method == SIP_SUBSCRIBE || p->method == SIP_REGISTER || p->method == SIP_NOTIFY)) {
- transmit_response(p, "503 Server error", req);
+ transmit_response(p, "400 Bad request", req);
sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
return -1;
}
@@ -17485,6 +17527,8 @@
global_callevents = FALSE;
global_t1min = DEFAULT_T1MIN;
+ global_matchexterniplocally = FALSE;
+
/* Copy the default jb config over global_jbconf */
memcpy(&global_jbconf, &default_jbconf, sizeof(struct ast_jb_conf));
@@ -17527,6 +17571,7 @@
M_INT_GE0("rtpkeepalive", global_rtpkeepalive, 0)
M_BOOL("compactheaders", compactheaders)
M_STR("notifymimetype", default_notifymime)
+ M_BOOL("limitonpeer", global_limitonpeers) /* accept a missing trailing 's' */
M_BOOL("limitonpeers", global_limitonpeers)
M_BOOL("directrtpsetup", global_directrtpsetup)
M_BOOL("notifyringing", global_notifyringing)
@@ -17656,6 +17701,7 @@
} } )
M_BOOL("callevents", global_callevents)
M_INT_GE0("maxcallbitrate", default_maxcallbitrate, DEFAULT_MAX_CALL_BITRATE)
+ M_BOOL("matchexterniplocally", global_matchexterniplocally)
M_END(ast_log(LOG_NOTICE, "sip.conf [general]: unknown option %s = %s\n",
v->name, v->value); )
}
@@ -18301,7 +18347,7 @@
static int sip_get_codec(struct ast_channel *chan)
{
struct sip_pvt *p = chan->tech_pvt;
- return p->peercapability;
+ return p->peercapability ? p->peercapability : p->capability;
}
/*! \brief Send a poke to all known peers
More information about the asterisk-commits
mailing list