I am currently preparing a kamailio-asterisk
combination. The
asterisk installation uses realtime for SIP. The kamailio
configuration (attached) was based on the reference at
http://kb.asipto.com/asterisk:realtime:kamailio-4.0.x-asterisk-11.3.0-astdb
but has been heavily modified. Currently asterisk runs on localhost
and only listens on SIP/RTP at 127.0.0.1 . Therefore, all of the SIP
traffic appears to come from localhost, from the point of view of
asterisk.
Currently I have a model on which internal SIP phones get identified
by the authentication username, and then the contact names at From:
and To: get massaged to incorporate the SIP domain, in order to
emulate multiple-domain support. The 'sip' table in Asterisk defines
all such contacts as SIP accounts of the form
name_domain.com, and
the SIP phones are configured to use 'name' as authentication
username for domain 'domain.com'. However, SIP providers that
register on the server with authentication names are left with their
original names, since in the model, SIP trunks are available to all
domains.
Now I have to add support for SIP providers which are to be
authorized on the basis of IP only. Apparently, the permissions.so
(WITH_IPAUTH) is made for just this purpose, so I enabled it. After
authentication, I need to route the INVITE to asterisk, and asterisk
must somehow match the account for the SIP trunk from the available
information on the INVITE request.
A typical INVITE for this scenario looks like this, before being
processed by kamailio:
INVITE sip:6008010@172.28.161.218:5060;transport=udp;user=phone SIP/2.0
Via: SIP/2.0/UDP
200.25.144.58:5060;branch=z9hG4bK+676ea13f680e853fd847230512a347561+32e3da76+1
Call-ID: FBE75B3A@32e3da76
From:
<sip:042294440@200.25.144.58:5060;user=phone>;tag=32e3da76+1+544c000c+52be771c
To: <sip:6008010@172.28.161.218:5060;user=phone>
CSeq: 975469826 INVITE
Expires: 180
Organization: SetelGYE
Min-SE: 90
Session-Expires: 18000
Supported: replaces, 100rel, timer
Contact: <sip:042294440@200.25.144.58:5060;transport=udp;user=phone>
Content-Length: 149
Content-Type: application/sdp
Max-Forwards: 70
Allow: INVITE, ACK, CANCEL, BYE, OPTIONS, NOTIFY, PRACK, UPDATE,
INFO, REFER
v=0
o=- 0 0 IN IP4 201.217.79.3
s=-
c=IN IP4 201.217.79.3
t=0 0
m=audio 5388 RTP/AVP 8 101
a=rtpmap:101 telephone-event/8000
a=fmtp:101 0-15
Here, 6008010 is the phone number that was dialed at the provider in
order to reach my system, and 042294440 is the provider-supplied
Caller-ID, which I want to preserve all the way to Asterisk. In
particular, 042294440 appears as the value that ends up as $fU
(From: username) while being processed in kamailio. If I pass the
SIP packet as-is to asterisk, asterisk first tries to match by the
value of $fU, which obviously fails to match the trunk name. It then
tries to match by incoming IP, which also fails because asterisk
received this packet from 127.0.0.1 . Finally, asterisk sort of
matches to the first record in the sip table, which is *not* the SIP
account for this trunk, but some other random account.
I have a partial solution that uses sqlops to make a query to the
sip table, using the $si (source IP) and reads the trunk name in
order to replace $fU. This works, as now $fU will have the trunk
name and asterisk will now recognize the intended SIP account for
the trunk. However, this has the unfortunate side effect of throwing
out the Caller-ID information.
What is the standard/proper way to deal with this situation? Is
there a well-known way to make Asterisk match the trunk name,
without overwriting the Caller-ID information? Before you ask,
requesting the provider to modify its INVITEs is not an option. I
believe there is a standard way to deal with this, since this
scenario should also arise with a kamailio that faces the internet,
and relays INVITEs (after authentication) to an asterisk in a local
network. As far as I can tell, the fact that in my case the 'local
network' is localhost should be irrelevant.
I tried appending a P-Asserted
Identity header to the incoming INVITE
before routing it to asterisk, like this:
#!ifdef WITH_IPAUTH
if((!is_method("REGISTER")) && allow_source_address() &&
$au == "")
{
# Attempt to create a P-Asserted-Identity if none exists, to
preserve
# incoming Caller-ID
if (!is_present_hf("P-Asserted-Identity"))
{
append_hf("P-Asserted-Identity: <sip:$fU@$fd>\r\n");
}
# Loading $fU from database using IP
sql_pvquery("elxpbx", "SELECT name FROM sip WHERE host =
'$si' AND sippasswd IS NULL", "$fU");
# source IP allowed
return;
}
#!endif
With tcpdump, I can see that the header is indeed appended to the SIP
headers of the INVITE, but there is no effect in Asterisk. From
examination of the Asterisk 11.8.1 source code, I see that
channels/chan_sip.c contains a get_pai() function that is supposed to
process P-Asserted-Identity and extract a caller ID. I am still
studying the code, but I would appreciate help on this issue, to see
why my attempt is not working.