aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorkpfleming <kpfleming@f38db490-d61c-443f-a65b-d21fe96a405b>2005-10-04 23:28:57 +0000
committerkpfleming <kpfleming@f38db490-d61c-443f-a65b-d21fe96a405b>2005-10-04 23:28:57 +0000
commit01e127d11225f757af4ae92d59c68e58752f9727 (patch)
tree80c6dd781f33a51a5d3e19044bcd1c2d866bf681
parent024f2617d8262e60fa1ee1a6496b079557fe72be (diff)
support call duration limits on inbound OSP calls (issue #5346)
git-svn-id: http://svn.digium.com/svn/asterisk/trunk@6721 f38db490-d61c-443f-a65b-d21fe96a405b
-rwxr-xr-xchannel.c25
-rwxr-xr-xchannels/chan_sip.c58
-rwxr-xr-xinclude/asterisk/channel.h12
-rwxr-xr-xres/res_osp.c123
4 files changed, 131 insertions, 87 deletions
diff --git a/channel.c b/channel.c
index 9296ed10d..3ffeebaef 100755
--- a/channel.c
+++ b/channel.c
@@ -273,6 +273,31 @@ void ast_channel_setwhentohangup(struct ast_channel *chan, time_t offset)
return;
}
+/*--- ast_channel_cmpwhentohangup: Compare a offset with when to hangup channel */
+int ast_channel_cmpwhentohangup(struct ast_channel *chan, time_t offset)
+{
+ time_t whentohangup;
+
+ if (chan->whentohangup == 0) {
+ if (offset == 0)
+ return (0);
+ else
+ return (-1);
+ } else {
+ if (offset == 0)
+ return (1);
+ else {
+ whentohangup = offset + time (NULL);
+ if (chan->whentohangup < whentohangup)
+ return (1);
+ else if (chan->whentohangup == whentohangup)
+ return (0);
+ else
+ return (-1);
+ }
+ }
+}
+
/*--- ast_channel_register: Register a new telephony channel in Asterisk */
int ast_channel_register(const struct ast_channel_tech *tech)
{
diff --git a/channels/chan_sip.c b/channels/chan_sip.c
index 5505a846f..2b449c5bf 100755
--- a/channels/chan_sip.c
+++ b/channels/chan_sip.c
@@ -637,6 +637,7 @@ static struct sip_pvt {
#ifdef OSP_SUPPORT
int osphandle; /* OSP Handle for call */
time_t ospstart; /* OSP Start time */
+ unsigned int osptimelimit; /* OSP call duration limit */
#endif
struct sip_request initreq; /* Initial request */
@@ -2666,6 +2667,10 @@ static struct ast_channel *sip_new(struct sip_pvt *i, int state, char *title)
struct ast_channel *tmp;
struct ast_variable *v = NULL;
int fmt;
+#ifdef OSP_SUPPORT
+ char iabuf[INET_ADDRSTRLEN];
+ char peer[MAXHOSTNAMELEN];
+#endif
ast_mutex_unlock(&i->lock);
/* Don't hold a sip pvt lock while we allocate a channel */
@@ -2757,6 +2762,10 @@ static struct ast_channel *sip_new(struct sip_pvt *i, int state, char *title)
if (!ast_strlen_zero(i->callid)) {
pbx_builtin_setvar_helper(tmp, "SIPCALLID", i->callid);
}
+#ifdef OSP_SUPPORT
+ snprintf(peer, sizeof(peer), "[%s]:%d", ast_inet_ntoa(iabuf, sizeof(iabuf), i->sa.sin_addr), ntohs(i->sa.sin_port));
+ pbx_builtin_setvar_helper(tmp, "OSPPEER", peer);
+#endif
ast_setstate(tmp, state);
if (state != AST_STATE_DOWN) {
if (ast_pbx_start(tmp)) {
@@ -2975,6 +2984,7 @@ static struct sip_pvt *sip_alloc(char *callid, struct sockaddr_in *sin, int useg
p->timer_t1 = 500; /* Default SIP retransmission timer T1 (RFC 3261) */
#ifdef OSP_SUPPORT
p->osphandle = -1;
+ p->osptimelimit = 0;
#endif
if (sin) {
memcpy(&p->sa, sin, sizeof(p->sa));
@@ -5957,6 +5967,22 @@ static void build_route(struct sip_pvt *p, struct sip_request *req, int backward
list_route(p->route);
}
+#ifdef OSP_SUPPORT
+/*--- check_osptoken: Validate OSP token for user authrroization ---*/
+static int check_osptoken (struct sip_pvt *p, char *token)
+{
+ char tmp[80];
+
+ if (ast_osp_validate (NULL, token, &p->osphandle, &p->osptimelimit, p->cid_num, p->sa.sin_addr, p->exten) < 1) {
+ return (-1);
+ } else {
+ snprintf (tmp, sizeof (tmp), "%d", p->osphandle);
+ pbx_builtin_setvar_helper (p->owner, "_OSPHANDLE", tmp);
+ return (0);
+ }
+}
+#endif
+
/*--- check_auth: Check user authorization from peer definition ---*/
/* Some actions, like REGISTER and INVITEs from peers require
authentication (if peer have secret set) */
@@ -5968,9 +5994,7 @@ static int check_auth(struct sip_pvt *p, struct sip_request *req, char *randdata
char *respheader = "Proxy-Authenticate";
char *authtoken;
#ifdef OSP_SUPPORT
- char tmp[80];
char *osptoken;
- unsigned int osptimelimit;
#endif
/* Always OK if no secret */
if (ast_strlen_zero(secret) && ast_strlen_zero(md5secret)
@@ -6002,14 +6026,7 @@ static int check_auth(struct sip_pvt *p, struct sip_request *req, char *randdata
}
}
else {
- if (ast_osp_validate (NULL, osptoken, &p->osphandle, &osptimelimit, p->cid_num, p->sa.sin_addr, p->exten) < 1) {
- return (-1);
- }
- else {
- snprintf (tmp, sizeof (tmp), "%d", p->osphandle);
- pbx_builtin_setvar_helper (p->owner, "_OSPHANDLE", tmp);
- return (0);
- }
+ return (check_osptoken (p, osptoken));
}
break;
case SIP_OSPAUTH_PROXY:
@@ -6017,14 +6034,7 @@ static int check_auth(struct sip_pvt *p, struct sip_request *req, char *randdata
return (0);
}
else {
- if (ast_osp_validate (NULL, osptoken, &p->osphandle, &osptimelimit, p->cid_num, p->sa.sin_addr, p->exten) < 1) {
- return (-1);
- }
- else {
- snprintf (tmp, sizeof (tmp), "%d", p->osphandle);
- pbx_builtin_setvar_helper (p->owner, "_OSPHANDLE", tmp);
- return (0);
- }
+ return (check_osptoken (p, osptoken));
}
break;
case SIP_OSPAUTH_EXCLUSIVE:
@@ -6032,14 +6042,7 @@ static int check_auth(struct sip_pvt *p, struct sip_request *req, char *randdata
return (-1);
}
else {
- if (ast_osp_validate (NULL, osptoken, &p->osphandle, &osptimelimit, p->cid_num, p->sa.sin_addr, p->exten) < 1) {
- return (-1);
- }
- else {
- snprintf (tmp, sizeof (tmp), "%d", p->osphandle);
- pbx_builtin_setvar_helper (p->owner, "_OSPHANDLE", tmp);
- return (0);
- }
+ return (check_osptoken (p, osptoken));
}
break;
default:
@@ -10243,6 +10246,9 @@ static int handle_request_invite(struct sip_pvt *p, struct sip_request *req, int
if (!ignore && p)
p->lastinvite = seqno;
if (c) {
+#ifdef OSP_SUPPORT
+ ast_channel_setwhentohangup (c, p->osptimelimit);
+#endif
switch(c->_state) {
case AST_STATE_DOWN:
transmit_response(p, "100 Trying", req);
diff --git a/include/asterisk/channel.h b/include/asterisk/channel.h
index 67b32b1b8..0d7cb6b05 100755
--- a/include/asterisk/channel.h
+++ b/include/asterisk/channel.h
@@ -562,6 +562,18 @@ int ast_softhangup_nolock(struct ast_channel *chan, int cause);
*/
int ast_check_hangup(struct ast_channel *chan);
+/*! Compare a offset with the settings of when to hang a channel up */
+/*!
+ * \param chan channel on which to check for hang up
+ * \param offset offset in seconds from current time
+ * \return 1, 0, or -1
+ * This function compares a offset from current time with the absolute time
+ * out on a channel (when to hang up). If the absolute time out on a channel
+ * is earlier than current time plus the offset, it returns 1, if the two
+ * time values are equal, it return 0, otherwise, it retturn -1.
+ */
+int ast_channel_cmpwhentohangup(struct ast_channel *chan, time_t offset);
+
/*! Set when to hang a channel up */
/*!
* \param chan channel on which to check for hang up
diff --git a/res/res_osp.c b/res/res_osp.c
index 128befbcc..dca948c72 100755
--- a/res/res_osp.c
+++ b/res/res_osp.c
@@ -521,7 +521,6 @@ int ast_osp_lookup(struct ast_channel *chan, char *provider, char *extension, ch
int tokenlen;
unsigned int dummy=0;
unsigned int timelimit;
- char* sipcallid;
unsigned int callidlen;
char callidstr[OSPC_CALLID_MAXSIZE] = "";
struct osp_provider *osp;
@@ -531,9 +530,9 @@ int ast_osp_lookup(struct ast_channel *chan, char *provider, char *extension, ch
char destination[2048]="";
char token[2000];
char tmp[256]="", *l, *n;
- OSPTCALLID *callid;
OSPE_DEST_PROT prot;
OSPE_DEST_OSP_ENABLED ospenabled;
+ char *devinfo = NULL;
result->handle = -1;
result->numresults = 0;
@@ -558,8 +557,6 @@ int ast_osp_lookup(struct ast_channel *chan, char *provider, char *extension, ch
callerid = l;
if (chan) {
- sipcallid = pbx_builtin_getvar_helper (chan, "SIPCALLID");
- ast_copy_string(callidstr, sipcallid, sizeof(callidstr));
cres = ast_autoservice_start(chan);
if (cres < 0)
return cres;
@@ -581,67 +578,71 @@ int ast_osp_lookup(struct ast_channel *chan, char *provider, char *extension, ch
ast_mutex_unlock(&osplock);
if (res) {
res = 0;
- callid = OSPPCallIdNew(strlen(callidstr), callidstr);
- if (callid) {
- /* No more than 10 back */
- counts = 10;
- dummy = 0;
- callidlen = sizeof(callidstr);
- if (!OSPPTransactionRequestAuthorisation(result->handle, source, "",
- callerid,OSPC_E164, extension, OSPC_E164, NULL, 1, &callid, NULL, &counts, &dummy, NULL)) {
- if (counts) {
- tokenlen = sizeof(token);
- result->numresults = counts - 1;
- if (!OSPPTransactionGetFirstDestination(result->handle, 0, NULL, NULL, &timelimit, &callidlen, callidstr,
- sizeof(callednum), callednum, sizeof(callingnum), callingnum, sizeof(destination), destination, 0, NULL, &tokenlen, token)) {
- ast_log(LOG_DEBUG, "Got destination '%s' and called: '%s' calling: '%s' for '%s' (provider '%s')\n",
- destination, callednum, callingnum, extension, provider);
- ast_channel_setwhentohangup (chan, timelimit); /* Only support OSP server with only one duration limit */
- do {
- if (!OSPPTransactionIsDestOSPEnabled (result->handle, &ospenabled) && (ospenabled == OSPE_OSP_FALSE)) {
- result->token[0] = 0;
- }
- else {
- ast_base64encode(result->token, token, tokenlen, sizeof(result->token) - 1);
+ /* No more than 10 back */
+ counts = 10;
+ dummy = 0;
+ devinfo = pbx_builtin_getvar_helper (chan, "OSPPEER");
+ if (!devinfo) {
+ devinfo = "";
+ }
+ if (!OSPPTransactionRequestAuthorisation(result->handle, source, devinfo,
+ callerid,OSPC_E164, extension, OSPC_E164, NULL, 0, NULL, NULL, &counts, &dummy, NULL)) {
+ if (counts) {
+ tokenlen = sizeof(token);
+ result->numresults = counts - 1;
+ callidlen = sizeof(callidstr);
+ if (!OSPPTransactionGetFirstDestination(result->handle, 0, NULL, NULL, &timelimit, &callidlen, callidstr,
+ sizeof(callednum), callednum, sizeof(callingnum), callingnum, sizeof(destination), destination, 0, NULL, &tokenlen, token)) {
+ ast_log(LOG_DEBUG, "Got destination '%s' and called: '%s' calling: '%s' for '%s' (provider '%s')\n",
+ destination, callednum, callingnum, extension, provider);
+ /* Only support OSP server with only one duration limit */
+ if (ast_channel_cmpwhentohangup (chan, timelimit) < 0) {
+ ast_channel_setwhentohangup (chan, timelimit);
+ }
+ do {
+ if (!OSPPTransactionIsDestOSPEnabled (result->handle, &ospenabled) && (ospenabled == OSPE_OSP_FALSE)) {
+ result->token[0] = 0;
+ }
+ else {
+ ast_base64encode(result->token, token, tokenlen, sizeof(result->token) - 1);
+ }
+ if ((strlen(destination) > 2) && !OSPPTransactionGetDestProtocol(result->handle, &prot)) {
+ res = 1;
+ /* Strip leading and trailing brackets */
+ destination[strlen(destination) - 1] = '\0';
+ switch(prot) {
+ case OSPE_DEST_PROT_H323_SETUP:
+ ast_copy_string(result->tech, "H323", sizeof(result->tech));
+ snprintf(result->dest, sizeof(result->dest), "%s@%s", callednum, destination + 1);
+ break;
+ case OSPE_DEST_PROT_SIP:
+ ast_copy_string(result->tech, "SIP", sizeof(result->tech));
+ snprintf(result->dest, sizeof(result->dest), "%s@%s", callednum, destination + 1);
+ break;
+ case OSPE_DEST_PROT_IAX:
+ ast_copy_string(result->tech, "IAX", sizeof(result->tech));
+ snprintf(result->dest, sizeof(result->dest), "%s@%s", callednum, destination + 1);
+ break;
+ default:
+ ast_log(LOG_DEBUG, "Unknown destination protocol '%d', skipping...\n", prot);
+ res = 0;
}
- if ((strlen(destination) > 2) && !OSPPTransactionGetDestProtocol(result->handle, &prot)) {
- res = 1;
- /* Strip leading and trailing brackets */
- destination[strlen(destination) - 1] = '\0';
- switch(prot) {
- case OSPE_DEST_PROT_H323_SETUP:
- ast_copy_string(result->tech, "H323", sizeof(result->tech));
- snprintf(result->dest, sizeof(result->dest), "%s@%s", callednum, destination + 1);
- break;
- case OSPE_DEST_PROT_SIP:
- ast_copy_string(result->tech, "SIP", sizeof(result->tech));
- snprintf(result->dest, sizeof(result->dest), "%s@%s", callednum, destination + 1);
- break;
- case OSPE_DEST_PROT_IAX:
- ast_copy_string(result->tech, "IAX", sizeof(result->tech));
- snprintf(result->dest, sizeof(result->dest), "%s@%s", callednum, destination + 1);
- break;
- default:
- ast_log(LOG_DEBUG, "Unknown destination protocol '%d', skipping...\n", prot);
- res = 0;
- }
- if (!res && result->numresults) {
- result->numresults--;
- if (OSPPTransactionGetNextDestination(result->handle, OSPC_FAIL_INCOMPATIBLE_DEST, 0, NULL, NULL, &timelimit, &callidlen, callidstr,
- sizeof(callednum), callednum, sizeof(callingnum), callingnum, sizeof(destination), destination, 0, NULL, &tokenlen, token)) {
- break;
- }
+ if (!res && result->numresults) {
+ result->numresults--;
+ callidlen = sizeof(callidstr);
+ if (OSPPTransactionGetNextDestination(result->handle, OSPC_FAIL_INCOMPATIBLE_DEST, 0, NULL, NULL, &timelimit, &callidlen, callidstr,
+ sizeof(callednum), callednum, sizeof(callingnum), callingnum, sizeof(destination), destination, 0, NULL, &tokenlen, token)) {
+ break;
}
- } else {
- ast_log(LOG_DEBUG, "Missing destination protocol\n");
- break;
}
- } while(!res && result->numresults);
- }
+ } else {
+ ast_log(LOG_DEBUG, "Missing destination protocol\n");
+ break;
+ }
+ } while(!res && result->numresults);
}
-
}
- OSPPCallIdDelete(&callid);
+
}
if (!res) {
OSPPTransactionDelete(result->handle);
@@ -680,11 +681,11 @@ int ast_osp_next(struct ast_osp_result *result, int cause)
if (result->handle > -1) {
dummy = 0;
- callidlen = sizeof(callidstr);
if (result->numresults) {
tokenlen = sizeof(token);
while(!res && result->numresults) {
result->numresults--;
+ callidlen = sizeof(callidstr);
if (!OSPPTransactionGetNextDestination(result->handle, OSPC_FAIL_INCOMPATIBLE_DEST, 0, NULL, NULL, &timelimit, &callidlen, callidstr,
sizeof(callednum), callednum, sizeof(callingnum), callingnum, sizeof(destination), destination, 0, NULL, &tokenlen, token)) {
if (!OSPPTransactionIsDestOSPEnabled (result->handle, &ospenabled) && (ospenabled == OSPE_OSP_FALSE)) {