*** empty log message ***
This commit is contained in:
@@ -1,11 +1,5 @@
|
||||
0.6.0
|
||||
=====
|
||||
27-May-2007: - new feature: "Obscure Loops" does modify the Call-IDs in
|
||||
outgoing requests and thus allows incoming calls forked
|
||||
off such an outgoing call (redirect, transfer, ...) back
|
||||
to the same UA where the initial call did originate.
|
||||
This even seems to fix some issues with Asterisks
|
||||
Loop detection... :-)
|
||||
25-May-2007: - Just discovered some patches originating from Debian
|
||||
project - included most of them as they make sense.
|
||||
(Hint: People, if you get fixes, please drop me a note
|
||||
|
||||
@@ -7,7 +7,6 @@ Major changes since 0.5.13:
|
||||
after the RTP timeout period.
|
||||
- Can now masquerade the User-agent header, too
|
||||
- Support for adding ;rport to Via headers (RFC3581)
|
||||
- "Obscure" SIP Loops (Calls redirected back to me work better)
|
||||
|
||||
General Overview:
|
||||
- SIP (RFC3261) Proxy for SIP based softphones hidden behind a
|
||||
|
||||
@@ -257,31 +257,6 @@ debug_port = 0
|
||||
#
|
||||
# use_rport = 0
|
||||
|
||||
######################################################################
|
||||
# Obscure SIP Loops
|
||||
#
|
||||
# By default, Siproxd can not handle the situation where a call
|
||||
# from an UA is made back to the *same* UA.
|
||||
#
|
||||
# E.g.
|
||||
#
|
||||
# UA ----- siproxd ----- Registrar
|
||||
#
|
||||
# and UA is registered with two accounts (A & B) at "Registrar".
|
||||
# If UA (account A) now initiates a Call to its second account (B)
|
||||
# this will result in a "loop" (if you use Asterisk as UA above, it
|
||||
# will react with an "482 Loop detected" error and does not accept the
|
||||
# call). Siproxd can not handle the RTP audio stream properly in such
|
||||
# a situation - you will most likely only hear silence.
|
||||
#
|
||||
# This expirmental feature does "obscure" this loop - well, actually
|
||||
# it does modify the OUTGOING Call-Id - and when the INVITE comes back,
|
||||
# it actually looks like a second (independend) call. This even makes
|
||||
# Asterisk work in the situation mentioned above.
|
||||
#
|
||||
# Default is disabled.
|
||||
# obscure_loops=1
|
||||
|
||||
######################################################################
|
||||
# Outbound proxy
|
||||
#
|
||||
|
||||
+5
-50
@@ -205,6 +205,7 @@ int proxy_request (sip_ticket_t *ticket) {
|
||||
sts = proxy_rewrite_invitation_body(ticket, DIR_INCOMING);
|
||||
|
||||
}
|
||||
sts=sip_obscure_callid(ticket);
|
||||
break;
|
||||
|
||||
/*
|
||||
@@ -262,29 +263,7 @@ int proxy_request (sip_ticket_t *ticket) {
|
||||
rtp_stop_fwd(osip_message_get_call_id(request), DIR_OUTGOING);
|
||||
}
|
||||
|
||||
/*
|
||||
* "Obscure" SIP Loops - modify Call-IDs on outgoing REQs, so calls
|
||||
* forked / redirected from a Call originating here may be
|
||||
* passed back without breaking things
|
||||
*/
|
||||
if (configuration.obscure_loops) {
|
||||
osip_call_id_t *CID=NULL;
|
||||
char *tmp;
|
||||
|
||||
CID=osip_message_get_call_id(request);
|
||||
if (CID) {
|
||||
/* does CID->number already exist? */
|
||||
if (CID->number) { /* accoridng to RFC3261, this part is mandatory */
|
||||
/* modify it */
|
||||
tmp=osip_malloc(strlen(CID->number)+7+1);
|
||||
sprintf(tmp,"%s-siproxd",CID->number);
|
||||
osip_free(CID->number);
|
||||
CID->number=tmp;
|
||||
} else {
|
||||
WARN("CID without number part received, not RFC3261 conform!");
|
||||
}
|
||||
}
|
||||
}
|
||||
sts=sip_obscure_callid(ticket);
|
||||
|
||||
break;
|
||||
|
||||
@@ -584,34 +563,8 @@ int proxy_response (sip_ticket_t *ticket) {
|
||||
response->from->url->username? response->from->url->username:"*NULL*",
|
||||
response->from->url->host? response->from->url->host : "*NULL*");
|
||||
|
||||
/*
|
||||
* "Obscure" SIP Loops - modify Call-IDs on incoming RESs, so calls
|
||||
* forked / redirected from a Call originating here may be
|
||||
* passed back without breaking things
|
||||
*/
|
||||
if (configuration.obscure_loops) {
|
||||
osip_call_id_t *CID=NULL;
|
||||
char *tmp, *tmp2;
|
||||
sts=sip_obscure_callid(ticket);
|
||||
|
||||
CID=osip_message_get_call_id(response);
|
||||
if (CID) {
|
||||
/* does CID->number already exist? */
|
||||
if (CID->number) { /* accoridng to RFC3261, this part is mandatory */
|
||||
/* modify it back*/
|
||||
tmp=strstr(CID->number,"-siproxd");
|
||||
if (tmp) {
|
||||
/* make sure to cut only the last marker - in case
|
||||
of multiple siproxd instances... */
|
||||
for (;(tmp2=strstr(tmp+1, "-siproxd")) != NULL;) {
|
||||
tmp=tmp2;
|
||||
}
|
||||
tmp[0]='\0';
|
||||
}
|
||||
} else {
|
||||
WARN("CID without number part received, not RFC3261 conform!");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Response for INVITE - deal with RTP data in body and
|
||||
@@ -691,6 +644,8 @@ int proxy_response (sip_ticket_t *ticket) {
|
||||
response->from->url->host ?
|
||||
response->from->url->host : "*NULL*");
|
||||
|
||||
sts=sip_obscure_callid(ticket);
|
||||
|
||||
/* Rewrite Contact header to represent the masqued address */
|
||||
sip_rewrite_contact(ticket, DIR_OUTGOING);
|
||||
|
||||
|
||||
+154
@@ -1177,3 +1177,157 @@ int sip_fixup_asterisk(char *buff, int *buflen) {
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* SIP_OBSCURE_CALLID
|
||||
*
|
||||
27-May-2007: - new feature: "Obscure Loops" does modify the Call-IDs in
|
||||
outgoing requests and thus allows incoming calls forked
|
||||
off such an outgoing call (redirect, transfer, ...) back
|
||||
to the same UA where the initial call did originate.
|
||||
This even seems to fix some issues with Asterisks
|
||||
Loop detection... :-)
|
||||
Needs more thinking. The logic about call termination is quite tricky -
|
||||
calls can be terminated from either side... It is not stratigh forward
|
||||
when and how to modify CIDs for call cancellation...
|
||||
* ...
|
||||
*
|
||||
* RETURNS
|
||||
* STS_SUCCESS on success
|
||||
*/
|
||||
int sip_obscure_callid(sip_ticket_t *ticket) {
|
||||
static char myident[]="-siproxd";
|
||||
int myidentlen=sizeof(myident)-1; /* a static strlen() of myident */
|
||||
|
||||
osip_message_t *sipmsg;
|
||||
osip_from_t *from;
|
||||
osip_to_t *to;
|
||||
osip_uri_param_t *fromtag, *totag; /* gname, gvalue */
|
||||
|
||||
osip_call_id_t *CID=NULL;
|
||||
|
||||
char *tmp, *tmp2;
|
||||
|
||||
|
||||
/* feature enabled? */
|
||||
if (!configuration.obscure_loops) return STS_SUCCESS;
|
||||
|
||||
sipmsg=ticket->sipmsg;
|
||||
|
||||
|
||||
if (MSG_IS_REQUEST(sipmsg) &&
|
||||
MSG_IS_REGISTER(sipmsg)) return STS_SUCCESS;
|
||||
if (MSG_IS_RESPONSE(sipmsg) &&
|
||||
MSG_IS_RESPONSE_FOR(sipmsg,"REGISTER")) return STS_SUCCESS;
|
||||
|
||||
from=sipmsg->from;
|
||||
osip_from_get_tag(from, &fromtag);
|
||||
|
||||
to=sipmsg->to;
|
||||
osip_to_get_tag(to, &totag);
|
||||
|
||||
/* at lest the From Tag must be present, otherwise out Logic does
|
||||
not work. Is MANDATORY according to RFC3261 */
|
||||
if (!fromtag || !fromtag->gvalue || strlen(fromtag->gvalue)==0) {
|
||||
WARN("sip_obscure_callid: no From-Tag, not RFC3261 conform!");
|
||||
return STS_FAILURE;
|
||||
}
|
||||
|
||||
CID=osip_message_get_call_id(sipmsg);
|
||||
|
||||
/* does CID->number exist? According to RFC3261, this part is mandatory */
|
||||
if (!CID || !CID->number) {
|
||||
WARN("sip_obscure_callid: invalid Call-ID received, not RFC3261 conform!");
|
||||
return STS_FAILURE;
|
||||
}
|
||||
|
||||
DEBUGC(DBCLASS_PROXY, "sip_obscure_callid: current Callid#=%s Direction=%i",
|
||||
CID->number, ticket->direction);
|
||||
|
||||
switch (ticket->direction) {
|
||||
|
||||
/* Outgoing Request */
|
||||
case REQTYP_OUTGOING:
|
||||
/* also need testing for "normal" incoming call that is present and
|
||||
now we SEND a cancel for this call */
|
||||
tmp=strstr(CID->number, myident);
|
||||
if (tmp==NULL) {
|
||||
/* no obscuring present yet, must be a new call, modify it */
|
||||
tmp=osip_malloc(strlen(CID->number) + myidentlen +
|
||||
strlen(fromtag->gvalue) + 1);
|
||||
sprintf(tmp,"%s%s%s",CID->number,myident,fromtag->gvalue);
|
||||
osip_free(CID->number);
|
||||
CID->number=tmp;
|
||||
} else {
|
||||
/* Obscuring is present, do nothing. */
|
||||
}
|
||||
break;
|
||||
|
||||
/* Incoming Response */
|
||||
case RESTYP_INCOMING:
|
||||
tmp=strstr(CID->number,myident);
|
||||
/* modify it back if existing */
|
||||
if (tmp) {
|
||||
/* make sure to cut only the last marker - in case
|
||||
of multiple siproxd instances...
|
||||
I dont know if this actually would work (multiple instances...)*/
|
||||
for (;(tmp2=strstr(tmp+1, myident)) != NULL;) {
|
||||
tmp=tmp2;
|
||||
}
|
||||
tmp[0]='\0';
|
||||
}
|
||||
break;
|
||||
|
||||
/* Incoming Request */
|
||||
case REQTYP_INCOMING:
|
||||
tmp=strstr(CID->number, myident);
|
||||
if (tmp==NULL) {
|
||||
/* no obscuring present yet, must be a new incoming call, do nothing */
|
||||
} else {
|
||||
/* if BYE or CANCEL, check if obscuring present.
|
||||
* if From-Tag different than in CID stored, modify back CID */
|
||||
DEBUGC(DBCLASS_PROXY, "tmp+myidentlen=[%s], FromTag=[%s]",
|
||||
tmp+myidentlen, fromtag->gvalue);
|
||||
|
||||
if (strcmp(tmp+myidentlen, fromtag->gvalue) != 0) {
|
||||
tmp[0]='\0';
|
||||
} else {
|
||||
/* if From-Tag equal to in CID stored, do nothing */
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
/* Outgoing Response */
|
||||
case RESTYP_OUTGOING:
|
||||
if (MSG_IS_RESPONSE_FOR(sipmsg,"BYE")) {
|
||||
tmp=strstr(CID->number, myident);
|
||||
if ((tmp==NULL)&& totag && totag->gvalue) {
|
||||
/* no obscuring present yet, must be a new call, modify it */
|
||||
tmp=osip_malloc(strlen(CID->number) + myidentlen +
|
||||
strlen(fromtag->gvalue) + 1);
|
||||
sprintf(tmp,"%s%s%s",CID->number,myident,totag->gvalue);
|
||||
osip_free(CID->number);
|
||||
CID->number=tmp;
|
||||
} else {
|
||||
/* Obscuring is present, do nothing. */
|
||||
}
|
||||
}
|
||||
// tmp=strstr(CID->number, myident);
|
||||
// /* modify it back if existing*/
|
||||
// if (tmp) {
|
||||
// /* make sure to cut only the last marker - in case
|
||||
// of multiple siproxd instances... */
|
||||
// for (;(tmp2=strstr(tmp+1, myident)) != NULL;) {
|
||||
// tmp=tmp2;
|
||||
// }
|
||||
// tmp[0]='\0';
|
||||
// }
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
DEBUGC(DBCLASS_PROXY, "sip_obscure_callid: new Callid#=%s",CID->number);
|
||||
|
||||
return STS_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -181,6 +181,7 @@ int sip_find_outbound_proxy(sip_ticket_t *ticket, struct in_addr *addr,
|
||||
int *port); /*X*/
|
||||
int sip_find_direction(sip_ticket_t *ticket, int *urlidx); /*X*/
|
||||
int sip_fixup_asterisk(char *buff, int *buflen); /*X*/
|
||||
int sip_obscure_callid(sip_ticket_t *ticket); /*X*/
|
||||
|
||||
/* readconf.c */
|
||||
int read_config(char *name, int search); /*X*/
|
||||
|
||||
Reference in New Issue
Block a user