Implement a handle_response_refer function to take care of responses
to outbound REFERS. Not that common, but still needed. git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@18022 65c4cc65-6c06-0410-ace0-fbb531ad65f3
This commit is contained in:
parent
1e8d1dda7d
commit
9bd9bceef7
1 changed files with 100 additions and 5 deletions
|
@ -9812,6 +9812,58 @@ static void handle_response_invite(struct sip_pvt *p, int resp, char *rest, stru
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* \brief Handle SIP response in REFER transaction
|
||||||
|
We've sent a REFER, now handle responses to it
|
||||||
|
*/
|
||||||
|
static void handle_response_refer(struct sip_pvt *p, int resp, char *rest, struct sip_request *req, int ignore, int seqno)
|
||||||
|
{
|
||||||
|
char *auth = "Proxy-Authenticate";
|
||||||
|
char *auth2 = "Proxy-Authorization";
|
||||||
|
char iabuf[INET_ADDRSTRLEN];
|
||||||
|
|
||||||
|
switch (resp) {
|
||||||
|
case 202: /* Transfer accepted */
|
||||||
|
/* We need to do something here */
|
||||||
|
/* The transferee is now sending INVITE to target */
|
||||||
|
/* Now wait for next message */
|
||||||
|
if (option_debug > 2)
|
||||||
|
ast_log(LOG_DEBUG, "Got 202 accepted on transfer\n");
|
||||||
|
/* We should hang along, waiting for NOTIFY's here */
|
||||||
|
/* (done in a separate function) */
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 401: /* Not www-authorized on SIP method */
|
||||||
|
case 407: /* Proxy auth */
|
||||||
|
if (ast_strlen_zero(p->authname)) {
|
||||||
|
ast_log(LOG_WARNING, "Asked to authenticate REFER to %s:%d but we have no matching peer or realm auth!\n",
|
||||||
|
ast_inet_ntoa(iabuf, sizeof(iabuf), p->recv.sin_addr), ntohs(p->recv.sin_port));
|
||||||
|
ast_set_flag(&p->flags[0], SIP_NEEDDESTROY);
|
||||||
|
}
|
||||||
|
if (resp == 401) {
|
||||||
|
auth = "WWW-Authenticate";
|
||||||
|
auth2 = "Authorization";
|
||||||
|
}
|
||||||
|
if ((p->authtries > 1) || do_proxy_auth(p, req, auth, auth2, SIP_REFER, 0)) {
|
||||||
|
ast_log(LOG_NOTICE, "Failed to authenticate on REFER to '%s'\n", get_header(&p->initreq, "From"));
|
||||||
|
ast_set_flag(&p->flags[0], SIP_NEEDDESTROY);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
|
||||||
|
case 500: /* Server error */
|
||||||
|
case 501: /* Method not implemented */
|
||||||
|
/* Return to the current call onhold */
|
||||||
|
/* Status flag needed to be reset */
|
||||||
|
ast_log(LOG_NOTICE, "SIP transfer failed, call miserably fails. \n");
|
||||||
|
ast_set_flag(&p->flags[0], SIP_NEEDDESTROY);
|
||||||
|
break;
|
||||||
|
case 603: /* Transfer declined */
|
||||||
|
ast_log(LOG_NOTICE, "SIP transfer declined, call fails. \n" );
|
||||||
|
ast_set_flag(&p->flags[0], SIP_NEEDDESTROY);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*! \brief Handle responses on REGISTER to services */
|
/*! \brief Handle responses on REGISTER to services */
|
||||||
static int handle_response_register(struct sip_pvt *p, int resp, char *rest, struct sip_request *req, int ignore, int seqno)
|
static int handle_response_register(struct sip_pvt *p, int resp, char *rest, struct sip_request *req, int ignore, int seqno)
|
||||||
{
|
{
|
||||||
|
@ -10065,9 +10117,15 @@ static void handle_response(struct sip_pvt *p, int resp, char *rest, struct sip_
|
||||||
res = handle_response_register(p, resp, rest, req, ignore, seqno);
|
res = handle_response_register(p, resp, rest, req, ignore, seqno);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case 202: /* Transfer accepted */
|
||||||
|
if (sipmethod == SIP_REFER)
|
||||||
|
handle_response_refer(p, resp, rest, req, ignore, seqno);
|
||||||
|
break;
|
||||||
case 401: /* Not www-authorized on SIP method */
|
case 401: /* Not www-authorized on SIP method */
|
||||||
if (sipmethod == SIP_INVITE) {
|
if (sipmethod == SIP_INVITE) {
|
||||||
handle_response_invite(p, resp, rest, req, ignore, seqno);
|
handle_response_invite(p, resp, rest, req, ignore, seqno);
|
||||||
|
} else if (sipmethod == SIP_REFER) {
|
||||||
|
handle_response_refer(p, resp, rest, req, ignore, seqno);
|
||||||
} else if (p->registry && sipmethod == SIP_REGISTER) {
|
} else if (p->registry && sipmethod == SIP_REGISTER) {
|
||||||
res = handle_response_register(p, resp, rest, req, ignore, seqno);
|
res = handle_response_register(p, resp, rest, req, ignore, seqno);
|
||||||
} else {
|
} else {
|
||||||
|
@ -10095,7 +10153,9 @@ static void handle_response(struct sip_pvt *p, int resp, char *rest, struct sip_
|
||||||
case 407: /* Proxy auth required */
|
case 407: /* Proxy auth required */
|
||||||
if (sipmethod == SIP_INVITE) {
|
if (sipmethod == SIP_INVITE) {
|
||||||
handle_response_invite(p, resp, rest, req, ignore, seqno);
|
handle_response_invite(p, resp, rest, req, ignore, seqno);
|
||||||
} else if (sipmethod == SIP_BYE || sipmethod == SIP_REFER) {
|
} else if (sipmethod == SIP_REFER) {
|
||||||
|
handle_response_refer(p, resp, rest, req, ignore, seqno);
|
||||||
|
} else if (sipmethod == SIP_BYE) {
|
||||||
if (ast_strlen_zero(p->authname))
|
if (ast_strlen_zero(p->authname))
|
||||||
ast_log(LOG_WARNING, "Asked to authenticate %s, to %s:%d but we have no matching peer!\n",
|
ast_log(LOG_WARNING, "Asked to authenticate %s, to %s:%d but we have no matching peer!\n",
|
||||||
msg, ast_inet_ntoa(iabuf, sizeof(iabuf), p->recv.sin_addr), ntohs(p->recv.sin_port));
|
msg, ast_inet_ntoa(iabuf, sizeof(iabuf), p->recv.sin_addr), ntohs(p->recv.sin_port));
|
||||||
|
@ -10117,9 +10177,17 @@ static void handle_response(struct sip_pvt *p, int resp, char *rest, struct sip_
|
||||||
case 501: /* Not Implemented */
|
case 501: /* Not Implemented */
|
||||||
if (sipmethod == SIP_INVITE) {
|
if (sipmethod == SIP_INVITE) {
|
||||||
handle_response_invite(p, resp, rest, req, ignore, seqno);
|
handle_response_invite(p, resp, rest, req, ignore, seqno);
|
||||||
|
} else if (sipmethod == SIP_REFER) {
|
||||||
|
handle_response_refer(p, resp, rest, req, ignore, seqno);
|
||||||
} else
|
} else
|
||||||
ast_log(LOG_WARNING, "Host '%s' does not implement '%s'\n", ast_inet_ntoa(iabuf, sizeof(iabuf), p->sa.sin_addr), msg);
|
ast_log(LOG_WARNING, "Host '%s' does not implement '%s'\n", ast_inet_ntoa(iabuf, sizeof(iabuf), p->sa.sin_addr), msg);
|
||||||
break;
|
break;
|
||||||
|
case 603: /* Declined transfer */
|
||||||
|
if (sipmethod == SIP_REFER) {
|
||||||
|
handle_response_refer(p, resp, rest, req, ignore, seqno);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
/* Fallthrough */
|
||||||
default:
|
default:
|
||||||
if ((resp >= 300) && (resp < 700)) {
|
if ((resp >= 300) && (resp < 700)) {
|
||||||
/* Fatal response */
|
/* Fatal response */
|
||||||
|
@ -10152,10 +10220,11 @@ static void handle_response(struct sip_pvt *p, int resp, char *rest, struct sip_
|
||||||
/* channel now destroyed - dec the inUse counter */
|
/* channel now destroyed - dec the inUse counter */
|
||||||
update_call_counter(p, DEC_CALL_LIMIT);
|
update_call_counter(p, DEC_CALL_LIMIT);
|
||||||
break;
|
break;
|
||||||
case 482: /* SIP is incapable of performing a hairpin call, which
|
case 482: /*
|
||||||
|
\note SIP is incapable of performing a hairpin call, which
|
||||||
is yet another failure of not having a layer 2 (again, YAY
|
is yet another failure of not having a layer 2 (again, YAY
|
||||||
IETF for thinking ahead). So we treat this as a call
|
IETF for thinking ahead). So we treat this as a call
|
||||||
forward and hope we end up at the right place... */
|
forward and hope we end up at the right place... */
|
||||||
ast_log(LOG_DEBUG, "Hairpin detected, setting up call forward for what it's worth\n");
|
ast_log(LOG_DEBUG, "Hairpin detected, setting up call forward for what it's worth\n");
|
||||||
if (p->owner)
|
if (p->owner)
|
||||||
ast_string_field_build(p->owner, call_forward,
|
ast_string_field_build(p->owner, call_forward,
|
||||||
|
@ -10167,6 +10236,12 @@ static void handle_response(struct sip_pvt *p, int resp, char *rest, struct sip_
|
||||||
case 410: /* Gone */
|
case 410: /* Gone */
|
||||||
case 400: /* Bad Request */
|
case 400: /* Bad Request */
|
||||||
case 500: /* Server error */
|
case 500: /* Server error */
|
||||||
|
if (sipmethod == SIP_REFER) {
|
||||||
|
handle_response_refer(p, resp, rest, req, ignore, seqno);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
/* Fall through */
|
||||||
|
handle_response_refer(p, resp, rest, req, ignore, seqno);
|
||||||
case 503: /* Service Unavailable */
|
case 503: /* Service Unavailable */
|
||||||
if (owner)
|
if (owner)
|
||||||
ast_queue_control(p->owner, AST_CONTROL_CONGESTION);
|
ast_queue_control(p->owner, AST_CONTROL_CONGESTION);
|
||||||
|
@ -10220,9 +10295,16 @@ static void handle_response(struct sip_pvt *p, int resp, char *rest, struct sip_
|
||||||
/* We successfully transmitted a message */
|
/* We successfully transmitted a message */
|
||||||
ast_set_flag(&p->flags[0], SIP_NEEDDESTROY);
|
ast_set_flag(&p->flags[0], SIP_NEEDDESTROY);
|
||||||
break;
|
break;
|
||||||
|
case 202: /* Transfer accepted */
|
||||||
|
if (sipmethod == SIP_REFER) {
|
||||||
|
handle_response_refer(p, resp, rest, req, ignore, seqno);
|
||||||
|
}
|
||||||
|
break;
|
||||||
case 401: /* www-auth */
|
case 401: /* www-auth */
|
||||||
case 407:
|
case 407:
|
||||||
if (sipmethod == SIP_BYE || sipmethod == SIP_REFER) {
|
if (sipmethod == SIP_REFER) {
|
||||||
|
handle_response_refer(p, resp, rest, req, ignore, seqno);
|
||||||
|
} else if (sipmethod == SIP_BYE) {
|
||||||
char *auth, *auth2;
|
char *auth, *auth2;
|
||||||
|
|
||||||
if (resp == 407) {
|
if (resp == 407) {
|
||||||
|
@ -10246,6 +10328,19 @@ static void handle_response(struct sip_pvt *p, int resp, char *rest, struct sip_
|
||||||
handle_response_invite(p, resp, rest, req, ignore, seqno);
|
handle_response_invite(p, resp, rest, req, ignore, seqno);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case 501: /* Not Implemented */
|
||||||
|
if (sipmethod == SIP_INVITE) {
|
||||||
|
handle_response_invite(p, resp, rest, req, ignore, seqno);
|
||||||
|
} else if (sipmethod == SIP_REFER) {
|
||||||
|
handle_response_refer(p, resp, rest, req, ignore, seqno);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 603: /* Declined transfer */
|
||||||
|
if (sipmethod == SIP_REFER) {
|
||||||
|
handle_response_refer(p, resp, rest, req, ignore, seqno);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
/* Fallthrough */
|
||||||
default: /* Errors without handlers */
|
default: /* Errors without handlers */
|
||||||
if ((resp >= 100) && (resp < 200)) {
|
if ((resp >= 100) && (resp < 200)) {
|
||||||
if (sipmethod == SIP_INVITE) { /* re-invite */
|
if (sipmethod == SIP_INVITE) { /* re-invite */
|
||||||
|
|
Loading…
Reference in a new issue