Da einige SIP-Provider bei kommenden Anrufen die Zielrufnummer in der To-Header-URI statt in der Request-URI des INVITE-Requests im SIP-Protokoll übermitteln habe ich hier eine technische Betrachtung dieser Vorgehensweise zusammengestellt.
Ein eingehendes INVITE sieht normalerweise etwa so aus (vereinfacht):
INVITE sip:bob@pbx;transport=udp SIP/2.0 To: "Bob" <sip:bob@pbx> ...
Sowohl die Request-URI (R-URI) als auch die URI im
To-Header sind hier
sip:bob@pbx
.
Request-URI: The Request-URI is a SIP or SIPS URI as described in Section 19.1 or a general URI (RFC 2396 [5]). It indicates the user or service to which this request is being addressed.
RFC 3261 §8.1.1.1 - Request-URI
:
The initial Request-URI of the message SHOULD be set to the value of the URI in the To field.
The To header field first and foremost specifies the desired "logical" recipient of the request, or the address-of-record of the user or resource that is the target of this request.
The To header field specifies the logical recipient of the request.
RFC 3261 §8.2.2.1 - To and Request-URI
:
The To header field identifies the original recipient of the request designated by the user identified in the From field. The original recipient may or may not be the UAS processing the request, due to call forwarding or other proxy operations.
However, the Request-URI identifies the UAS that is to process the request
In some cases, users may want to conceal personal information in header fields that convey identity. This can apply not only to the From and related headers representing the originator of the request, but also the To - it may not be appropriate to convey to the final destination a speed-dialing nickname, or an unexpanded identifier for a group of targets, either of which would be removed from the Request-URI as the request is routed, but not changed in the To header field if the two were initially identical. Thus it MAY be desirable for privacy reasons to create a To header field that differs from the Request-URI.
Im To-Header eines eingehenden INVITE-Requests steht normalerweise die vom Anrufer gewählte Nummer. Das kann auch eine Kurzwahl o.ä. sein die von der Telefonanlage des Anrufers zu einer Request-URI aufgelöst wird.
Die To-Header-URI ist also sowas ähnliches wie DNIS/DNID, also die gewählte Nummer; nicht zwangsläufig die Zielrufnummer auf der Seite des Angerufenen.
Im To-Header kann sogar eine andere Telefonanlage (Domain)
stehen als in der Request-URI. Beispiel:
A ruft B an. B steht in der Request-URI und sehr wahrscheinlich auch
im To-Header. B leitet an C (auf unserer Telefonanlage) weiter.
Jetzt steht C (wir) in der Request-URI. Im To-Header kann
aber immer noch B stehen.
D.h. die To-URI hat auf der Telefonanlage des Angerufenen keine Relevanz bei der Entscheidung an welchen eigenen Benutzer der Anruf gerichtet ist.
Soviel zur Theorie.
SIP-Provider senden in der Request-URI normalerweise
nicht die tatsächlich angerufene Nummer sondern den
Account-Namen (manchmal SIP-ID
genannt, meist
alphanumerisch oder die Kopfnummer unseres Rufnummernblocks)
unseres Trunks.
Beispiel:
INVITE sip:accountname@host;transport=udp SIP/2.0 To: <sip:012377777555@pbx> ...
oder
INVITE sip:0123777770@host;transport=udp SIP/2.0 To: <sip:012377777555@pbx> ...
Dies ist laut SIP-RFC korrekt. Daß in der Request-URI nicht die tatsächlich angerufene Nummer steht sondern der Account-Name beim Provider ist nach dem SIP-Standard so vorgesehen.
Die Problematik entsteht schon bei der SIP-Registrierung
(REGISTER,
RFC 3261 §10.2 - Constructing the REGISTER Request
).
Durch die SIP-Registrierung wird dem SIP-Registrar mitgeteilt
unter welcher IP-Adresse ein Benutzer-Account aktuell für
kommende Anrufe erreichbar ist.
REGISTER ist aber immer nur auf einzelne Benutzer
ausgelegt, nicht auf Rufnummernblöcke (Trunks). Von einer
Telefonanlage mit einem Rufnummernblock mit 4-stelligen
Durchwahlen (xxxx) für jede dieser
Durchwahlen (10.000!) eine Registrierung zu senden ist keine
gute Lösung.
Dieses Problem hat also weder etwas mit Asterisk zu tun noch mit Gemeinschaft. Das ist eher ein allgemeines SIP-Problem, denn SIP-Provider oder Trunks sind in keinem der SIP-RFCs vorgesehen.
Asterisk (und damit erstmal auch Gemeinschaft) nimmt die angerufene
Nummer (in den o.g. Beispielen accountname
bzw.
0123777770
) RFC-konform aus der Request-URI
(INVITE sip:accountname@...
bzw.
INVITE sip:0123777770@...
).
Blöderweise sagt das in solchen Fällen dann nichts über
die angerufene Durchwahl aus.
Kurze Antwort: Gar nicht. SIP-Trunks sind im SIP-Standard nicht vorgesehen.
Man könnte zwar die angerufene Nummer aus dem To-Header
nehmen, das wäre aber nicht RFC-konform und funktioniert auch
nicht immer, z.B. nicht wenn vorher schon Weiterleitungen
stattgefunden haben. Evtl. mag zwar ein Provider dafür sorgen
daß bei ihm der To-Header immer stimmt
, also die
bei uns anzurufende Nummer enthält, aber das kann Asterisk
/ Gemeinschaft ja nicht wissen, ist also keine allgemeingültige
Lösung.
Gemeinschaft
Wenn man trotzdem (nicht RFC-konform) anhand der To-Headers-URI eingehend routen will, so ist dies in Gemeinschaft / Asterisk durch einen manuellen Workaround möglich.
Vorab sei aber gesagt daß durch den Begriff
Workaround
kein Fehler in Gemeinschaft impliziert
wird und daß weder die
Amooma GmbH
noch ich Unzulänglichkeiten im SIP-Protokoll supporten
können. Die folgenden Änderungen sind nur etwas
für erfahrene Benutzer und erfolgen auf eigene Gefahr.
In der Datei /opt/gemeinschaft/etc/asterisk/e-gategroups-in.ael.php gibt es folgenden auskommentierten Code:
/*
# hack for Sipgate.de {
if (preg_match('/\bsipgate\b/i', $name)) {
echo "\t\t\t", "\n";
echo "\t\t\t", 'Set(did_full=${SIP_HEADER(To)});' ,"\n";
echo "\t\t\t", 'Set(did_full=${CUT(did_full,@,1)});' ,"\n";
echo "\t\t\t", 'Set(did_full=${did_full:5});' ,"\n";
echo "\t\t\t", 'Verbose(1,### Inbound call from Sipgate to ${did_full});' ,"\n";
echo "\t\t\t", "\n";
}
# hack for Sipgate.de }
*/
Diesen Code könnte man reinnehmen (also die Kommentarzeichen /* */ entfernen) um anhand des To-Headers zu routen. Etwa so:
# hack for routing based on To header URI { echo 'if ("${CHANNEL(channeltype)}" = "SIP") {' ,"\n"; echo ' Set(did_full=${SIP_HEADER(To)});' ,"\n"; // "Bob" <sip:012377777555@host> echo ' Set(did_full=${CUT(did_full,@,1)});' ,"\n"; // "Bob" <sip:012377777555 echo ' if ("${CUT(did_full,<,2)}" != "") {' ,"\n"; echo ' Set(did_full=${CUT(did_full,<,2)});' ,"\n"; echo ' }' ,"\n"; // sip:012377777555 echo ' if ("${CUT(did_full,:,2)}" != "") {' ,"\n"; echo ' Set(did_full=${CUT(did_full,:,2)});' ,"\n"; echo ' }' ,"\n"; // 012377777555 echo ' Verbose(1,### DNID by To header: ${did_full});' ,"\n"; echo '}' ,"\n"; # hack for routing based on To header URI }
Dann Asterisk neu starten:
/etc/init.d/asterisk restart
Es versteht sich von selbst daß man sich danach mit dem Asterisk-CLI verbindet (asterisk -r) und mit Verbosity 1 (core set verbose 1) und ggf. auch 3 (core set verbose 3) genau beobachtet ob der Code korrekt funktioniert bzw. diesen ggf. anpaßt.
Von der kompletten angerufenen Nummer (z.B. 012377777555)
läßt sich dann ganz normal in der Web-Oberfläche von
Gemeinschaft (als Benutzer mit Admin-Rechten) unter Routen →
Gateway-Gruppen bei Eingehende Durchwahl
mit einem
Suchen-/Ersetzen-Muster eine eventuelle
Ortsvorwahl
und Kopfnummer
(z.B. 012377777) abschneiden, sodaß nur die reine
Durchwahl
(z.B. 555, bei einem
Anlagenanschluss
oder hier SIP-Trunk) bzw.
MSN
(z.B. 555555, bei einem
Mehrgeräte-Basisanschluß
oder
Analog-Anschluß)
übrigbleibt. Dies funktioniert also genauso wie beim eingehenden
Routing anhand der Request-URI. Auch das eingehende Routing von
Durchwahlen zu Nebenstellen unter Routen → Routen eingehend
funktioniert ganz genauso.
Manchmal sieht man Remote-Party-ID mit ;party=called, aber Remote-Party-ID (RPID) ist nur ein alter Draft der es nicht in ein RFC geschafft hat, und ;party=called war da nie angesprochen.
Daneben gibt es auch P-Called-Party-ID (RFC 3455 §4.2, §5.2). Dieser Header würde sich gut eignen, allerdings kommt er bei kaum einem Provider zum Einsatz.
Manche SIP-Provider senden einen proprietären X-irgendwas-Header (z.B. X-Original-DDI-URI). Das ist natürlich erst recht keine allgemeingültige Lösung.
Wieder andere Provider senden gar keinen zusätzlichen SIP-Header sondern sagen ihren Kunden sie sollen die angerufene Nummer aus dem To-Header nehmen. Dies ist wahrscheinlich die schlechteste aller Varianten, denn der To-Header ist bereits anders definiert.
Klaus Darilion in asterisk-dev:
A Workaround is to put the originally called number in the To header - but this is ugly as To based routing it is against all RFCs.
in asterisk-dev:
Using To: you assume that the To header contains the originally called number. But that depends on the setup of the trunking provider.
in asterisk-dev:
Found it: http://www.ietf.org/rfc/rfc3455.txt P-Called-Party-ID (there is is good documentation why other workarounds are not good). This remembers me on another approach - differentiate between routing and retargeting. Please read http://tools.ietf.org/html/draft-rosenberg-sip-ua-loose-route-02 which also addresses these problems. As this is logically not retargeting but routing, the trunking provider could send the called number in the RURI, and the registered contact is sent as Route header. Thus, Asterisk could match the registered contact against the topmost Route header and the RURI contains the dialed number. Probably, as there are multiple solutions, we should ask on the SIP implementors list.
Thread signaling DID on a SIP trunk
auf der
sip-implementors-Mailingliste:
https://lists.cs.columbia.edu/pipermail/sip-implementors/2009-January/thread.html#21508
Olle E. Johansson in https://lists.cs.columbia.edu/pipermail/sip-implementors/2009-January/021536.html:
Right now there's too many ways for service providers to solve this problem, including home-brewed headers. That doesn't help anyone.
Theo Zourzouvillys in http://wiki.voip.co.uk/sip/matching_using_to_header:
the To and From header fields are end to end header fields populated by the originating UA, and not modified by the network. A UA is free to place whatever it likes in this field, as it is not used in any routing or targeting decisions.
So, the request that proxy.voip.co.uk will forward now looks like this:
INVITE sip:056854@87.127.89.138:5060 SIP/2.0 From: Alice <sip:alice@voip.co.uk> To: Bob <sip:bob@voip.co.uk>Note that the From and To headers have NOT been modified by the proxy, as RFC 3261 (the SIP standard) makes clear on page 162/163 in
Table 2: Summary of header fields:Header field where proxy ACK BYE CAN INV OPT REG ___________________________________________________________ From c r m m m m m m To c(1) r m m m m m m The "proxy" column describes the operations a proxy may perform on a header field: r: A proxy must be able to read the header field, and thus this header field cannot be encrypted.So, as you can see, a SIP proxy is NOT allowed to modify the To or From headers, only read them.
In short, you can not use the To header for matching, and doign so is totally incorrect.
There is currently work going on in the IETF to provide a mechanism to work out what (logical) address a request was initially targeted to, as there is no
correctway to pass this information yet (although we try and send with P-Called-Party-ID where possible). Current ideas include a new 'Target' header or using loose routing and not modifying the R-URI at all.
Fazit: Es gibt für dieses Problem leider noch keinen verbindlichen Standard in SIP der sich durchgesetzt hat.
IETF-Draft
Delivery of Request-URI Targets to User Agents
(draft-rosenberg-sipcore-target-uri-delivery)
(zuvor auch bekannt als
draft-rosenberg-sip-target-uri-delivery,
draft-holmberg-sip-target-uri-delivery
IETF-Draft Applying Loose Routing to Session Initiation Protocol
(SIP) User Agents (UA)
(draft-rosenberg-sip-ua-loose-route)
History-Info-Header (RFC 4244)
SIP Forum:
SIPconnect,
SIPconnect Technical Recommendation v. 1.0 (PDF)
Rechtliches | (c) Philipp Kempgen