Diplomarbeit

Werbung
Fachhochschule Köln
University of Applied Sciences Cologne
07 Fakultät für Informations-, Medien- und
Elektrotechnik, Studiengang Elektrotechnik/NT
Institut für Nachrichtentechnik
Labor für Datennetze
Diplomarbeit
Diplomand
Stefan Abu Salah
Matrikelnummer
11027379
Referent
Prof. Dr. Andreas Grebe
Korreferent
Dipl. Math. Guido Spahn
Diplomarbeit
Stefan Abu Salah
Thema
Entwicklung eines VoIP-Accounting-Moduls für den
SIP Express Router auf Basis des GeoVIPA–
Konzeptes mit einer Schnittstelle zum Mediation
Device T·XMD
Hiermit versichere ich, dass ich die Diplomarbeit selbständig angefertigt und keine
anderen als die angegebenen und bei Zitaten kenntlich gemachten Quellen und
Hilfsmittel benutzt habe.
Stefan Abu Salah
| 2
Diplomarbeit
Stefan Abu Salah
Ich möchte mich ganz besonders bei Prof. Dr. Andreas Grebe, Dipl. Math. Guido
Spahn und der Firma TECON für die engagierte Unterstützung bedanken.
Desweiteren möchte ich meiner Mutter Mechthild Abu Salah und Achim Marikar
vielmals für das Fehlerlesen, sowie Holger Moskopp, Thorsten Lokau und meiner
Freundin Michaela Böke danken.
| 3
Diplomarbeit
Stefan Abu Salah
Inhaltsverzeichnis
1 Vorwort__________________________________________________________________7
2 Ziel dieser Diplomarbeit_____________________________________________________9
3 Grundlagen zu VoIP_______________________________________________________10
3.1 Codecs_____________________________________________________________10
3.2 Das Real Time Protocol________________________________________________11
3.2.1 Der RTP-Proxy____________________________________________________13
3.3 Das Real Time Control Protocol__________________________________________14
3.4 Übersicht über SIP____________________________________________________15
3.4.1 SIP-Komponenten_________________________________________________16
3.4.2 Der SIP – Server__________________________________________________16
3.4.3 Der SIP–Proxy____________________________________________________17
3.4.4 Grundlagen des Protokolls_________________________________________17
3.4.5 SIP-Nachrichten___________________________________________________18
3.4.6 Aufbau der SIP-Messages___________________________________________21
3.4.7 Das Session Description Protocol SDP_________________________________23
4 SER - Sip Express Router____________________________________________________24
4.1 Die Konfigurationsdatei ser.cfg__________________________________________25
5 RADIUS_________________________________________________________________27
5.1 AAA - Authentifikation, Authorisation, Accounting__________________________27
5.1.1 Authentifikation__________________________________________________28
5.1.2 Authorisation____________________________________________________28
5.1.3 Accounting______________________________________________________28
5.2 FreeRADIUS_________________________________________________________29
5.3 Der SER und FreeRADIUS_______________________________________________29
6 MySQL__________________________________________________________________30
6.1 MySQL – Grundlagen _________________________________________________31
6.2 phpMyAdmin_________________________________________________________32
7 Das TECON extended Mediation Device_______________________________________34
7.1 Architektur des T·XMD_________________________________________________35
| 4
Diplomarbeit
Stefan Abu Salah
7.1.1 Collectoren______________________________________________________35
7.1.2 Processing Unit ___________________________________________________36
7.1.3 Distributoren und Converter ________________________________________37
7.1.4 Job Manager_____________________________________________________38
7.1.5 Frontend ________________________________________________________38
7.2 Rating______________________________________________________________39
7.3 TECON Billing Solution_________________________________________________39
8 Das GeoVIPA-Konzept_____________________________________________________40
8.1 Umsetzung des GeoVIPA Konzeptes______________________________________42
9 Notwendige Erweiterungen im SER __________________________________________44
9.1 Analyse der SIP-Messages_______________________________________________44
9.1.1 Vorgehen beim Eintreffen einer INVITE-Message________________________47
9.1.2 Vorgehen beim Eintreffen einer OK-Message___________________________48
9.1.3 Vorgehen beim Eintreffen einer BYE-Message__________________________48
9.1.4 Vorgehen beim Eintreffen sonstiger SIP-Messages_______________________48
9.2 Lokalisierung_________________________________________________________48
9.3 Erzeugen der Call Detail Records_________________________________________52
9.3.1 CDR im CSV-Format_______________________________________________52
9.3.2 CDR in MySQL____________________________________________________53
9.4 Performance und Stabilität______________________________________________56
9.5 Vorkommen doppelter Call-IDs__________________________________________57
10 Änderungen im Quellcode des RTP-Proxy_____________________________________58
10.1 Generelle Vorgehensweise_____________________________________________58
10.2 Erläuterung der Umsetzung____________________________________________60
10.3 SDP und der watchdog________________________________________________61
10.4 Performance und Stabilität_____________________________________________62
11 Erläuterungen der Änderungen im Quellcode von FreeRADIUS___________________63
11.1 Die CHIP aus Radius__________________________________________________63
12 Übertragen der CDRs in das T·XMD_________________________________________64
12.1 Erweiterung des T·XMD um eine einfache VoIP–Rating–Schnittstelle___________64
12.2 Erstellen einer Konfiguration des T·XMD für VoIP – CDRs____________________66
| 5
Diplomarbeit
Stefan Abu Salah
13 Rechtliche Situation______________________________________________________68
14 Schlussbetrachtung_______________________________________________________70
15 Abbildungsverzeichnis____________________________________________________71
16 Tabellenverzeichnis_______________________________________________________72
17 Abkürzungsverzeichnis____________________________________________________73
18 Literaturverzeichnis_______________________________________________________75
18.1 Printmedien_________________________________________________________75
18.2 Internetquellen______________________________________________________75
19 Anhang________________________________________________________________76
19.1 Änderungen am Quellcode des SER : msgparser.c__________________________76
19.2 Änderungen am Quellcode des RTPProxy : main.c__________________________97
19.3 SER.cfg___________________________________________________________105
19.4 Makefile.defs (SER)__________________________________________________109
19.5 Makefile (rtpproxy)__________________________________________________109
| 6
Diplomarbeit
Stefan Abu Salah
1 Vorwort
Internettelefonie [VoIP = Voice over IP] hat in den letzten Jahren sowohl technologisch als
auch von der Akzeptanz her im Markt große Sprünge gemacht. Die Verbesserung der
verwendbaren Sprachcodecs, einhergehend mit der drastischen Erhöhung der dem
Endkunden zur Verfügung stehenden Bandbreite, hat die anfängliche Skepsis der Kunden
weichen lassen, dass VoIP zu einer konkurrenzfähigen Alternative zur herkömmlichen
Telefonie zu werden kann. Das Internet ist in den letzten Jahren zu einem ständigen
Begleiter durch den Alltag geworden und aus der Geschäftswelt nicht mehr
wegzudenken. Email und Instant-Messenger dienen heute der Kommunikation zwischen
Menschen. Die Gewöhnung der Menschen an diese Dienste ist inzwischen sehr weit
fortgeschritten. Diese inzwischen zur Normalität gewordene Nutzung digitaler Medien
hat zu einer neuen Offenheit gegenüber Neuerungen geführt. Ein logischer Schritt ist nun
die intensive Nutzung des Internets nicht nur für Datendienste wie das WWW oder die
Übertragung von Textnachrichten, sondern auch für die Übertragung von Sprache in
Echtzeit. Flatrates versprechen mit unschlagbaren Preisen eine Art Telefon-Flatrate zu
werden.
Das größte Problem der VoIP-Anbieter war bisher, dass sie ihren Kunden nur eine
Verbindung von Rechner zu Rechner anbieten konnten. Das Anrufen eines Teilnehmers
mit einem herkömmlichem Telefon war von einem VoIP-Anschluß lange Zeit nicht
möglich. Dieser Umstand machte es VoIP-Dienstleistern schwer, Geld mit dieser
Technologie zu verdienen. Das Bindeglied zwischen der VoIP-Welt und den Telefonnetzen
fehlte und Kunden waren nicht bereit für eine einfache Rechner-zu-Rechner–Verbindung
extra zu zahlen. Erst die Einführung von VoIP-Gateways1 machte das Telefonieren ins
weltweite Telefonnetz möglich und VoIP zu einer wirklichen Alternative zum
herkömmlichen Telefon. Die weitgehende Nutzung der Internetinfrastruktur macht diese
Technik besonders günstig.
Die Instandhaltung des bestehenden Telefonnetzes und die Schaffung neuer Kapazitäten
für Telefon aber auch für die Nutzung des Internets, kostet die Telefongesellschaften
enorme Summen. Diese Kosten deckten bisher die Kunden der Telefonanbieter mit ihren
Gebühren. Ohne Beteiligung der VoIP-Teilnehmer an diesen Kosten kann in Zukunft keine
1 Ein Gateway ermöglicht das Kommunizieren von Netzwerken, die auf völlig unterschiedlichen Protokollen basieren.
Vorwort
| 7
Diplomarbeit
Stefan Abu Salah
moderne Infrastruktur aufrecht erhalten und erweitert werden.
Bisherige VoIP-Tarifmodelle sehen nur einen Tarif für nationale Verbindungen vor. Eine
entfernungsbasierte Abrechnung, wie dies derzeit im Festnetz üblich ist, ist nicht möglich.
Damit auch die Nutzung des Internetweges, also die Vermittlung der Sprachpakete über
das Internet, in Rechnung gestellt werden kann, ist eine Verzonung der VoIP–Welt ein
wichtiger Schritt. Damit auch im VoIP–Netz Orts- oder Ferngespräche abrechenbar
werden, sind einige technische Neuerungen nötig.
Vorwort
| 8
Diplomarbeit
Stefan Abu Salah
2 Ziel dieser Diplomarbeit
In Zusammenarbeit mit der Firma TECON soll diese Arbeit die oben genannten Probleme
beseitigen. Dies bedarf einiger Änderungen in den bestehenden Systemen, welche die
Telefonie über das Internet ermöglichen. Es müssen Abrechnungsschnittstellen
geschaffen werden, welche die VoIP-Welt mit der herkömmlichen PSTN2-Welt verbinden.
Es soll möglich werden, den Aufenthaltsort der an einem VoIP-Gespräch beteiligten
Personen bestimmen zu können, und somit eine entfernungsbasierte Abrechnung, aber
auch Not- und Röchelrufe, zu ermöglichen. Insbesondere bei Not- und Röchelrufen ist
eine Bestimmung des Ausgangsortes des ankommenden Telefonats für die schnelle
Hilfeleistung sehr wichtig und rechtlich vorgeschrieben. Bislang verhindert unter anderem
auch die fehlende Lokalisierng der Teilnehmer eine Trennung von Telefon- und
Internetanschluss. Ziel dieser Diplomarbeit ist es, diese Umstände aus dem Weg zu
räumen. Folgende Ziele wurden für diese Diplomarbeit definiert:

Lokalisierung der Gesprächsteilnehmer

Ermittlung der Gesprächsparameter (u.a. die Länge des Gesprächs, die verwendeten
Codecs)

Erzeugen der zur Abrechnung benötigten CDRs (Call Detail Records)

Implementierung einer Watchdog-Funktion

Erstellen eines einfachen Rating-Moduls für das Verarbeiten der CDRs im T·XMD
(TECON eXtended Mediation Device)
2 Public Switched Telephone Network. Unter einem PSTN versteht man ein Telekommunikationsnetz, das für die Abwicklung von
Telefongesprächen konstruiert ist
Ziel dieser Diplomarbeit
| 9
Diplomarbeit
Stefan Abu Salah
3 Grundlagen zu VoIP
Derzeit befinden sich die Wege der Kommunikation in einem starken Wandel. Waren
früher Telekommunikationsnetze noch auf die Übertragung von Sprache spezialisiert,
gehen heute die Anwendungen weit über diesen alleinigen Nutzen hinaus. Schon lange
ist
die
Verwendung
Informationsbeschaffung
des
der
Internet
ein
wesentlicher
Telekommunikationskunden.
Hier
Bestandteil
prallen
der
Techniken
aufeinander, die vollkommen unterschiedliche Ansätze verfolgen. Auf der einen Seite
stehen
die
klassischen
Kommunikationsnetze
mit
ihren
verbindungsorientierten
Gesprächskanälen mit exklusiv zugeordneten garantierten Bandbreiten, auf der anderen
Seite stehen die verbindungslosen, paketorientierten Netze des Internets. Ist QoS3
(Quality of Services) für klassische Telekommunikationsnetze ein absolutes Muß, so gilt
bei den verbindungslosen Netzen allenfalls das Prinzip best effort, also die
schnellstmögliche Vermittlung der Datenpakete durch das Netz. Um eine möglichst
hochwertige Sprachübertragung auch über das Internet zu gewährleisten, stehen eine
Vielzahl an Protokollen und Codecs zur Verfügung.
3.1 Codecs
Das Wort Codec ist ein englisches Akronym der Begriffe Coder und Decoder. Spricht man
von einem Codec, so meint man meistens ein Verfahren zum Umwandeln von analogen
Sprach- oder Videoinformationen in ein digitales, oft komprimiertes, Format. Die
Verfahren zur Kodierung eines analogen Signals sind vielfältig und haben sich in den
letzten Jahren stark entwickelt. Besonders durch höhere Rechenkapazitäten und höhere
Bandbreiten haben sich die Möglichkeiten der Codecentwickler verbessert. Weiterhin
haben die Entwickler mit vielen Problemen zu kämpfen. So müssen Codecs zum einen
ressourcenschonend sein, zum anderen das Originalsignal möglichst originalgetreu
wiedergeben. Fehlerhaft übertragene oder ganz fehlende Pakete müssen ersetzt werden,
ohne dass sich dies negativ auf die Signalqualität auswirkt. Die Methoden hierfür sind
vielfältig. Einige Codecs setzten auf das Auffüllen dieser Lücken mit einfachem Rauschen,
3 QoS (Quality of Service) bezeichnet die Priorisierung von IP-Datenpaketen anhand bestimmter Merkmale und Eigenschaften. Auf
diese Weise können beispielsweise VoIP – Pakete schneller ihren Adressaten erreichen und somit kann die Sprachqualität von
Verbindungen erhöht werden.
Grundlagen zu VoIP
| 10
Diplomarbeit
Stefan Abu Salah
andere, aufwendigere, setzen auf Schachtelung der Sprachinformationen in viele Pakete.
Geht hier ein Paket verloren, kann der verlorengegangene Inhalt aus den korrekt
empfangenen Paketen errechnet werden. Man erkauft sich bei erstgenanntem Verfahren
die hohe Performance mit gelegentlich hörbaren Knacksern bei Verlust von Paketen,
während man bei letzgenanntem Verfahren bei einem packet-loss oft ein höheres Delay
und eine durch nicht ganz perfekte Auffüllalgorithmen künstlich klingende Stimme hat.
Durchgesetzt haben sich für VoIP insbesondere PCM (Pulse Code Modulation) und das
aus dem Mobilfunk bekannte GSM (Global System for Mobile Communications).
Folgende Tabelle zeigt einige gängige Codecs für den Einsatz von VoIP. Die letzte Spalte
der Tabelle enthält die zu den jeweiligen Codecs gehörenden Identifizierer, welche in den
RTP-Datenpaketen (Realtime Transport Protocol, RFC1889) mitgeführt werden. Auf diese
Weise weiß die Empfangsstation des RTP-Streams, welcher Decoder benutzt werden
muss.
Codec
Audio / Video
Abtastrate
(Hz)
Audiochannel
RTPPayloadtype
PCMU
Audio
8000
1
0
G.721
Audio
8000
1
2
GSM
Audio
8000
1
3
PCMA
Audio
8000
1
8
G.722
Audio
8000
1
9
G.728
Audio
8000
1
15
H.261
Video
90000
-
31
Tabelle 1 Codecs für VoIP
3.2 Das Real Time Protocol
Für die Übertragung von Sprach- und Videopaketen im Internet hat sich RTP als das
zuverlässigste herausgestellt. RTP beinhaltet einige wichtige Voraussetzungen, um in
Echtzeit Daten über das Internet zu senden. Ein wichtiger Mechanismus ist der ständige
Austausch von Zeit- und Synchronisationsmarkern zwischen Sender und Empfänger. Auf
diese Weise kann eine Dienstesynchronität sichergestellt werden. Des Weiteren enthalten
Grundlagen zu VoIP
| 11
Diplomarbeit
Stefan Abu Salah
alle RTP-Pakete einen timestamp und eine Sequenznummer, mit deren Hilfe
Paketüberholungen festgestellt werden können, und es gibt im RTP-Header einen Eintrag,
der Sender und Empfänger eindeutig identifiziert. Für die Übertragung der RTP-Pakete
nutzt man in der Regel UDP (User Datagram Protocol, RFC768). Die Verwendung von TCP
(Transmission Control Protocol, RFC793) ist bei Echtzeitanwendungen zwar auch
denkbar, der von TCP bereitgestellte PAR-Mechanismus (Positive Acknoledgement with
Retransmission), also das nochmalige Versenden eines verlorengegangenen Paketes,
macht bei zeitkritischen Anwendungen keinen Sinn, da es nur ein gewisses Zeitfenster
gibt, in dem dieses Paket noch verarbeitet werden kann. [TCP]
IP
20 Byte
V
P X
UDP
RTP
8 Byte
CC
12 Byte
M
Kodierter Audio/Video Content
20 ... 150 Byte
PT (7 Bit)
Sequence Number (16 Bit)
Timestamp (32 Bit)
Syncronisation Source (SSRC) Identifier (32 Bit)
Contributing Source (CSRC) Identifiers (0 ... 15*32 Bit)
V: Version (2 Bit)
P: Padding (1 Bit)
X: Extension (1 Bit)
CC: CSCR Count (4 Bit)
M: Marker (1 Bit)
PT: Payload Type (7 Bit)
CSRC ist optional
Abbildung 1 Aufbau eines RTP-Headers
Trotz all dieser Maßnahmen kann durch die alleinige Verwendung von RTP als
Transportprotokoll für Echtzeitdaten Quality of Services nicht erreicht werden. RTP nutzt
nur die gängigen Mechanismen des Internets zur Übertragung der Nachrichten.
Zur Realisierung von QoS gibt es andere Protokolle wie RSVP4 (Resource ReSerVation
4 RSVP ist ein Signalisierungsprotokoll und dient dem Reservieren gewisser Bandbreiten speziell für einen Dienst.
Grundlagen zu VoIP
| 12
Diplomarbeit
Stefan Abu Salah
Protocol, RFC2205) oder DiffServ5 (Differentiated Service Architecture in IP Network,
RFC2474, RFC2475). Trotz dieser Tatsache bringt RTP alle notwendigen Informationen
mit, die für den Transport von Echtzeitinformationen nötig sind.
RTP bringt keine Mechanismen mit, die den Auf- oder Abbau von Verbindungen initiieren
können, ist auf diese jedoch angewiesen. Um diesen Umstand aus dem Weg zu räumen,
bedarf es anderer Protokolle. Hier bieten sich unter anderem SIP (siehe Kapitel 3.5) oder
H.3236, an.
3.2.1 Der RTP-Proxy
Ein RTP-Proxy übernimmt von den ihm bekannten Clients die zu sendenden Pakete und
schickt sie mit einem neuen Header an den Zielrechner. Auf diese Weise sieht er für die
Kommunikationspartner aus wie ein normaler Client. Jedes zu einer Verbindung
gehörende RTP-Paket durchläuft den Proxy-Server. Die SIP-Messages zur Steuerung des
Gesprächs laufen jedoch nach wie vor über den SIP-Server (siehe Kapitel 3.4.2).
SIP-Server
SI
P
es
ag
-M
e
ss
ss
Me
ag
P-
es
SI
RTP-Proxy
RTP-Stream
RTP-Stream
Abbildung 2 VoIP mit RTP-Proxy
5 DiffServ ist ein Priorisierungsverfahren von IP-Datenpaketen für das Erreichen von QoS. Die Priorität des Pakets wird anders als bei
RSVP vom Sender bestimmt.
6 In der von der ITU-T veröffentlichten Empfehlung H.323 sind Protokolle definiert, die eine audio-visuelle Kommunikation auf jedem
paketbasiertem Netzwerk ermöglicht.
Grundlagen zu VoIP
| 13
Diplomarbeit
Stefan Abu Salah
3.3 Das Real Time Control Protocol
RTCP (Real Time Control Protocol, RFC1890) überträgt einige Steuerinformationen, die für
den Transport der RTP-Datenströme benötigt werden. Regelmäßig werden hierfür RTCPPakete zwischen Sender und Empfänger ausgetauscht, in denen unter anderem
Feedbacks über die Qualität der Verbindung (QoS Feedback) und Änderungswünsche
bezüglich der Senderate oder des verwendeten Codecs gesendet werden.
IP
20 Byte
V
P
UDP
RTCP
8 Byte
RC
PT = SR (9 Bit)
Length (16 Bit)
SSRC of Sender (32 Bit)
NTP Timestamp, most Significant Word (32 Bit)
NTP Timestamp, least Significant Word (32 Bit)
RTP Timestamp (32 Bit)
Sender's Packet Count (32 Bit)
Sender's Octet Count (32 Bit)
Report Block 1 (24 Byte)
Report Block 2 (24 Byte)
Profile Specific Extensions (32 Bit)
V:
P:
RC:
PT:
NTP:
Version (2 Bit)
Padding (1 Bit)
Report Count (4 Bit)
Packet Type (9 Bit)
Network Time Protocol
Abbildung 3 Aufbau eines RTCP-Headers
Auf diese Weise kann auf veränderte Einflüsse auf dem Vermittlungsweg reagiert und
Grundlagen zu VoIP
| 14
Diplomarbeit
Stefan Abu Salah
eine störungsfreie Übertragung der Nutzdaten gewährleistet werden. RTCP bietet eine
Vielzahl weiterer interessanter Möglichkeiten der Einflußnahme auf eine RTPDatenübertragung, auf die hier im Einzelnen nicht weiter eingegangen wird.
3.4 Übersicht über SIP
SIP (Session Initiation Protocol, RFC3261, früher RFC2543) wurde von der IETF7
entwickelt,
um
einen
komplett
neuen
Ansatz
für
Verbindungen
in
Kommunikationssysteme zu liefern, und ist in seiner Definition dem HTTP (Hyper Text
Transfer Protocol, RFC1945, RFC2616) wesentlich näher als den klassischen Protokollen
der Telekommunikation. Entwickelt wurde es, um Verbindungen zwischen Endgeräten
einzuleiten, zu ändern und zu beenden. Generell kann man mit SIP eine ganze Reihe von
Diensten ermöglichen, es ist in keiner Weise an VoIP gebunden. Von Anbeginn der
Entwicklung war es das Ziel, ein Protokoll zu schaffen, welches die Möglichkeit bietet,
nicht nur Multimediaverbindungen, sondern auch Verbindungen ganz anderer Art zu
steuern. [SIP]
Conference Management
Conference Setup and
Discovery
SAP
UDP
SDP
SIP
HTTP
Media Agents
Conference Course
Control
SMTP
RSVP
Ditributed
Control
TCP
Audio/ Shared
Video Apps.
RTP/ Reliable
RTCP Multicast
UDP
IP + IP Multicast
Abbildung 4 Protokollarchitektur für Multimediaverbindungen
Zum Transport der Nutzdaten einer Multimediaverbindung bedient man sich anderer
Protokolle, welche von der IETF festgelegt wurden. Genau diese Flexibilität ist eine
besondere Stärke von SIP. An Nahtstellen zu diversen anderen Netzen lässt sich mit
Gateways eine Verbindung herstellen. So ist es denkbar, mit zwischengeschaltetem PSTN7 Die Internet Engineering Task Force (IETF) ist neben der Internet Research Task Force (IRTF) eine von zwei Arbeitsgruppen des
Internet Architecture Board (IAB). Sie ist eine offene, internationale Vereinigung von Netzwerktechnikern, Herstellern und
Anwendern, die für Vorschläge zur Standardisierung des Internets zuständig ist.
Grundlagen zu VoIP
| 15
Diplomarbeit
Stefan Abu Salah
Gateway eine Verbindung aus dem IP-Netz ins herkömmliche Telekommunikationsnetz
herzustellen und umgekehrt. SIP ist Teil der von der IETF ins Leben gerufenen
Steuerungsstruktur, zu der auch RTP, RTCP, RTSP (Real Time Streaming Protocol,
RFC82326), SAP (Session Announcement Protocol), SDP (Session Discription Protocol, RFC
2327) und RSVP (Recource Reservation Protocol, RFC2205) gehören.
3.4.1 SIP-Komponenten
Im Folgenden werden die an einer SIP-Sitzung beteiligten Komponenten kurz erläutert:

Der UAC (User Agent Client) ist die Instanz, die die Session initiiert. Dies kann ein
Endgerät, also z.B. ein IP-Telefon oder ein PC mit Software für die IP-Telefonie sein.

Der UAS (User Agent Server) ist die Instanz, die die Anfragen des UAC entgegennimmt
und beantwortet. Sie bildet das Gegenstück zum UAC. Ein UAS könnte ein SIP-Proxy
(siehe Kapitel 3.4.3) sein, denkbar ist aber auch eine Peer-to-Peer-Verbindung,
beispielsweise direkt zwischen zwei PCs, in diesem Fall ist eine Unterscheidung
zwischen UAC und UAS nicht eindeutig möglich, da jedes Endgerät UAC und UAS sein
kann. Ein klassischer UAS kann in einem Netzwerk gewisse Dienste zur Verfügung
stellen, er baut jedoch von sich aus nie eine Verbindung zu einem UAC auf. Beispiele
hierfür sind LDAP9 (Lightweight Directory Access Protocol, RFC2251) oder ein RADIUSServer (Remote Authentication Dial-In User Service, RFC2138, RFC2139).
3.4.2 Der SIP – Server
Eine zentrale Rolle spielt in einem SIP-System der SIP-Server. Er stellt viele wichtige
Funktionen bereit. So nimmt er Registrierungsanfragen UACs entgegen und steuert
Leistungsmerkmale, wie beispielsweise das Parken von Verbindungen, Call Pickup usw. Er
übernimmt die Funktion des AAA (weitere Erläuterungen zu AAA finden Sie in Kapitel 5)
und ermittelt die genaue Endadresse der Teilnehmer (z.B. sip:username@anbieter). Er
leitet Verbindungsanforderungen bei Bedarf an zuständige Server weiter und kümmert
8 Die Requests for Comments (RFC) sind eine Reihe von technischen und organisatorischen Dokumenten des RFC-Editor zum
Internet. Bei der ersten Veröffentlichung noch im ursprünglichen Wortsinne zur Diskussion gestellt, behalten RFC auch dann ihren
Namen, wenn sie sich durch allgemeine Akzeptanz und Gebrauch zum Standard entwickelt haben.
9 LDAP ist ein Netzwerkprotokoll zur Realisierung von Verzeichnisdiensten und wurde von der University of Michigan 1993
entwickelt.
Grundlagen zu VoIP
| 16
Diplomarbeit
Stefan Abu Salah
sich um QoS-Anforderungen, indem er diese an andere Netzelemente sendet. Bei Peer-toPeer-Verbindungen ist der Einsatz eines SIP-Servers nicht zwingend nötig, vorausgesetzt,
die IP-Adressen der Teilnehmer sind bekannt.
3.4.3 Der SIP–Proxy
Ein SIP-Proxy übernimmt die Vermittlung der SIP-Messages durch das Netz, indem er
ankommende SIP-Messages entgegennimmt und diese mit neuem Header an den
Zielrechner, oder falls ihm dieser nicht bekannt ist, an einen ihm bekannten SIP-Proxy
verschickt. Auf diese Weise stellt er sich für die Kommunikationspartner wie ein normaler
Client dar. Jedes zu einer Verbindung gehörende SIP-Paket durchläuft den Proxy-Server.
SIP-Proxy
SIP-Proxy
SIP-Messages
SI
es
P-
ag
Me
ss
ss
Me
ag
P-
es
SI
RTP-Stream
Teilnehmer A
Teilnehmer B
Abbildung 5 SIP-Proxy
3.4.4 Grundlagen des Protokolls
SIP bietet wichtige Funktionen zur Steuerung von Echtzeitanwendungen über das
Internet. Um über das verbindungslose Internet Verbindungen aufzubauen und somit
benötigte Betriebsmittel bereitzustellen, ist Signalisierung (Call Control) notwendig. Mit
SIP ist es möglich, alle aus der herkömmlichen ISDN-Welt bekannten Features auch in der
VoIP-Welt zu nutzen. Hierzu gehören User–Capabilities (z.B. Festlegen eines AudioCodecs), User–Availability (Feststellen der Kommunikationsbereitschaft), Call–Setup (z.B.
Verbindungsaufbau), Call–Handling (z.B. Weiterleiten einer Verbindung) und einige
Grundlagen zu VoIP
| 17
Diplomarbeit
Stefan Abu Salah
weitere. Der Transport der SIP-Messages erfolgt gewöhnlich über UDP auf Port 5060
(möglich, jedoch nicht empfohlen, ist auch die Verwendung von TCP). SIP vermittelt
sowohl Peer-to-Peer- als auch Mehrpunktverbindungen und ermöglicht die Adressierung
von Benutzern über IP-Adressen oder Namen. SIP gilt derzeit als das wichtigste Protokoll
zur Handhabung von Multimediaverbindungen im Internet
und hat sich gegen
Konkurenten wie H.323 klar durchgesetzt. In Zukunft wird SIP als zentrales
Vermittlungsprotokoll
des
Mobilfunkstandards
UMTS
(Universal
Mobile
Telecommunications Systems) seine Leistungsfähigkeit unter Beweis stellen. [sip]
3.4.5 SIP-Nachrichten
Im Verlauf dieser Diplomarbeit war es elementar wichtig, die genaue Definition der SIPMessages aus RFC2543 und RFC3261 zu kennen, da mit in C programmierten
Filterfunktionen gezielt Headerinformationen ausgelesen und verarbeitet werden müssen.
In RFC2543 sind sieben SIP-Methoden definiert. Diese Methoden dienen dem Austausch
von Informationen zwischen beteiligten Stationen und dem SIP-Server. Sie steuern
beispielsweise den Auf- oder Abbau eines VoIP-Geprächs. Im Folgenden werden die
definierten SIP-Methoden genauer beleuchtet:
SIP - Methode
REGISTER
INVITE
BYE
STATUS
Beschreibung
Eine REGISTER-Methode wird von einem SIP-Client zum Registrar
gesendet, damit dieser ihn in seine intern geführte Liste der durch ihn
verwalteten SIP-User aufnimmt. Der Client meldet mit dem REGISTER
seine Bereitschaft zum Annehmen von eingehenden VoIP-Gesprächen
an.
Die INVITE-Methode wird von einem SIP-Client an den SIP-Server
gesendet, um eine VoIP-Verbindung zu einem anderen Clienten
aufzubauen. Die INVITE-Methode ist die erste für das Initiieren einer
Verbindung gesendeten Methode.
Die BYE-Methode beendet ein Gespräch. Die BYE-Methode wird von
einem UAC beispielsweise beim Auflegen des Telefonhörers
verschickt.
Die STATUS-Methode gibt Auskunft über den Zustand einer
Verbindung.
Grundlagen zu VoIP
| 18
Diplomarbeit
Stefan Abu Salah
CANCEL
ACK
OPTIONS
Ein CANCEL wird zum vorzeitigen Beenden eines Requests versendet.
Dies ist beispielsweise der Fall, wenn die maximale Wartezeit für das
Abheben des Telefonhörers auf der Seite des B-Teilnehmers erreicht
ist, oder der A-Teilnehmer den Hörer seinerseits vor einer Reaktion des
B-Teilnehmers auflegt.
Ein ACK ist eine positive Bestätigung des Verbindungsaufbaus. Nach
erfolgreichem Austausch der ACK-Methoden kann mit dem
Datenaustausch begonnen werden.
Mit der OPTIONS-Methode können Informationen zu den
Eigenschaften von Endsystemen abgefragt oder bereitgestellt werden,
ohne das hierfür eine Verbindung hergestellt werden muss.
Tabelle 2 SIP-Methoden
Desweiteren sind einige Statuscodes in SIP
definiert. Diese Codes dienen dem
Klassifizieren von SIP-Methoden und deren Inhalt. Generell lassen sich die Statuscodes in
sechs Grundtypen einordnen. In Tabelle 3 sind die verfügbaren Statuscodes zusammen
mit ihren Bedeutungen aufgelistet:
Grundlagen zu VoIP
| 19
Diplomarbeit
Stefan Abu Salah
Client Error
Code
413
414
415
420
480
481
482
483
484
485
486
487
500
501
502
503
504
505
600
603
604
606
Server Error
Bedeutung
Trying
Ringing
Call is Being Forwarded
Queuing
Session Progress
OK / Success
Multiple Choices
Moved Permanently
Moved Temporarily
Use Proxy
Alternative Service
Bad Request
Unauthorized
Payment Required
Forbidden
Not Found
Method not Allowed
Not Acceptable
Proxy Auth. Required
Request Timeout
Conflict
Gone
Length Required
Global Failure
Client Error
Redirection
Informational
Code
100
180
181
182
183
200
300
301
302
305
380
400
401
402
403
404
405
406
407
408
409
410
411
Bedeutung
Request Entity too Large
Request URI too Large
Unsupported Media Type
Bad Extension
Temporarily not Available
Call Leg does not Exist
Loop Detected
Too many Hops
Address Incomplete
Ambiguous
Busy here
Request Cancelled
Internal Server Error
Not Implemented
Bad Gateway
Service Unavailabel
Gateway Timeout
SIP Version not Supported
Busy Everywhere
Decline
Does not Exist Anywhere
Not Acceptable
Tabelle 3 Status Codes
Grundlagen zu VoIP
| 20
Diplomarbeit
Stefan Abu Salah
Das folgende Strichdiagramm zeigt den SIP-Nachrichtenaustausch bei der Verwendung
eines SIP-Servers:
SIP-Server
A-Teilnehmer
INVITE
Trying
Ringing
B-Teilnehmer
INVITE
Ringing
OK
OK
ACK
ACK
Austausch der Gesprächsdaten
BYE
BYE
x
OK
OK
t
Abbildung 6 SIP - Nachrichtenaustausch
3.4.6 Aufbau der SIP-Messages
Der Aufbau der in RFC2543 definierten SIP-Messages unterscheidet sich kaum von den
Definitionen von HTTP/1.1 oder SMTP (RFC821). Anfragen und Antworten werden auf
Basis von Klartext zwischen den beteiligten Stationen ausgetauscht. Man unterscheidet
genau wie bei HTTP zwischen Requests und Responses, wobei beide denselben
Grundaufbau haben. SIP-Messages bestehen aus UTF-8 kodierten Textkomponenten (ISO
10646 Character Set). Folgende Grafik zeigt den generellen Aufbau einer SIP-Message
Grundlagen zu VoIP
| 21
Diplomarbeit
Stefan Abu Salah
zusammen mit einem Beispiel einer Original INVITE-Message:
Start Line
Message Header
Enthält:
General Header
Entity Header
Request Header
Response Header
Leerzeile
Message Body
SDP
INVITE sip:[email protected] SIP/2.0
Via: SIP/2.0/UDP 139.6.16.111:5060
From: "phil1"
<sip:[email protected]>;tag=000d290027926519c-1fcc317b
To: <sip:[email protected]>
Call-ID: [email protected]
CSeq: 101 INVITE
CRLF
v=0
o=CiscoSystemsSIP-IPPhone-UserAgent 28199 24313 IN IP4
139.6.16.111
s=SIP Call
c=IN IP4 139.6.16.111
t=0 0
m=audio 24638 RTP/AVP 8 0 18 101
a=rtpmap:8 PCMA/8000
a=rtpmap:101 telephone-event/8000
a=fmtp:101 0-15
Abbildung 7 Aufbau einer SIP-Message
Headertyp
General Headers
Entity Headers
Response Headers
Request Headers
Beschreibung
Enthält allgemeine Informationen wie beispielsweise Absender
und Empfängeradresse und die CallID
Beschreibung des Typs und der Länge der SIP-Nachricht, z.B.
Content-Type, Content-Length, Allow u.s.w.
Enthält Informationen vom Server, z.B. www-Authenticate,
Warning, Proxy-Authenticate, u.s.w.
Beschreibung weiterer Informationen durch den SIP-Client, z.B.
Authorisation, Max-Forwards, Proxy-Require, u.s.w
Tabelle 4 SIP-Header
Grundlagen zu VoIP
| 22
Diplomarbeit
Stefan Abu Salah
3.4.7 Das Session Description Protocol SDP
SDP (Session Description Protocol, RFC2327) ist ein Unterstützungsprotokoll und
ermöglicht die genaue Beschreibung einer RTP-Verbindung. Es dient dem Aushandeln von
Codecs, Bandbreiten, Media-Beschreibungen und einigen anderen für die Kommunikation
wichtigen Komponenten. SDP ist eigentlich kein eigenständiges Protokoll, sondern stellt
eine von SIP oder RTP nutzbare Erweiterung dar. Die folgende Tabelle zeigt die in SDP
definierten Parameter:
Parameter
a
b
c
e
i
k
m
o
p
r
s
t
u
v
z
Name
Attributes
Bandwidth
Connection Information
E-Mail Address
Session Information
Encryption Key
Media
Owner
Phone Number
Repeat
Session Name
Time
URI
Version
Time Zone Adjustment
Beschreibung
SDP – Erweiterungen
erforderliche Bandbreite
Mediastream Informationen
E-Mailadresse des Erzeugers
Zusatzinformationen in Textform
Verschlüsselungskeys
Adresse und Name des Mediastreams
Erzeuger dieser Session
Telefonnummer des Erzeugers
Wiederholungen
Name dieser Session
Dauer dieser Session
Identifier dieser Session-Beschreibung
Protokollversion
Zeitzoneninformationen
Tabelle 5 SDP-Parameter
Grundlagen zu VoIP
| 23
Diplomarbeit
Stefan Abu Salah
4 SER - Sip Express Router
Der SER (Sip Express Router) ist eine von der Gruppe iptel.org des Fraunhofer10 Instituts
FOKUS11 entwickelte Routersoftware für den Einsatz von VoIP. Die Software wurde auf
Performance optimiert, was es ihr ermöglicht, selbst auf einem Standard-PC mehrere
tausend Gespräche pro Minute zu verwalten. Die Bearbeitung der Telefonate übernimmt
eine vom SER geführte Routingtabelle. Der SIP Express Router basiert auf dem Session
Initiation Protocol und ist auch deshalb für eine große Zahl von Diensten tauglich und
nicht auf VoIP beschränkt. Denkbar sind Umsetzungen mit Diensten wie Messaging,
Videokonferenzen oder Voice-Mail. Ein weiterer Grund für die schnelle Verbreitung des
SER sind die niedrigen entstehenden Kosten. Des Weiteren unterliegt der SER in vielen
Ländern keinerlei nationaler Regulierungen. Durch seinen modularen Aufbau ist die
Erweiterung des SER mit neuen Diensten kein Problem und in wenigen Arbeitsschritten
vollzogen. Eine Vielzahl an Modulen bietet bereits das Grundpaket des SER, viele im Netz
verfügbare Module erweitern dieses Angebot nochmals um einige interessante
Funktionen.
Dies sind einige Gründe, weshalb sich neue Dienstanbieter, wie beispielsweise sipgate,
Freenet oder iPhone, im kommerziellen Bereich auch durch die Entwicklung des SER neue
Märkte erschließen konnten.
Der SIP Express Router übernimmt den Auf- und Abbau von Telefongesprächen über das
Internet und bietet darüber hinaus eine Vielzahl weiterer Dienste wie AAA (siehe Kapitel
5.1), über Schnittstellen zu MySQL und RADIUS, oder Billingdienste, die sich nahtlos in
zukünftige
Kommunikationsstrukturen
integrieren
lassen.
Für
die
Zukunft
sind
weitergehende Möglichkeiten geplant. So wird es in kommenden Versionen komplexe
Anwendungen wie Konferenzmanagement, Calling-Card-Szenarien oder auch Click-To-Dial
geben.
10 Die Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e. V. ist die größte Organisation für Forschungs- und
Entwicklungsdienstleistungen in Europa. Sie stellt einen wichtigen Teil der deutschen Forschungslandschaft dar, die u. a. aus
Hochschulen, Max-Planck-Gesellschaft, Hermann von Helmholtz-Gemeinschaft, Wissenschaftsgemeinschaft Gottfried Wilhelm
Leibniz und der Deutschen Forschungsgemeinschaft besteht.
11 FOKUS ist ein Institut von der Fraunhofer Gesellschaft und entwickelt die notwendigen Bausteine für eine vollständige, nahtlose
Integration von Technologien und Endgeräten sowie für den Einsatz von offenen flexiblen Kommunikationsdiensten und
-anwendungen.
SER - Sip Express Router
| 24
Diplomarbeit
Stefan Abu Salah
4.1 Die Konfigurationsdatei ser.cfg
Alle wichtigen Einstellungen am SER werden in dem Konfigurationsskript ser.cfg
vorgenommen. Hier nimmt der Administrator Einfluß auf den Ablauf des SER und
erweitert ihn mit zusätzlichen Modulen. Wichtig ist hier die syntaktische Verwandtschaft
zur Programmiersprache C, die ein schnelles und eingängliches Arbeiten mit dieser
Konfigurationsdatei ermöglicht. Zur Veranschaulichung sehen sie im Folgenden einen
Ausschnitt aus der Konfigurationsdatei; hier wird das Verhalten des SER beim Eintreffen
einer INVITE-Message definiert:
...
if (method == "INVITE") {
if (lookup("location_inet4")) {
# Comment out three lines below if you want
# RTP for IPv4->IPv4 calls to go directly
# between UAs
if (af == inet) {
if (force_rtp_proxy("FAII"))
t_on_reply("1");
} else {
sl_send_reply("403", "User nicht erreichbar
oder unbekannt!");
break;
};
};
};
...
Die Möglichkeiten des SER sind, wie bereits erwähnt, über zusätzliche Module
erweiterbar. Damit der SER diese Module verarbeiten kann, müssen diese in der
Konfigurationsdatei geladen und konfiguriert werden. Der folgende Skriptauszug
veranlasst den SER dazu, das Modul acc.so zu laden, und setzt einige wichtige Parameter
zur Steuerung der Modulfunktionalitäten.
SER - Sip Express Router
| 25
Diplomarbeit
Stefan Abu Salah
...
loadmodule "/usr/local/lib/ser/modules/acc.so"
...
modparam
("acc","radius_config","/usr/local/etc/radiusclient/radiusclient.conf")
modparam("acc", "service_type", 15)
modparam("acc", "radius_flag", 1)
...
Je nach Installationsart des SER befindet sich das Konfigurationsskript unter /etc/ser oder
unter /user/local/etc/ser. Das komplette Skript, welches ich für diese Arbeit erstellte,
befindet sich im Anhang dieser Diplomarbeit.
SER - Sip Express Router
| 26
Diplomarbeit
Stefan Abu Salah
5 RADIUS
Die meisten Benutzer des Internets wissen nicht, wie sie vom Provider freigeschaltet
werden, damit sie im Internet surfen oder ihre eMails abrufen können. Auch wenn sie
einen Heimzugang zum Firmennetz ihres Arbeitgebers nutzen, ist es für sie vollkommen
uninteressant, wie dies genau funktioniert, solange es funktioniert. Sicher ist allerdings,
dass es eine Möglichkeit geben muss, mit der ein System erkennt, wer Sie sind und was
genau Ihre Nutzungsprivilegien zu dem bereitgestellten Dienst sind. Die Technik, die dies
ermöglicht, heißt Remote Access Dialin User Service, oder kurz RADIUS. [RAD]
RADIUS, ursprünglich von Livingston Enterprises entwickelt, ist ein Access-ControlProtokoll welches die Authentizität eines Users auf Basis einer challenge/responseMethode, verifiziert. RADIUS wird inzwischen überall dort eingesetzt, wo die
Authentizität, zentrale Authorisation und detailiertes User-Accounting benötigt werden.
5.1 AAA - Authentifikation, Authorisation, Accounting
RADIUS war das erste Protokoll, welches AAA-Funktionalitäten im vollen Umfang
ermöglichte, und so sehr schnell auf Akzeptanz in der Industrie stieß. Natürlich gab es
auch andere Methoden und Architekturen, die eine ähnliche Zielsetzung verfolgten, aber
es hat sich gezeigt, dass AAA einige besondere Vorzüge gegenüber anderen Mitstreitern
hat. Vor der Einführung von RADIUS war teures Spezialequipment erforderlich, um User
zu authentifizieren. Es gab keinen Standard, sondern viele proprietäre Lösungen, und jede
hatte ihre eigenen Methoden, die Authentifikation durchzuführen. Die einen benutzten
CHAP (Challenge/Response Authentification Protocol), andere benutzten Profile und
wieder andere setzten auf SQL-Datenbanken. Das größte Problem dieses Durcheinanders
war schnell abzusehen: Die mangelnde Skalierbarkeit. AAA wurde von einer
Arbeitsgruppe der IETF definiert, um ein möglichst hohes Maß an Skalierbarkeit zu
erreichen und die oben genannten Probleme zu lösen. Es sollte möglich sein, in
vollkommen inhomogenen Umgebungen unterschiedlichste Dienste anzubieten und diese
getrennt abzurechnen. ISPs (Internet Service Provider) waren daran interessiert, neben
dem eigentlichen xDSL, ISDN oder Cable-Modem-Anschluss Zusatzdienste abzurechnen,
und das alles mit einem standardisierten Verfahren.
RADIUS
| 27
Diplomarbeit
Stefan Abu Salah
Nach einigen Jahren Entwicklung stand das Gerüst für AAA, welches alle diese Aspekte
berücksichtigen sollte.
5.1.1 Authentifikation
Authentifikation ist der Prozess, eine Person oder eine Maschine zu erkennen, um ihr
bestimmte Dienste einzuräumen und so die Möglichkeit der Abrechnung zu geben.
Authentifikation wird in den allermeisten Fällen in Form von UserID/Username in
Verbindung mit einem Passwort durchgeführt. Ist ein Passwort in falsche Hände gelangt,
so kann die Authentizität des Users nicht mehr sichergestellt werden, welhalb sich in
letzter Zeit, besonders in den Bereichen rund um den schnell wachsenden Markt des
eCommerce, ein Trend abgezeichnet hat, digitale Zertifikate als Bestandteil einer PKI
(Pulic Key Infrastructure) statt der Passwörter einzusetzen.
5.1.2 Authorisation
Zur Authorisation eines Users oder einer Maschine werden einige Bestimmungen oder
Templates genutzt, um gewisse Dienste freizuschalten. So ist es z.B. möglich,
unterschiedliche Bandbreiten bei xDSL-Anschlüssen freizuschalten oder bei gewissen
Anschlüssen eine statische IP zu vergeben, statt dies dynamisch per DHCP zu tun. So
genannte Smart-Implementations bieten zusätzlich die Option, anhand von intelligenteren
Algorithmen zu entscheiden, was einen sinnvollen Kompromiss zwischen dem
angefragten Dienst und den für den User freigeschalteten Diensten darstellt, ohne die
Anfrage einfach abzulehnen. So kann beispielsweise auf die Anfrage zur Nutzung von
beiden ISDN-Kanälen zur Kanalbündelung mit dem Freischalten nur eines Kanals
geantwortet werden, ohne die Verbindung generell zu unterbinden.
5.1.3 Accounting
Das Accounting dient der genaueren Aufschlüsselung der Dienste und Kapazitäten, die
ein User/eine Maschine während einer Session in Anspruch genommen hat. Für den
Accounting-Vorgang werden beispielsweise die Menge der übertragenen Daten
festgehalten, oder die Zeitpunkte zwischen dem Beginn und dem Ende der
Inanspruchnahme eines Dienstes. Die so erfassten Daten können dann beispielsweise der
RADIUS
| 28
Diplomarbeit
Stefan Abu Salah
Weiterverarbeitung zwecks individueller Inrechnungstellung zugeführt, oder auch für
statistische Zwecke und Analysen für die Kapazitätsplanung herangezogen werden.
5.2 FreeRADIUS
FreeRADIUS ist eine der populärsten Entwicklungen der Open-Source-Gemeinde. Das Ziel
dieser Entwicklung war es, einen kostengünstigen Radiusserver zu schaffen. Zu diesem
Zweck fanden sich viele Entwickler zusammen, hierunter viele Entwickler des Debian
GNU/Linux-Betriebssystems, und schufen eine funktionsreiche Software mit modularem
Aufbau unter dem Lizensmodell der GNU GPL12. FreeRADIUS wurde komplett neu
entwickelt, weist in der Konfiguration jedoch Parallelen zum alten Livingston-RADIUSServer auf. FreeRADIUS ist auf vielen Plattformen lauffähig, zu denen beispielsweise
Linux, FreeBSD, OpenBSD und Solaris gehören. Wärend der Entwicklung wurde
besonders auf soliden Aufbau und Sicherheit geachtet, was sich, trotz niedriger
Versionsnummern, im Produktiveinsatz in stabil laufenden Versionen bezahlt gemacht hat
und mit zur weiten Verbreitung von FreeRADIUS beigetragen hat.
5.3 Der SER und FreeRADIUS
Der SER kann, wie in Kapitel 4 bereits erwähnt, auf vielfältige Weise AAA ermöglichen.
Hierfür ist er jedoch auf die Hilfe externer Programme angewiesen. FreeRADIUS bietet
alle Komponenten für AAA und hat sich im professionellem Umfeld, insbesondere in der
Telekommunikationsbranche, durchgesetzt. Somit war es eine logische Konsequenz,
FreeRADIUS in dieser Arbeit für AAA einzusetzen.
12 Die GPL (GNU General Public License) erlaubt das Kopieren, Abändern und Verbreiten von Programmen und deren Quellcode.
RADIUS
| 29
Diplomarbeit
Stefan Abu Salah
6 MySQL
MySQL [sql] ist ein relationales Datenbankmanagementsystem. Relational bedeutet, dass
Daten nicht in einem einzigen großen Speicherraum verwaltet werden, sondern in
aufgeteilten,
kleineren
Datenbeständen
(Tabellen).
Diese
separaten,
kleineren
Datenbestände sind wesentlich besser handhabbar und dadurch viel performanter. Es
können Abfragen auf diese Datensätze durch definierte Relationen miteinander verknüpft
werden. SQL (Structured Query Language) ist die wichtigste Abfragesprache für solche
Datenbankzugriffe.
MySQL wird von dem kommerziellen Unternehmen MySQL AB entwickelt und zur
Verfügung gestellt. Dieses Unternehmen bietet Serviceleistungen rund um die MySQL –
Datenbank. MySQL ist seit Jahren OpenSource und benutzt die GPL (GNU General Puplic
License). Auch dieser Umstand hat zu der weiten Verbreitung und Unterstützung
beigetragen. MySQL ist sehr schnell, zuverlässig und bietet ausgereifte APIs13 (Application
Programming Interface) für alle gängigen Programmiersprachen.
MySQL kennt eine ganze Reihe unterschiedlicher Tabellentypen. Neben den schnellen,
unkomplizierten und Platz sparenden MyISAM-Tabellen kann man den Tabellentyp
InnoDB nutzen. InnoDB-Tabellen unterstützen zusätzlich ACID14-Transaktionen und
verteilen ihre Datenbestände auf mehrere Dateien. Die Möglichkeit, von Referenztabellen
und Versioning Gebrauch zu machen, ist ein weiterer positiver Aspekt dieses
Tabellentyps. InnoDB ist das derzeit schnellste im Markt verfügbare festplattenbasierte
Datenbanksystem.
Die Performance der MySQL-Datenbank läßt sich mittels vieler Parameter an die
Einsatzbedingungen anpassen. Beispielsweise kann definiert werden, wieviele Threads
sich um die Bearbeitung der ein- und ausgehenden Operationen bemühen und wie groß
die Puffer für häufig vorkommende Transaktionen bemessen werden sollen. [SQL]
13 Ein API (Application Programming Interface) ist eine, meist von einem Betriebssystem bereitgestellte, Programmierschnittstelle, die
es ermöglicht, auf Quellcode-Ebene Funktionen in eigene Programmcodes einzubetten.
14 Das Akronym ACID beschreibt erwünschte Eigenschaften von Transaktionen bei Datenbanken oder verteilten Systemen. Es steht
für Atomicity, Consistency, Isolation und Durability.
MySQL
| 30
Diplomarbeit
Stefan Abu Salah
6.1 MySQL – Grundlagen
MySQL ist von der UNIX-Shell aus bedien- und administrierbar und benötigt keine
grafischen Frontends. Somit ist auch die Administration der Datenbank über gesicherte
Zugänge, wie beispielsweise SSH15, von entfernten Rechnern möglich. Wichtig ist auch zu
erwähnen, dass die reibungslose Integration in die UNIX-Shell eine Vielzahl an
Möglichkeiten bietet. Hervorgehoben sei hier nur die Möglichkeit, Datenbankaktionen
jeder Art über Skripte ausführbar und automatisierbar zu machen.
Folgende Beispiele sollen anhand einiger grundlegender Aktionen den Umgang mit der
Skriptsprache über die Shell einen Überblick geben:
stefan@phil:~$ mysql -h localhost -u debian-sys-maint -p ↵
password: ***********
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 24 to server version: 4.0.24_Debian-2-log
Type 'help;' or '\h' for help. Type '\c' to clear the buffer.
mysql> SELECT VERSION(), CURRENT_DATE; ↵
+---------------------+--------------+
| VERSION()
| CURRENT_DATE |
+---------------------+--------------+
| 4.0.24_Debian-2-log | 2005-08-23
|
+---------------------+--------------+
1 row in set (0.02 sec)
mysql> USE tecon; ↵
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A
Database changed
mysql> SHOW TABLES; ↵
+-----------------+
| Tables_in_tecon |
+-----------------+
| adressen
|
| connection
|
| isps
|
+-----------------+
3 rows in set (0.01 sec)
15 SSH (Secure Shell) SSH ist sowohl ein Programm als auch ein Netzwerkprotokoll, mit dessen Hilfe man sich gesicherten Zugang z.B.
über das Internet auf einem entfernten Computer verschaffen kann. SSH2, der aktuelle Standard, verwendet AES mit einer
Schlüssellänge von 128Bit und kann somit als sicher eingestuft werden.
MySQL
| 31
Diplomarbeit
Stefan Abu Salah
mysql> DESCRIBE adressen; ↵
+---------+---------------+------+-----+---------+----------------+
| Field
| Type
| Null | Key | Default | Extra
|
+---------+---------------+------+-----+---------+----------------+
| index
| bigint(20)
|
| PRI | NULL
| auto_increment |
| time
| timestamp(14) | YES |
| NULL
|
|
| name
| varchar(50)
|
|
|
|
|
| vorname | varchar(50)
|
|
|
|
|
| strasse | varchar(50)
|
|
|
|
|
| hn
| varchar(10)
|
|
|
|
|
| plz
| varchar(10)
|
|
|
|
|
| ort
| varchar(50)
|
|
|
|
|
| plip
| varchar(20)
|
|
|
|
|
+---------+---------------+------+-----+---------+----------------+
9 rows in set (0.00 sec)
mysql> SELECT name,vorname,strasse,hn FROM adressen; ↵
+------------+-----------+----------------------+-----+
| name
| vorname
| strasse
| hn |
+------------+-----------+----------------------+-----+
| Müller
| Heinz
| Musterstrasse
| 13a |
| Mengenbach | Klaus
| Hauptstrasse
| 1
|
| Weiler
| Liselotte | Gertrudenallee
| 2
|
+------------+-----------+----------------------+-----+
3 rows in set (0.00 sec)
mysql> QUIT ↵
stefan@phil:~$ █
Diese Beispiele zeigen eine erfolgreiche Anmeldung als Benutzer debian-sys-maint an dem
mysql-Deamon, gefolgt von grundlegendsten Befehlen zur Betrachtung der vorhandenen
Tabellen und deren Inhalt. Die hier abgesetzen Befehle können ebenso in einem
Shellskript abgesetzt werden und werden dann nacheinander ausgeführt.
6.2 phpMyAdmin
Obwohl die Benutzung der Shell einige Vorteile hat, ist es doch angenehmer, wenn man
alltägliche Aufgaben über ein etwas eingänglicheres Interface erledigen kann.
phpMyAdmin ist eine PHP16-Applikation zur Administration von MySQL-Datenbanken. Die
Verwendung von PHP als Programmiersprache macht die Nutzung von phpMyAdmin über
16 PHP (früher: Personal HomePage Tools, heute Php Hypertext Preprocessor) ist eine serverseitig interpretierte Sprache zur
Generierung dynamischer Webseiten.
MySQL
| 32
Diplomarbeit
Stefan Abu Salah
HTTP mit jedem Browser, also auch über das Internet, möglich. Besonders vorteilhaft an
phpMyAdmin ist die Tatsache, dass der Administrator auch ohne das Absetzen
komplizierter SQL-Befehle die wichtigsten Aktionen mit wenigen Mausklicks erledigen
kann. phpMyAdmin ist, wie auch MySQL, unter der GPL verfügbar und kann somit
kostenfrei eingesetzt werden.
Folgende Bildschirmmitschnitte zeigen die einfach zu bedienende Oberfläche von
phpMyAdmin:
Abbildung 8 phpMyAdmin Ansicht des Tabelleninhalts
MySQL
| 33
Diplomarbeit
Stefan Abu Salah
7 Das TECON extended Mediation Device
In der IT-Landschaft fallen enorme Datenmengen an. Diese Daten gilt es, durch den
Einsatz von Software auszuwerten. Um eine sinnvolle Auswertung zu ermöglichen,
müssen die in vielfältiger Form anfallenden Daten durch Filtermechanismen auf
verarbeitbare Formate konvertiert werden. Wichtig ist es, sich den schnell entwickelnden
Datenformaten, -quellen und -schnittstellen flexibel anpassen zu können, und dies
möglichst schnell und kostengünstig. Genau diese Anforderungen erfüllt das T·XMD
(TECON eXtended Mediation Device). Durch die übersichtlich gestaltete und einfach zu
bedienende
grafische
Oberfläche
ist
das
T·XMD
schnell
an
veränderte
Rahmenbedingungen anpassbar. Eine besondere Stärke ist die Erweiterbarkeit des
T·XMD. Es ist möglich, eine Vielzahl von Plugins oder externe Komponenten in den
Verarbeitungsprozess mit einzubeziehen. Durch diesen Funktionsreichtum ist eine
optimale Aufbereitung und Anreicherung der anfallenden Daten jederzeit möglich.
Zusammenfassend lassen sich folgende Aufgaben für das Datenmanagement des T·XMD
nennen:

Sammeln aus verschiedenen Datenquellen mit beliebigen Formaten

Kontrollieren und Sichern der Daten

Konvertieren in beliebige Formate

Prozessierung, sowie Vor- und Nachbearbeitung

Datenanreicherung

Verteilung der Daten
Bedingt durch die Flexibilität und Erweiterbarkeit bringt das T·XMD für eine Vielzahl an
Einsatzfeldern alle relevanten Funktionalitäten mit und ist somit selbst kompliziertesten
Aufgaben in komplexen Netzwerken unterschiedlichster Systeme gewachsen. Dies
prädestiniert das T·XMD für den Einsatz in vielen Branchen. [TEC]
Das TECON extended Mediation Device
| 34
Diplomarbeit
Stefan Abu Salah
7.1 Architektur des T·XMD
Die folgende Abbildung zeigt den prinzipiellen Aufbau des T·XMD. Hier sind die
Kernkomponenten des T·XMD ersichtlich.
Distributor
Datapool
Converter
Filter
Provider
Datapool
Collector
Processing Unit
CORBA
Job Manager
Database Interface
Frontend
Abbildung 9 Aufbau des T·XMD
7.1.1 Collectoren
Das Sammeln der Daten aus verschiedenen Quellen übernehmen beim T·XMD die
Collectoren. Sie können parallel Anfragen an unterschiedlichste Systeme über diverse
Netze, z.B. IP-basierte Netzwerke, absetzen. Die Abfragen sind vom Benutzer frei
konfigurierbar
und
können
mit
diversen
zeitlichen
oder
eventbasierten
Steuerungsmethoden automatisiert werden. Die übermittelten Daten werden in einem
internen Format zwischengespeichert und stehen dann der weiteren Verarbeitung zur
Verfügung. Es stehen folgende Übertragungsprotokolle zur Verfügung:
Das TECON extended Mediation Device
| 35
Diplomarbeit
Stefan Abu Salah

Filebasiert

FTAM17 gemäß ISO8571

FTP18
Werden weitere Protokolle benötigt, können diese über ein PlugIn-System integriert
werden. Es ist außerdem möglich, die eingegangenen Daten einer Archivierung zu
unterziehen und so die Datensicherheit zu erhöhen. Diese Backups können auf vielfältigen
Medien, bzw. Bandlaufwerken oder einfach als Kopie, in einem dafür vorgesehen Ordner
abgelegt werden.
7.1.2 Processing Unit
Die Processing Unit übernimmt die Verarbeitung der Inhalte des Datenpools und leitet
diese an Filter und verschiedene Prozesse weiter. Für die weitere Verarbeitung ist es
erforderlich, die aus dem Datenpool gelesenen Rohdaten in das interne Format des
T·XMD zu überführen. Hierzu unterstüzt das T·XMD frei konfigurierbare Konverter,
welche sowohl ASCII19- als auch binäre Formate umwandeln können.
Prozesslogiken können mit einer, syntaktisch an Java/C++ erinnernde, Skriptsprache
programmiert werden. Diese flexible Skriptsprache macht die Definition beliebig
komplexer Konfigurationsprozesse möglich. Da die so definierten Prozessketten beim
Start kompiliert werden, sind sie in hohem Maße performant und bleiben trotzdem
flexibel.
Die durch die Skriptsprache zugänglichen Funktionen können jederzeit durch externe
Module und Skripte erweitert werden. Es ist an dieser Stelle außerdem problemlos
möglich, die aus dem Datenpool geholten Informationen mit Daten anzureichern, indem
man externe Schnittstellen, wie diese beispielsweise Datenbanken bieten, nutzt. Auf diese
Weise steht eine Vielzahl an Erweiterungsmöglichkeiten bereit.
17 File Transfer and Access Management (FTAM) ist ein standardisiertes Datenkommunikations-Protokoll für den Filetransfer. FTAM
ermöglicht insbesondere im Zahlungsverkehr einen sehr grossen Aktionsumfang, der weit über das klassische Online-Banking
hinaus geht.
18 File Transfer Protokoll (FTP) ist ein in RFC 959 definiertes Dateiübertragungsprotokoll für IP-Netzwerke.
19 American Standard Code for Information Interchange (ASCII) definiert die Zuordnung von digital dargestellten Ganzzahlen zu den
in der normalen Schriftsprache geschriebenen Zeichen.
Das TECON extended Mediation Device
| 36
Diplomarbeit
Stefan Abu Salah
Abbildung 10 Konfiguration der Prozesslogik des T·XMD
7.1.3 Distributoren und Converter
Um die Daten in ein beliebiges Ausgabeformat umzuwandeln und zu verteilen, bringt das
T·XMD Distributoren und Converter mit. Diese auf vielfältige Weise konfigurierbaren
Converter reichern bei Bedarf die Daten mit zusätzlichen, für die Weiterverarbeitung
wichtigen Informationen an und stellen diese im Datenpool zur Verfügung. Folgesysteme
(beispielsweise das Billingsystem) können sich aus diesem Pool bedienen.
Das TECON extended Mediation Device
| 37
Diplomarbeit
Stefan Abu Salah
7.1.4 Job Manager
Der Job Manager ist die zentrale Steuerungseinheit des T·XMD. Er kommuniziert mit den
einzelnen Komponenten des T·XMD über die Kommunikationsschnittstelle CORBA20 und
bietet eine persistente Speicherung der Daten in eine SQL-Datenbank.
7.1.5 Frontend
Die grafische Oberfläche (Frontend) führt den Benutzer intuitiv durch das T·XMD. Als
zusätzliche Hilfe beantwortet das elektronische Benutzerhandbuch eventuell auftretende
Fragen und verschafft schnell einen Überblick über die vielfältigen Möglichkeiten des
T·XMD.
Abbildung 11 Das Frontend des T·XMD
20 Die Common Object Request Broker Architecture (CORBA) ist eine nicht an eine Programmiersprache gebundene Middleware, die
plattformübergreifende Protokolle und Dienste definiert. CORBA wird von der Object Management Group (OMG) entwickelt und
vereinfacht das Erstellen verteilter Anwendungen in heterogenen Umgebungen.
Das TECON extended Mediation Device
| 38
Diplomarbeit
Stefan Abu Salah
Das Frontend bietet alle Schnittstellen zur Konfiguration und Administration des T·XMD
und bietet volle Kontrolle über Collectoren, Prozessoren und Distributoren. So ist es
möglich, alle Prozesse über die Benutzeroberfläche einzusehen, zu ändern oder neue
Prozesse zu erstellen. Außerdem lassen sich alle wichtigen Informationen über den
Betriebszustand abrufen.
7.2 Rating
Das Rating nimmt die vom T·XMD gelieferten, formatierten Gebrauchsdaten entgegen
und ordnet diese den verursachenden Benutzern zu. Des Weiteren werden zusätzliche
Daten ermittelt, welche für eine spätere Abrechnung benötigt werden. Hierzu gehören:

Zuordnung des Tarifes mit konfigurierbaren zusätzlichen Bedingungen (Quality of
Service, übertragenes Volumen, etc.)

Tarifierung von IN-Diensten und Value-Added-Services (Dienste wie beispielsweise VPNs
und ”Shared Cost Services”)

Ermittlung der Kundenhirarchien und ”Cost Responsibilities”

Provisionierung
Mit dem TECON-Rating lassen sich nicht nur Telefonietarifmodelle, sondern jede Art von
Datendiensten abbilden und ins Billing übertragen. Durch die flexible Schnittstelle und
den mächtigen Funktionsumfang lassen sich schnell und unkompliziert selbst
anspruchsvolle Tarifmodelle umsetzen.
7.3 TECON Billing Solution
Die TECON Billing Solution ist das letzte Glied in der Verarbeitungskette des T·XMD. Hier
werden die vom Rating angereicherten Informationen aufbereitet und in Form von
Rechnungsdokumenten in einer grafischen Benutzeroberfläche bereitgestellt. Es ist hier
auch möglich, neue Produkte, Preis- oder Rabattänderungen einzugeben. Die TECON
Billing Solution ermöglicht es, eine ganze Reihe zusätzlicher Modelle zu definieren, wie
beispielsweise Aufpreise, Gutschriften oder diverse Rabattmodelle. Sind alle Daten
aufbereitet, kann die TECON Billing Solution Rechnungen in verschiedensten Formen und
Formaten, insbesondere in gedruckter Form, elektronisch, oder für die Ausgabe im
Internet optimiert, ausgeben.
Das TECON extended Mediation Device
| 39
Diplomarbeit
Stefan Abu Salah
8 Das GeoVIPA-Konzept
GeoVIPA
(Geographische
Verzonung
von
VoIP
zur
Authentifizierung
der
Verkehrsursprünge zur Abrechnung und Erkennung von Verbindungsursprüngen für
Notrufe und Mehrwertdienste) wird von den Firmen TECON und WeyTeCon entwickelt.
[GEO]
IP-Network (national)
International VoIP
traffic (incoming)
International VoIP
traffic (outgoing)
National ISP
originating
National ISP
terminating
local ISP
(e.g. ”local area
carrier”) originating
local ISP
(e.g. ”local area
carrier”) terminating
PSTN (national)
”long distance
carrier” selected
via Call-by-Call
”long area
carrier”
originating
GW (CCS7->IP)
GW (IP->CCS7)
”long area
carrier”
terminating
CCS7: NAT 1 area
PSTN (international)
International
traffic
(incoming)
CCS7 GW
(INTO->NATO/1)
CCS7 GW
(INTO->NATO/1)
International
traffic
(outgoing)
CCS7: INTO area
Abbildung 12 Integration von VoIP in das PSTN
Das Ziel dieser Entwicklung war die Schaffung eines Systems zur Realisierung von bisher
nur aus dem PSTN bekannten Diensten und Einsatzmöglichkeiten. Die wichtigsten Punkte
sind:

Lokalisierung der Gesprächspartner für die Realisierung von entfernungsbasierten
Tarifsystemen und zur gesetzeskonformen Umsetzung von Not- und Röchelrufen, die
Das GeoVIPA-Konzept
| 40
Diplomarbeit
Stefan Abu Salah
eine Bestimmung des Ursprungs eines Anrufs voraussetzen

Schaffung von Abhörmechanismen (für Bedarfsträgeranfragen)

Abrechnung des genutzten Datenvolumens

Abrechnung von Mehrwertdiensten

Nutzung gängiger Abrechnungssysteme

Nahtlose Integration in das besthende PSTN
GeoVIPA soll sich nahtlos in die bestehenden PSTN-Infrastrukturen einbinden lassen und
mindestens die aus dem PSTN bekannten Möglichkeiten bieten. Zusätzlich ist die
Zuweisung von Mehrwertdiensten abhängig vom Nutzer vorgesehen und dies
vollkommen gelöst von der physikalischen Adresse des verwendeten Anschlusses. Auch
soll es mit GeoVIPA möglich sein, von jedem beliebigen Internetanschluss das eigene
VoIP-Telefon zu benutzen und trotzdem Bedarfsträgeranfragen zu erlauben.
GeoVIPA sieht die Zuweisung einer IPv621-Adresse [IPv6] zu jeder Rufnummer vor. Diese
IPv6-Adresse identifiziert den dieser Rufnummer zugeordneten Nutzer eindeutig, und
wird CHIP (Charging IP) genannt. Die Lokalisierung wird ausschließlich über die
physikalische IP-Adresse, also der vom Netzbetreiber vergebenen Anschlussadresse,
realisiert. Hierfür ist in der ursprünglichen Fassung eine IPv6-Adresse vorgesehen, welche
einen LAC (Local Area Code) mit Informationen über den Bezirk des Anschlusses enthält.
Der LAC lehnt sich an die vom Ortsnetz bekannten Vorwahlen im PSTN an.
Da die Umstellung von IPv4 auf IPv6 jedoch noch einige Jahre dauern kann ist es
vorgesehen eine Abbildung der dem VoIP-Telefon vom Netz zugeordneten IPv4-Adresse
auf eine beim Provider geführten IPv6-Adresse zu realisieren. Diese IPv6-Adresse wird
beim Provider als CHIP geführt und ist der Rufnummer fest zugeordnet.
Der IP-DNA nimmt eine zentrale Rolle im Konzept von GeoVIPA ein. Er vereint je nach
Ausbaustufe
einen
SIP-Server,
einen
SIP-Proxy,
und
bietet
Schnittstellen
für
Abrechnungssysteme und zur Lokalisierung der Nutzer. Der IP-DNA bietet außerdem AAA
und ersetzt so die bisher hierfür vorgesehenen Systeme. Auf nationaler Ebene ist ein
ROOT-IP-DNA
vorgesehen,
welcher
Bedarfsträgeranfragen
bearbeitet
und
Lokalisierung für Not- und Röchelrufe durchführt.
21 IPv6 (Internet Protocol Version 6) ist die Weiterentwicklung der bisherigen Version 4 und bietet
Das GeoVIPA-Konzept
| 41
die
Diplomarbeit
Stefan Abu Salah
8.1 Umsetzung des GeoVIPA Konzeptes
Da GeoVIPA stark auf dem Vorhandensein von IPv6-Netzwerken beruht, mussten für die
Umsetzung der Ziele dieser Diplomarbeit einige Änderungen am Konzept von GeoVIPA
vorgenommen werden. In zukünftigen Weiterentwicklungen ist die schrittweise
Annäherung an GeoVIPA jedoch möglich.
Da keine IPv6-Adressen mit LAC zur Verfügung stehen, muss für die Lokalisierung eine
andere Lösung gefunden werden. Das in dieser Diplomarbeit entwickelte Konzept sieht
vor, dass jeder ISP eine Adress-Datenbank führt. Diese Datenbank muss alle zur
Lokalisierung der Kunden benötigten Informationen, verknüpft mit der IP-Adresse des
Anschlusses (PLIP) des Kunden, enthalten. Da die IP-Adressen nicht statisch einem
bestimmten Kunden zugeordnet sind, müssen Start- und Endzeitpunkt der IP-Zuweisung
hinterlegt werden. Die Verknüpfung der Adress- und der IP-Daten kann beim ISP in
beliebiger Form erfolgen. Die Abfrage der Lokalisierungsdaten ist von jedem ISP frei
definierbar und kann bei jedem Provider anders aussehen.
ISPDatenbank
Adressdatenbank
Provider 1
Teilnehmer A
SIP-Server
ISP 1
Internet
ISP 2
ISP 3
Adressdatenbank
Provider 3
Teilnehmer B
Adressdatenbank
Provider 2
Teilnehmer C
Abbildung 13 Übersicht der Komponenten zur Lokalisierung
Das GeoVIPA-Konzept
| 42
Diplomarbeit
Stefan Abu Salah
Da nicht klar ist, welchem ISP die ermittelte PLIP zugeordnet werden kann, muss eine ISPDatenbank die den ISPs zugehörigen IP-Bereiche enthalten. Fällt nun eine PLIP in den
Bereich eines bestimmten ISPs, kann die Adressabfrage bei diesem ISP abgesetzt werden.
Die
ISP-Datenbank
sieht
neben
den
IP-Bereichsgrenzen
Felder
für
den
Dienstanbieternamen, den Host und die für die Verbindung zur Adressdatenbank
benötigten Variablen (Passwort, Benutzernamen etc.) vor. Außerdem ist ein Feld mit dem
zum Absetzen einer Adressdatenbankabfrage benötigten SQL-Befehl vorhanden.
Nach der Abfrage der Adressdatenbank stehen die benötigten Daten der Teilnehmer
sowohl dem Notrufsystem als auch zu Abrechnungszwecken zur Verfügung. In diesem
Konzept wird vorausgesetzt, dass alle ISPs eine solche Datenbank realisieren.
Das GeoVIPA-Konzept
| 43
Diplomarbeit
Stefan Abu Salah
9 Notwendige Erweiterungen im SER
Um die Ziele dieser Diplomarbeit zu erreichen, war es nötig, Änderungen am Quellcode
des SER vorzunehmen. Diese Änderungen sollen sich nahtlos in die Quelltexte des SER
eingliedern und möglichst den Originalquellcode nicht verändern, sondern nur ergänzen.
Ein weiteres Ziel ist die Erhaltung der hohen Performance des SER [ser].
9.1 Analyse der SIP-Messages
Eine wichtige Aufgabe war die Analyse der Originalquelltexte. Es galt, möglichst viele
Informationen über eingehende und ausgehende SIP-Messages zu erhalten. Es stellte sich
schnell heraus, dass die Analyse dieser Messages der Schlüssel für die Umsetzung ist, da
sie die wichtigsten Gesprächsparameter enthalten.
Als geeigneter Ort des Abgreifens hat sich die Quelltextdatei msg_parser.c herausgestellt.
Hier lassen sich sämtliche SIP-Nachrichten abgreifen. Der folgende Codeausschnitt zeigt
das Übergeben der SIP-Nachricht an den für die Erweiterung zuständigen Code:
/* returns 0 if ok, -1 for errors */
int parse_msg(char* buf, unsigned int len, struct sip_msg* msg)
{
...
/*find first Via: */
first_via=0;
second_via=0;
if (parse_headers(msg, flags, 0)==-1) goto error;
/*
/*
/*
/*
/*
######## ERWEITERUNG LOKALISIERUNG ########
#
Diplomarbeit
#
#
Stefan Abu Salah 11.06.2005
#
###########################################
#
# Abgreifen der SIP-Nachrichten
#
###########################################
*/
*/
*/
*/
*/
if( loc_get_msg(msg) )
DBG("loc_get_msg: failed\n");
/* ########## ENDE DER ERWEITERUNG ########### */
#ifdef EXTRA_DEBUG
Notwendige Erweiterungen im SER
| 44
Diplomarbeit
Stefan Abu Salah
/* dump parsed data */
if (msg->via1){
...
Die Funktion loc_get_msg() nimmt einen Zeiger auf die Struktur sip_msg entgegen. Diese
Struktur enthält alle Informationen der verschickten SIP-Nachrichten. Im Falle eines
Fehlschlagens der Verarbeitung wird ein Eintrag in der vom SER geführten DebugAusgabe erzeugt. Dies soll eine eventuell nötige Fehleranalyse erleichtern.
Die Funktion loc_get_msg() prüft nun, um was für eine SIP-Meldung (INVITE, BYE, OK,
u.s.w.) es sich handelt. Nach dieser Eingruppierung der entgegengenommenen Nachricht
folgt deren Analyse.
int loc_get_msg( struct sip_msg* msg )
{
...
if( strstr(msg->first_line.u.request.method.s,"BYE") != NULL
&& strstr(msg->first_line.u.request.method.s,"OK") == NULL
&& strstr(msg->first_line.u.request.method.s,"REGISTER") ==
NULL )
{
// Auslesen der Header Informationen
call = loc_analyse_msg( msg );
...
Die Funktion loc_analyse_msg() bekommt den erforderlichen Zeiger weitergereicht und
kann mit der Analyse beginnen. Alle zur Weiterverarbeitung benötigten Daten werden in
einer hierfür angelegten Struktur abgelegt. Es kommen zu den aus den reinen SIPNachrichten auszulesenden Informationen noch die IPs der Gesprächspartner (also die
PLIPs) und die für die Zeiterfassung benötigten Werte hinzu. Die Daten müssen anhand
der in RFC2543 definierten SIP-Felder ausgewertet weden. Dies übernimmt die Funktion
loc_get_msg_item(). Gibt man dieser den Zeiger auf die SIP-Nachricht sowie einige
Marker zur Bestimmung des einzulesenden Datenfeldes, so bekommt man wiederum
einen Zeiger auf den Ergebniswert, beispielweise einen Zeiger auf die CallID, zurück. Auf
diese Weise werden sämtliche relevanten Felder der SIP-Nachricht ausgelesen.
Notwendige Erweiterungen im SER
| 45
Diplomarbeit
Stefan Abu Salah
// Struktur zur Aufname der Gesprächsdaten
struct loc_csv {
int sip_code;
char acct_status_type[ACCT_STATUS_TYPE],
start_time[TIMESTAMP],
end_time[TIMESTAMP],
start_realtime[REALTIME],
end_realtime[REALTIME],
calling_station_id[CALLING_STATION_ID],
aplip[PLIP],
bplip[PLIP],
dstip[PLIP],
ch_ip[CHIP],
called_station_id[CALLED_STATION_ID],
audio_codec[AUDIO_CODEC],
acct_session_id[ACCT_SESSION_ID],
session_status[SESSION_STATUS],
totag[ACCT_SESSION_ID],
fromtag[ACCT_SESSION_ID],
service_type[SERVICE_TYPE],
aname[NAME],
avorname[VORNAME],
astrasse[STRASSE],
ahn[HN],
aort[ORT],
aplz[PLZ],
azusatz[ZUSATZ],
bname[NAME],
bvorname[VORNAME],
bstrasse[STRASSE],
bhn[HN],
bort[ORT],
bplz[PLZ],
bzusatz[ZUSATZ];
};
Der Rückgabewert der Funktion loc_analyse_msg() ist ein Zeiger auf diese Struktur.
Notwendige Erweiterungen im SER
| 46
Diplomarbeit
Stefan Abu Salah
9.1.1 Vorgehen beim Eintreffen einer INVITE-Message
Beim Eintreffen einer INVITE-Message werden die relevanten Daten mit einem INSERT in
die Datenbank geschrieben. Dieser erste Gesprächsdatensatz enthält bereits viele
wichtige Informationen über das vom A-Teilnehmer angefragte Gespräch, jedoch noch
keine Informationen über den B-Teilnehmer. Diese stehen erst nach dem Eintreffen der
OK-Message, also dem Entgegennehmen des Gesprächs durch den B-Teilnehmer, zur
Verfügung und können später in den bereits angelegten Datensatz eingefügt werden.
Es muß außerdem beachtet werden, dass das SDP–Protokoll INVITE-Messages zum
Ändern der Gesprächsparameter nutzt. Diese Meldungen unterscheiden sich nicht von
den INVITE-Messages, die dem Initiieren eines Gesprächs dienen. Hier muss also
unterschieden werden, ob es sich bei dieser Message um einen neuen Gesprächswunsch
handelt, oder nur eine Änderung der Parameter des bereits laufenden Gesprächs
gewünscht ist. Die Lösung dieses Problems besteht darin, bei jedem Eintreffen einer
INVITE-Message in der Datenbank nachzusehen, ob bereits ein Eintrag mit identischer
CallID vorhanden ist. Ist dies der Fall, muß es sich um ein SDP-Paket handeln und kein
neuer Eintrag in die Datenbank eingefügt werden.
Der folgende Codeausschnitt zeigt die Umsetzung der Analyse am Beispiel des Filters für
INVITE-Messages:
...
//Ist bereits eine INVITE-Verbindung mit dieser call_id vorhanden?
if( (sql_answer = loc_sqlquer(sdp_query,HOST,USER,PASSWORD,DBASE))
!= NULL )
// SDP-Message
strcpy(call->acct_status_type,"SDP");
else
// 1. INVITE-Message
strcpy(call->acct_status_type,"FAILED");
// Abfrage der Adressdaten des A-Teilnehmers über den Provider
// Rückgabe: Zeiger auf char[], Format: csv
address = loc_get_isp( call );
if( address != NULL )
{
// Auswerten der Adressdaten und Speichern dieser Werte
...
Notwendige Erweiterungen im SER
| 47
Diplomarbeit
Stefan Abu Salah
9.1.2 Vorgehen beim Eintreffen einer OK-Message
In der OK-Message sind alle Informationen über den B-Teilnehmer enthalten. So lassen
sich die PLIP des B-Teilnehmers bestimmen und die Startzeit des Gesprächs festsetzen.
Des Weiteren enthält die OK-Message die ausgehandelten Codecs. Die in der OK-Message
mitgesendeten Codecs sind das Resultat des Absprechens der beteiligten UACs und
werden für das Gespräch benutzt. Für eine spätere Abrechnung des durch die
Kommunikation
erzeugten
Datenvolumens,
oder
beispielsweise
der
getrennten
Abrechnung von Videotelefonie, sind die verwendeten Codecs interessant.
Die in der OK-Message gesammelten Daten werden in den bereits erzeugten Datensatz
eingefügt und komplettieren den Verbindungsaufbau. Ab diesem Zeitpunkt gilt das
Gespräch als zustandegekommen und kann abgerechnet werden.
9.1.3 Vorgehen beim Eintreffen einer BYE-Message
Beim Eintreffen einer BYE-Message wird das Gespräch als beendet angenommen und
somit der Endzeitpunkt dieses Gesprächs in der Datenbank auf den aktuellen Wert
gesetzt.
9.1.4 Vorgehen beim Eintreffen sonstiger SIP-Messages
Andere SIP-Messages beinhalten keine, oder keine neuen, für die Lokalisierung oder
Abrechnung benötigten Daten. In den Erweiterungen hat die Auswertung dieser
Messages eine reine Kontrollfunktion. Das Mitschneiden dieser Messages macht die
Fehleranalyse einfacher, weshalb es auch für diese Messages Analysecontainer gibt.
9.2 Lokalisierung
Die Lokalisierung wird alleine über die Anschlussadressen (PLIP) der Teilehmer
vorgenommen. Das Konzept sieht hierfür zwei getrennte Schritte vor.
Im ersten Schritt muss ermittelt werden, bei welchem ISP die PLIP gemeldet ist. Hierfür ist
die ISP-Datenbank abzufragen. In dieser Datenbank stehen die den unterschiedlichen ISPs
zugeordneten IP-Bereiche verknüpft mit Abfragedaten, welche für die Abfrage der
Adressdatenbank
benötigt
werden.
Hierzu
gehören
Authentisierungs-
Notwendige Erweiterungen im SER
| 48
und
Diplomarbeit
Stefan Abu Salah
Verbindungsdaten der bei dem ISP stehenden Adressdatenbank, sowie ein fertiger SQLBefehl, mit welchem eine genaue Lokalisierungsabfrage möglich ist. Das Mitsenden eines
kompletten SQL-Befehls hat den großen Vorteil, dass die ISPs ihre Adressdatenbank
beliebig gestalten können. Sie müssen nur ihren Eintrag in der ISP-Datenbank
entsprechend anpassen. Die einzige Voraussetzung ist, dass das Rückgabeformat
eingehalten wird. Folgende Abbildung zeigt die hier benutzte Datenbanktabelle. Sie
enthält die benötigten Felder zur Bestimmung des ISPs anhand einer IP:
ISP-Datenbank
ISPs
FromIP
ToIP
code
Orgaisation
URL
User
Password
Database
Query
Der Adressbereich des ISP beginnt hier
Der Adressbereich des ISP endet hier
Wert für Netzmaske
Name des ISP
Internetadresse der Adressdatenbank
Datenbank Username
Passwort zur Authentisierung
Abzufragende Databank
Enthält die genaue SELECT-Abfrage für
die Adressdatenbank
Abbildung 14 Modell der ISP-Datenbank
Diese Lokalisierungsabfrage ist Teil des zweiten Schrittes. In diesem wird die erhaltene
SQL-Abfrage an die Adressdatenbank des betroffenen ISP abgesetzt. Die Rückgabe muss
nun die genaue Adresse des Teilnehmers enthalten. Die Lokalisierung des Teilnehmers ist
hiermit abgeschlossen.
Notwendige Erweiterungen im SER
| 49
Diplomarbeit
Stefan Abu Salah
Adressdatenbank
IPs
n
IP
starttime
endtime
KdNr (FKey)
hat
m
Kunden
KdNr (PRIK)
Name
Vorname
...
Abbildung 15 Modell der Adressdatenbank des ISP
Der prinzipielle Aufbau der Adressdatenbank des ISP ist in untenstehender Abbildung
gezeigt. Da die Adressdaten von jedem Provider in einer dafür vorgesehenen Datenbank
abrufbar geführt werden müssen, die Provider jedoch unterschiedlichste Verfahren und
Datenquellen nutzen, kann diese Datenbank bei jedem Provider anders aussehen.
Zur Veranschaulichung der zur Lokalisierung benötigten Schritte zeigt die nächste
Abbildung einen beispielhaften Ablauf eines regulären VoIP-Telefonats.
Notwendige Erweiterungen im SER
| 50
Diplomarbeit
Stefan Abu Salah
SIP-Server
Adressdatenbank
Provider 1
ISPDatenbank
A
Adressdatenbank
Provider 2
B
INVITE
Trying
INVITE
Welchem
Provider
gehört
die A-PLIP?
Provider 1
SQL-Daten
Schritt 1
Abfrage der
Adressdaten zu PLIP A
Schritt 2
Rückgabe der
Adressdaten von A
Ringing
OK
Ringing
OK
Welchem
Provider
gehört
die A-PLIP?
Provider 2
SQL-Daten
Schritt 1
Abfrage der
Adressdaten zu PLIP B
Rückgabe der
Adressdaten von B
OK
ACK
Austausch der Gesprächsdaten
x
t
BYE
Schritt 2
BYE
OK
ACK
Abbildung 16 Veranschaulichung der Lokalisierung
Notwendige Erweiterungen im SER
| 51
Diplomarbeit
Stefan Abu Salah
9.3 Erzeugen der Call Detail Records
Zur Weiterverarbeitung ist die Speicherung der Call Detail Records (Gesprächsrohdaten)
notwendig. Dieses kann in diversen Formaten erfolgen. Die für die Weiterverarbeitung
wichtigen Call Detail Records werden in zwei Formen gespeichert. Das primäre
Speichermedium ist eine MySQL-Datenbank. Sie bietet einige große Vorteile. Zum einem
ist die Datenspeicherung persistent, zum anderen lässt sie sich flexibel erweitern.
Zusätzlich werden alle Daten auch in ein CSV-File (siehe Kapitel 9.3.1) geschrieben. Auf
diese Weise liegen die Informationen redundant vor und können von vielen Programmen
für die Weiterverarbeitung herangezogen werden.
9.3.1 CDR im CSV-Format
Ein gängiges Format zur Speicherung von einfach strukturierten Daten ist das CSVFormat. CSV steht für Character Separated Values, da die einzelnen Werte durch ein
spezielles Trennzeichen getrennt werden. Als Trennzeichen sind neben Komma auch
Semikolon, Doppelpunkt, Tabulator und andere Zeichen üblich, in der Regel werden
einzelne Datensätze durch einen Zeilenumbruch abgeschlossen. Es existiert jedoch kein
allgemein verbindlicher Standard für das Dateiformat.
In CSV-Format können Tabellen und Listen abgebildet und selbst komplizierte
Datenstrukturen durch zusätzliche Regeln oder mit Hilfe von XML abgespeichert werden.
Das folgende Beispiel veranschaulicht den Aufbau eines CSV-Files:
Hans;Müller;Hauptstraße;1;53639;Königswinter;
Eva;Meyer;Nebenstraße;43b;50679;Köln;
Manfred;Schuster;Feldweg;80a;53127;Bonn;
Ist ein Datensatz vollständig, ist also ein Gespräch zustandegekommen und die
Lokalisierung abgeschlossen, werden die gesammelten Daten in ein CSV-File geschrieben.
Die Daten hierfür werden aus dem primären Speichermedium, der MySQL-Datenbank,
geholt und der Funktion loc_csv() übergeben. Diese speichert diesen, sich bereits im CSVFormat befindlichen String in eine Datei. Der Dateiname setzt sich aus dem Wort detail,
gefolgt von dem aktuellen Datum in der Form YYYYMMDD zusammen. Auf diese Weise
Notwendige Erweiterungen im SER
| 52
Diplomarbeit
Stefan Abu Salah
wird für jeden Tag ein neues File angelegt.
...
// Erzeugen eines csv - Eintrags
sql_answer = loc_sqlquery(csv_query,HOST,USER,PASSWORD,DBASE);
strcpy(tmp,sql_answer);
loc_csv( tmp );
...
void loc_csv( char item[] )
{
FILE *csv;
char item_str[10000] = "";
char csvpath[1000] = "/usr/local/var/log/ser/csv/detail-";
char tmp[1000] ="";
strcpy(tmp,loc_realtime("%Y%m%d"));
strcat(csvpath,tmp);
strcat(csvpath,".csv");
strcpy(item_str,item);
item_str[strlen(item_str)] = '\n';
//strcat(item_str,'\n');
csv = fopen(csvpath,"a+");
if( csv==NULL )
{
return;
}
fprintf(csv,"%s",item_str);
fclose(csv);
}
...
9.3.2 CDR in MySQL
Wie bereits erwähnt, dient eine MySQL-Datenbank als primäres Speichermedium zur
Aufnahme der CDRs. In den Erweiterungen wurde die standard MySQL-C-API eingesetzt,
um
den
Datentransfer
zwischen
SER
und
MySQL
herzustellen.
Für
den
Verbindungsaufbau wurde die Funktion loc_sqlquery() implementiert, die vollständige
SQL-Befehle entgegennimmt und diese auf eine im Vorherein definierte Datenbank
Notwendige Erweiterungen im SER
| 53
Diplomarbeit
Stefan Abu Salah
absetzt. Der folgende Ausschnitt zeigt den für den Verbindungsaufbau zuständigen CCode:
char *loc_sqlquery( char query[],char url[], char user[], char pw[],
char dbase[] )
{
MYSQL *sql;
MYSQL_RES *result;
MYSQL_ROW row;
int count = 0, i = 0;
char *answer = NULL;
...
// Initialisierung der SQL Verbindung
sql = mysql_init(NULL);
#ifdef SQL_QUERY_LOG
loc_logfile(query);
#endif
if( sql == NULL )
return NULL;
// Verbindung mit dem Server wird aufgebaut ...
if( mysql_real_connect(sql,url,user,pw,dbase,PORT,SOCKET,FLAG ) ==
NULL )
{
// Trennen der Verbindung
answer = mysql_error(sql);
strcpy(tmp,answer);
loc_logfile(answer);
mysql_close(sql);
return NULL;
}
...
Diese Funktion wertet die ihr übergebene SQL-Anfrage aus und ist in der Lage, zwischen
einem SELECT, UPDATE, DELETE oder INSERT zu unterscheiden. Alle gängigen SQLBefehle können so über diese eine Funktion abgesetzt werden, ohne dass hierfür andere
Funktionen definiert werden müssen. Folgende Tabelle zeigt die zur Aufnahme der CDRs
verwendeten Datenfelder der MySQL-Tabelle:
Notwendige Erweiterungen im SER
| 54
Diplomarbeit
Stefan Abu Salah
Feld
acct_status_type
start_time
end_time
start_realtime
end_realtime
calling_station_id
aplip
bplip
dstip
ch_ip
called_station_id
audio_codec
acct_session_id
session_status
totag
fromtag
service_type
sip_code
aname
avorname
astrasse
ahn
aort
aplz
azusatz
bname
bvorname
bstrasse
bhn
bort
bplz
bzusatz
Typ
varchar(100)
varchar(20)
varchar(20)
varchar(20)
varchar(20)
varchar(100)
varchar(20)
varchar(20)
varchar(20)
varchar(20)
varchar(100)
varchar(100)
varchar(100)
varchar(100)
varchar(100)
varchar(100)
varchar(50)
int(11)
varchar(100)
varchar(100)
varchar(100)
varchar(10)
varchar(100)
varchar(10)
varchar(200)
varchar(100)
varchar(100)
varchar(100)
varchar(10)
varchar(100)
varchar(10)
varchar(200)
Beschreibung
Feld zur Aufnahme des Status-Typs (BYE, etc.)
Beginn des Telefonats (UNIX Timestamp)
Ende des Telefonats (UNIX Timestamp)
Beginn des Telefonats (YYYYMMDDhhmmss)
Ende des Telefonats (YYYYMMDDhhmmss)
URI des A-Teilnehmers
PLIP des A-Teilnehmers
PLIP des B-Teilnehmers
IP des Registrars
Charging IP des A-Teilnehmers
URI des B-Teilnehmers
Verwendeter Audiocodec
Identifizierer des Gesprächs (CallID)
Statusflag der Session
Zusätzliche ID des Gesprächs
Zusätzliche ID des Gesprächs
Vom UAC frei belegbares Feld
SIP - Code
Nachname des A-Teilnehmers
Vorname des A-Teilnehmers
Straße des A-Teilnehmers
Hausnummer des A-Teilnehmers
Wohnort des A-Teilnehmers
Postleitzahl des A-Teilnehmers
Adresszusatz des A-Teilnehmers
Nachname des B-Teilnehmers
Vorname des B-Teilnehmers
Straße des B-Teilnehmers
Hausnummer des B-Teilnehmers
Wohnort des B-Teilnehmers
Postleitzahl des B-Teilnehmers
Adresszusatz des B-Teilnehmers
Tabelle 6 CDR in MySQL
Notwendige Erweiterungen im SER
| 55
Diplomarbeit
Stefan Abu Salah
9.4 Performance und Stabilität
Eine große Herausforderung war es, die hohe Stabilität des SER durch die Erweiterungen
nicht zu verschlechtern. Insbesondere die von den IP-Telefonen unterschiedlich
ausgelegten SIP-Meldungen machten es schwer, die Filter stabil lauffähig zu bekommen.
Hier gab es beim Testen des Öfteren Überraschungen. Die Snom-Serie war erst nach
einem Firmwareupdate zu standardgerechtem Layout der Messages zu überreden und
brachte vorher den SER zum Absturz. Die vorliegende Lösung läuft auf allen hier
getesteten IP-Telefonen und Softphones stabil. Folgende Tabelle zeigt die verwendeten IPTelefone.
Hersteller
Snom
Bezeichnung
Snom200
Firmware: 3.56z
[sno]
Cisco Systems
Cisco IP Phone CP-7960G
Firmware: 7.5
[cis]
www.wirlab.net
kphone
Version 4.1.0
Softphone für Linux
[kph]
Tabelle 7 Verwendete IP-Telefone
Die Erweiterungen brauchen einen Teil der CPU-Zeit für die Auswertung der Messages
und für das Speichern der CDRs. Bei den Tests waren keine negativen Auswirkungen
spürbar. Sicher ist jedoch, dass sich die Zahl der maximal pro SER vermittelbaren
Gespräche verringern dürfte, wobei die erhöhten CPU-Belastungen nur während der
Signalisierungsphase auftreten. Ein laufendes Gespräch verursacht an dieser Stelle
keinerlei Performanceeinbußen.
Notwendige Erweiterungen im SER
| 56
Diplomarbeit
Stefan Abu Salah
Es ist zur Steigerung der Performance die Möglichkeit des Verlagerns der zur
Lokalisierung benötigten Datenbankabfragen ins T·XMD vorgesehen. Dies würde zu einer
Entlastung des Systems führen, jedoch muss die Möglichkeit zur sofortigen Lokalisierung
der Teilnehmer im Fall von Not- und Röchelrufen weiterhin im SER vorhanden sein.
9.5 Vorkommen doppelter Call-IDs
Da die Call-ID die wichtigste Größe zum Identifizieren eines Gesprächs und somit auch für
das spätere Abrechnen ist, ist es absolut notwendig, sicherzustellen, das diese ID unter
keinen Umständen doppelt vorkommen kann. In der RFC2543 ist unter Absatz 6.12 das
genaue Vorgehen bei der Generierung dieser Call-ID vorgegeben. Eine Call-ID darf nur für
ein Gespräch, also für den Zeitraum zwischen einer INVITE- und der dazugehörigen BYEMessage, Gültigkeit haben.
Eine gültige Call-ID hat den folgenden Aufbau:
Call-ID = („Call-ID“ | „i“ ) „:“ local-id „@“ host
local-id = 1*uric
Im Header einer SIP – Message könnte dann ein Call-ID-Eintrag folgendermaßen
aussehen:
Call-ID: [email protected]
oder
i: [email protected]
Die local-id wird im HEX– Format gesendet und beim Erstellen der ersten INVITE-Message
vom UAC mit einem Zufallszahlenalgorithmus generiert. Sollten trotzdem einmal gleiche
CallIDs auftauchen, ist die Identifizierung des Gesprächs über die gleich aufgebauten
From- und To-ID's immer noch eindeutig möglich. Ein falsches Zuordnen von Gesprächen
ist somit selbst bei tausenden von gleichzeitig geführten Gesprächen ausgeschlossen.
Notwendige Erweiterungen im SER
| 57
Diplomarbeit
Stefan Abu Salah
10 Änderungen im Quellcode des RTP-Proxy
Mit den Änderungen im SER ist die Lokalisierung der Teilnehmer und die Abrechnung der
Verbindung nach den oben beschriebenen Erweiterungen bereits im vollen Umfang
realisiert. Für den Produktiveinsatz ist jedoch ein weiterer wichtiger Punkt zu klären. Was
passiert mit einer durch einen Fehler unterbrochenen Verbindung? Alleine die bisher
vorgenommenen Erweiterungen hätten im Fehlerfall eine Abrechnung ins Unendliche zur
Folge, da das zur INVITE-Message gehörende BYE ausbleiben könnte. Beispiele für
mögliche Fehlerfälle sind Stromausfall, oder der Ausfall der Internetverbindung bei einem
Teilnehmer. Im herkömmlichen Telefonnetz wird nach gewissen Zeitabschnitten
kontrolliert, ob das Gespräch noch läuft, oder ob ein Fehler die Verbindung getrennt hat.
Ist dies der Fall, darf nur bis zum letzten bekannten Zeitpunkt abgerechnet werden, zu
dem die Verbindung sicher noch bestand. Diese Funktionalität nennt man den watchdog.
Eine solche Watchdog-Funktionalität muss auch für VoIP implementiert werden. Zur
Kontrolle, ob noch eine Verbindung besteht, bietet es sich an, den durch eine
Kommunikation verursachten RTP-Datenstrom zu kontrollieren. Da der RTP-Proxy [rtp]
diese Funktionalität nicht bietet, mussten einige Änderungen an dessen Quellcode dies
nachholen.
10.1 Generelle Vorgehensweise
Zur Identifikation der RTP-Datenpakete und deren Zuordnung zu einer Session wird die
CallID im Header jedes RTP-Pakets mitgesendet. Diese CallID unterscheidet sich nicht von
der CallID der zugehörigen SIP-Messages. Hier lässt sich also ein RTP-Datenstrom direkt
einem bereits initialisierten Gespräch zuordnen.
Der RTP-Strom muss nun in definierbaren Zeitabständen analysiert werden. Zeigt die
Analyse, dass ein Gespräch noch aktiv ist, also die zugehörigen RTP-Daten den Proxy
durchlaufen, muss die Endzeit des Gesprächs in den CDRs auf den aktuellen Wert gesetzt
werden. Ist dies nicht der Fall, wird diese Endzeit nicht geändert.
Änderungen im Quellcode des RTP-Proxy
| 58
Diplomarbeit
Stefan Abu Salah
Die folgende Abbildung zeigt schematisch den Ablauf eines SIP-Gesprächs mit watchdog.
Man sieht wie der watchdog des RTP-Proxys den Timestamp für das Gesprächsende
immer nach einer Zeit (ΔT) in der Datenbank auf den aktuellen Wert setzt.
SIP-Server
CDR-Datenbank
RTP-Proxy
A
B
INVITE
INVITE
Trying
Ringing
OK
Ringing
OK
Erzeugen eines neuen
CDR-Eintrags
RTP-Stream
RTP-Stream
Aktualisiere
n
d. timestamps
ΔT
RTP-Stream
RTP-Stream
Aktualisiere
n
d. timestamps
x
t
Abbildung 17 Prinzipielle Funktionsweise des Watchdogs
Um die durch die Datenbanktransaktionen hervorgerufenen Performanceeinbußen so
gering wie möglich zu halten, lassen sich zwei Zeiten definieren. Die Zeit
STREAM_UPDATE definiert das Zeitintervall, nach dem analysiert werden soll, ob eine
Verbindung noch besteht. SQL_UPDATE (ΔT) legt das Datenbank-Aktualisierungsintervall
fest. Nach der hier angegebenen Zeit werden die Endzeiten durch ein UPDATE der CDRDatenbank auf den in der Struktur gespeicherten Wert gesetzt.
Änderungen im Quellcode des RTP-Proxy
| 59
Diplomarbeit
Stefan Abu Salah
...
// Angaben in Sekunden
#define STREAM_UPDATE 60
#define SQL_UPDATE 120
// Struktur zur Aufnahme der Verbindungen
struct rtp_streams
{
long int timestamp;
char call_id[100];
struct rtp_streams *next;
};
struct rtp_streams *first_stream;
...
10.2 Erläuterung der Umsetzung
Ergibt die Restwertbestimmung des aktuellen Timestamps und STREAM_UPDATE den
Wert Null, so erfolgt die Auswertung des Streams. Der erste Test wird in der Funktion
chk_new_rtp_stream() durchgeführt. Die Restwertbestimmung liefert eine Sekunde lang
den Wert Null. In dieser Sekunde durchlaufen für jedes Gespräch, abhängig vom
verwendeten Codec, 50 bis 100 Sprachpakete den Proxy. Die Auswertung aller Pakete ist
unnötig, weshalb die Funktion chk_new_rtp_stream() zuerst testet, ob in dieser Sekunde
bereits eine Analyse dieses Gespräches stattgefunden hat. Dieses Vorgehen soll zur
Entlastung des Systems führen, da unnötige Aktionen auf diese Weise verhindert werden.
Kann kein Eintrag in der Liste der Gespräche mit den übergebenen Parametern CallID und
aktuellem Timestamp gefunden werden, wird dieser Datensatz von der Funktion
chk_rtp_stream() entweder neu angelegt, oder nur der Timestamp aktualisiert. In einem
letzten Schritt wird festgestellt, ob die Datenbank aktuallisiert werden soll. Die
Restwertbestimmung von aktuellem Timestamp und dem Wert in SQL_UPDATE legt
diesen Zeitpunkt fest. Liefert diese Prüfung den Wert Null, werden die Endzeitpunkte des
zugehörigen CDR-Eintrags in der MySQL-Datenbanktabelle aktualisiert. Das Aktualisieren
übernimmt die Funktion rtp_stream2sql().
Änderungen im Quellcode des RTP-Proxy
| 60
Diplomarbeit
Stefan Abu Salah
...
time_t event_time;
// Nach in SREAM_UPDATE definierter Zeit nachsehen
// ob der rtp-Stream noch läuft
if( (time(&event_time) % STREAM_UPDATE) == 0 )
{
// Ist der RTP-Stream mit der Kennung "callid"
// noch nicht aktualisiert worden?
if(chk_new_rtp_stream( sp->call_id, time(&event_time))!=0 )
{
chk_rtp_stream( sp->call_id );
if( (time(&event_time) % SQL_UPDATE) == 0 )
rtp_stream2sql( );
}
}
...
10.3 SDP und der watchdog
Mit SDP ist es beispielsweise möglich, Gespräche umzuleiten, zu parken oder Haltemusik
einzublenden. Hierdurch kann es vorkommen, dass der RTP-Strom abbricht, ohne dass ein
Fehler die Ursache hierfür ist. In diesem Fall würde der watchdog das Gesprächende,
genau wie bei fehlerhaft beendeten Verbindungen, nicht weiter aktualisieren. Es kann
also in einem solchen Fall nicht unterschieden werden, ob eine Verbindung Zusatzdienste
nutzt oder durch einen Fehler getrennt wurde.
Die hier gemachten Änderungen umgehen dieses Problem dadurch, dass die
Aktualisierung der Endzeiten, durch den watchdog, mit dem Ende der Inanspruchnahme
einer dieser Dienste fortgesetzt wird. Damit die intern geführte Liste nicht zu lang wird,
sollte jedoch eine maximale Gesprächslänge (z.B. 1 bis X Tage) definiert werden, nach
der eine Verbindung zwangsgetrennt wird.
Änderungen im Quellcode des RTP-Proxy
| 61
Diplomarbeit
Stefan Abu Salah
10.4 Performance und Stabilität
Die am rtpproxy vorgenommenen Erweiterungen laufen performant, stabil und
zuverlässig, jedoch sind Tests unter realistischen Bedingungen mit mehreren hundert
gleichzeitigen Gesprächen nötig, um eine abschließende Betrachtung der Performance
und der Stabilität zuzulassen. Die bisherigen Tests haben keine Schwächen aufgezeigt.
Änderungen im Quellcode des RTP-Proxy
| 62
Diplomarbeit
Stefan Abu Salah
11 Erläuterungen der Änderungen im Quellcode von
FreeRADIUS
Zur Identifizierung des Benutzers sieht GeoVIPA das Verwenden der CHIP vor. Diese, dem
Benutzer fest zugeordnete ID, dient später der personenbezogenen Abrechnung des
Gesprächs. Es ist hiermit also möglich, einen beliebigen Anschluss zu nutzen und
trotzdem auf eigene Kosten zu telefonieren. Die CHIP muss dem Benutzer im RADIUSServer fest zugeordnet werden.
11.1 Die CHIP aus Radius
Die Benutzerverwaltung des FreeRADIUS-Servers [rad] wird in der Konfigurationsdatei /
etc/raddb/users verwaltet. Diese Datei beinhaltet eine genaue Aufschlüsselung der
Rechte jedes einzelnen Benutzers. Hier kann jeder URI eine CHIP zugeordnet werden. Da
es für das Aufnehmen der CHIP in RADIUS keine definierten Einträge gibt, ist hier zu
diesem Zweck die Variable Framed-IP-Address verwendet worden. In Zukunft kann man
jedoch eine spezielle Variable für die CHIP implementieren.
# /etc/raddb/users
...
[email protected] Auth-Type := Digest, User-Password == "1234"
Reply-Message = "Authenticated",
Callback-Number = "9,1234",
# Der folgende Eintrag beinhaltet die URI und die CHIP
Framed-IP-Address = "[email protected];192.168.0.1;",
Sip-Rpid = "1234"
...
Die bei der Authentisierung durch RADIUS ausgetauschten Daten stehen in der Datei
radius.c zur Verfügung und können ausgewertet werden. Hier kann der Eintrag der
Variablen Framed-IP-Address ausgelesen und im CSV-Format in eine Datei oder in eine
Datenbank geschrieben werden. Auf diese Weise stehen die Daten bei einer späteren
Auswertung z.B. durch das T·XMD zur Verfügung.
Erläuterungen der Änderungen im Quellcode von FreeRADIUS
| 63
Diplomarbeit
Stefan Abu Salah
12 Übertragen der CDRs in das T·XMD
Das Aufbereiten, Anreichern und Übertragen der in den CDRs gesammelten
Verbindungsdaten übernimmt das T·XMD. Es ermittelt die Entfernung der Teilnehmer,
den Minutenpreis und die Dauer der Verbindung und reichert die aus den CDRs geholten
Daten mit diesen Informationen an. Nach diesen Rating-Vorgängen können die
Verbindungen ins Billing überführt und die Rechnungen der Kunden erstellt werden.
Datapool
Rating
Holen der Daten
aus dem CSV-File
Collector
Umwandeln
der Daten
nach CSV
Speichern der
CSV-Files
in den Datenpool
Anreichern
der Daten
T·XMD
Überführen der
Angereicherten Daten
in den Datenpool
Datapool
Datenbank für CDRs
Holen der
Verbindungsdaten
Billing
Erzeugen der
Kundenrechnung
Abfrage der
Verbindungsdaten
Abbildung 18 Ablauf des Ratingvorgangs
12.1 Erweiterung des T·XMD um eine einfache VoIP–Rating–
Schnittstelle
Für das Rating des VoIP-Verbindungen musste ein Plugin für das T·XMD geschrieben
werden. Zu Demonstrationszwecken reichte hier eine sehr einfache Umsetzung aus. Es
wird lediglich anhand eines Vergleichs der Postleitzahlen der Teilnehmer eine
Entfernungsbestimmung durchgeführt. Sind die ersten beiden Stellen der Postleitzahlen
Übertragen der CDRs in das T·XMD
| 64
Diplomarbeit
Stefan Abu Salah
gleich, so handelt es sich bei diesem Modell um ein Ortsgespräch, gleicht sich hier nur die
erste Stelle, so wird das Gespräch der nächst größeren Verzohnungsstufe zugeordnet.
Sind die Postleitzahlen in Gänze unterschiedlich, wird das Gespräch als Ferngespräch
abgerechnet. In späteren Implementierungen kann diese Schnittstelle jedoch beliebig
ausgebaut und erweitert werden. Beispielsweise ließen sich über eine Abbildung der
Adressen auf die dort gültigen Vorwahlnummern die herkömmlichen Tarifzonen weiter
nutzen. Das folgende Skript erweitert das T·XMD um eine Rating-Schnittstelle für VoIPVerbindungen:
// voip_rating_impl.cc
#include "voip_rating_impl.hh"
#define ORT "1,5"
#define REGIO "3,0"
#define FERN "4,5"
#define SEP ";"
String rating(String aplz, String bplz)
{
// Hier wird anhand eines PLZ - Vergleichs entschieden um welche
// Tarifzone es sich handelt
if( aplz[0] == bplz[0] && aplz[1] == bplz[1] )
// Sind die ersten beiden Ziffern der PLZ gleich, so
// handelt es sich um ein Ortsgepräch
return "ORT" + SEP + ORT + SEP;
else if ( aplz[0] == bplz[0] )
// Ist die erste Ziffer der PLZ gleich, so handelt es
// sich um ein Regio - Gespräch
return "REGIO" + SEP + REGIO + SEP;
// Sind die PLZ vollkommen unterschiedlich, so muss es sich
// um ein Ferngespräch handeln
return "FERN" + SEP + FERN + SEP;
}
Übergibt man dieser Funktion als Parameter die Postleitzahlen der Teilnehmer, so
bekommt man als Antwort einen String mit der Entfernungseinstufung und dem
zugehörigen Minutenpreis im CSV-Format mit definierbaren Trennzeichen. Diese Daten
stehen dem Billing im nächsten Schritt zur Verfügung.
Übertragen der CDRs in das T·XMD
| 65
Diplomarbeit
Stefan Abu Salah
12.2 Erstellen einer Konfiguration des T·XMD für VoIP – CDRs
Die Konfiguration des T·XMD geschieht mittels einer Skriptsprache. Für die Verarbeitung
der
Gesprächsrohdaten
mussten
drei
Module
mit
unterschiedlichen
Aufgaben
programmiert werden. Zunächst muss ein Skript das T·XMD anweisen, die Rohdaten aus
der Datenbank einzulesen und in einen Container zu speichern. Die Daten sollen im CSVFormat
abgelegt
werden.
Im
nächsten
Schritt
sollen
diese
Daten mit
den
Lokalisierungsdaten angereichert werden.
Abbildung 19 Das Billing
Die Abfrage der Adressdaten bei den ISPs reichert die Verbindungsdaten mit Name und
Anschrift der Gesprächsteilnehmer an. Im letzten Schritt erfolgt das Rating der
Gespräche. Das oben beschriebene Rating-Modul reichert die Verbindungsdaten mit den
Übertragen der CDRs in das T·XMD
| 66
Diplomarbeit
Stefan Abu Salah
für das Billing wichtigen Informationen, wie Preis/Minute, Gesamtverbindungszeit und
Gesamtkosten an.
Das Rating der Gespräche ist nun abgeschlossen und die Daten
können wieder in einem Container dem Billingsystem zugeführt werden.
Übertragen der CDRs in das T·XMD
| 67
Diplomarbeit
Stefan Abu Salah
13 Rechtliche Situation
Das
TDDSG
(Teledienstedatenschutzgesetz)
verbietet
die
Speicherung
von
Nutzungsdaten, die nicht für das Funktionieren des Dienstes oder für die Abrechnung
nötig sind. In §6 des TDDSG [tdd] ist dies klar definiert:
Der Diensteanbieter darf personenbezogene Daten eines Nutzers ohne dessen
Einwilligung nur erheben, verarbeiten und nutzen, soweit dies erforderlich ist, um
die Inanspruchnahme von Telediensten zu ermöglichen und abzurechnen
(Nutzungsdaten). Nutzungsdaten sind insbesondere
a) Merkmale zur Identifikation des Nutzers,
b) Angaben über Beginn und Ende sowie über den Umfang der jeweiligen Nutzung
und
c) Angaben über die vom Nutzer in Anspruch genommenen Teledienste.
Zitat: §6 TDDSG (Abs. 1)
Insbesondere sei hier erwähnt, dass für die Speicherung der Verbindungsdaten im Falle
der Nutzung einer Internet-Flatrate keinerlei Berechtigung besteht, da keine für eine
spätere Abrechnung durch den ISP relevanten Daten gesammelt werden müssen. Das in
diesem Konzept vorgesehene Speichern der Verknüpfung von IP-Daten und persönlichen
Kundendaten in einer Datenbank zur Lokalisierung des Kunden stellt einen besonderen
Fall dar. Einerseits darf durch den Telefonanbieter zwar die Verknüpfung dieser Daten
erfolgen,
Der Diensteanbieter darf Nutzungsdaten eines Nutzers über die Inanspruchnahme
verschiedener Teledienste zusammenführen, soweit dies für Abrechnungszwecke
mit dem Nutzer erforderlich ist.
Zitat: §6 TDDSG (Abs. 2)
andererseits ist der ISP, über den der Kunde das Internet nutzt, hierzu nur berechtigt,
wenn der Kunde diesem Anbieter vertraglich zur Nutzung dieser Daten zugestimmt hat.
Ist dies nicht der Fall, dürfen die Daten nicht gespeichert oder weitergereicht werden.
Somit müssen beide Teilnehmer bei ihren ISP vertraglich deutlich gemacht haben, dass sie
Rechtliche Situation
| 68
Diplomarbeit
Stefan Abu Salah
diesen das Recht zur Bereitstellung der zur Lokalisierung benötigten Daten geben. Nur in
diesem Fall wäre das Zugänglichmachen der Abrechnungsdaten nach TDDSG rechtens:
Der Diensteanbieter darf an andere Diensteanbieter oder Dritte Abrechnungsdaten
übermitteln, soweit dies zur Ermittlung des Entgelts und zur Abrechnung mit dem
Nutzer erforderlich ist. Hat der Dienstsanbieter mit einem Dritten einen Vertrag
über den Einzug des Entgelts geschlossen, so darf er diesem Dritten
Abrechnungsdaten übermitteln, soweit es für diesen Zweck erforderlich ist.
...
Zitat: §6 TDDSG (Abs. 5)
Schwierig wird die Situation, wenn nur ein Teilnehmer ein solches Einverständnis gegeben
hat. In diesem Fall ist der ISP des anderen Teilnehmers nicht berechtigt, eine
Adressdatenerfassung durchzuführen, und eine Lokalisierung dieses Teilnehmers ist
unmöglich.
Es muss also sichergestellt werden, dass alle über dieses System erreichbaren Teilnehmer
über einen für die Lokalisierung vertraglich abgesicherten ISP-Zugang verfügen.
Rechtliche Situation
| 69
Diplomarbeit
Stefan Abu Salah
14 Schlussbetrachtung
Mit den beschriebenen Erweiterungen sind die anfangs definierten Ziele dieser
Diplomarbeit
erreicht
worden.
So
ist
es
möglich,
eine
Lokalisierung
der
Gesprächsteilnehmer durchzuführen, und alle wichtigen Gesprächsparameter stehen in
CDRs für die weitere Verarbeitung zur Verfügung. Notrufzentralen kann sofort beim
Eintreffen eines Notruf der vollständige Adressdatensatz des Anrufers zur Verfügung
gestellt werden. Im Fehlerfall können die gestörten Verbindungen durch die
Implementierung einer watchdog-Funktionalität bis auf ein einstellbares Intervall genau
abgerechnet werden. Ein einfaches, für das Rating der VoIP-Verbindungen benötigtes
Modul wurde für das T·XMD entwickelt und und bereitet die CDRs mit den für das Billing
benötigten Informationen an.
Schlussbetrachtung
| 70
Diplomarbeit
Stefan Abu Salah
15 Abbildungsverzeichnis
Abbildung 1 Aufbau eines RTP-Headers__________________________________________12
Abbildung 2 VoIP mit RTP-Proxy________________________________________________13
Abbildung 3 Aufbau eines RTCP-Headers________________________________________14
Abbildung 4 Protokollarchitektur für Multimediaverbindungen_______________________15
Abbildung 5 SIP-Proxy________________________________________________________17
Abbildung 6 SIP - Nachrichtenaustausch_________________________________________21
Abbildung 7 Aufbau einer SIP-Message__________________________________________22
Abbildung 8 phpMyAdmin Ansicht des Tabelleninhalts_____________________________33
Abbildung 9 Aufbau des T·XMD_______________________________________________35
Abbildung 10 Konfiguration der Prozesslogik des T·XMD___________________________37
Abbildung 11 Das Frontend des T·XMD _________________________________________38
Abbildung 12 Integration von VoIP in das PSTN___________________________________40
Abbildung 13 Übersicht der Komponenten zur Lokalisierung________________________42
Abbildung 14 Modell der ISP-Datenbank_________________________________________49
Abbildung 15 Modell der Adressdatenbank des ISP________________________________50
Abbildung 16 Veranschaulichung der Lokalisierung________________________________51
Abbildung 17 Prinzipielle Funktionsweise des Watchdogs___________________________59
Abbildung 18 Ablauf des Ratingvorgangs________________________________________64
Abbildung 19 Das Billing______________________________________________________66
Schlussbetrachtung
| 71
Diplomarbeit
Stefan Abu Salah
16 Tabellenverzeichnis
Tabelle 1 Codecs für VoIP_____________________________________________________11
Tabelle 2 SIP-Methoden______________________________________________________19
Tabelle 3 Status Codes_______________________________________________________20
Tabelle 4 SIP-Header_________________________________________________________22
Tabelle 5 SDP-Parameter______________________________________________________23
Tabelle 6 CDR in MySQL______________________________________________________55
Tabelle 7 Verwendete IP-Telefone______________________________________________56
Schlussbetrachtung
| 72
Diplomarbeit
Stefan Abu Salah
17 Abkürzungsverzeichnis
Abkürzung
A
AAA
API
ASCII
C
CDR
CHIP
CORBA
CPU
CSV
D
DHCP
diffserv
DSL
F
FTAM
FTP
G
GeoVIPA
Beschreibung
RFC
Authentication, Authorization, Accounting
Application Programming Interface
American Standard Code for Information
Interchange
Call Detail Record
Charging IP
Common Object Request Broker Architecture
Central Processing Unit
Comma Separated Values
Dynamic Host Configuration Protocol
Differentiated Services
Digital Subscriber Line
RFC2131
RFC2474, RFC2475
File Transfer and Access Management
File Transfer Protocol
RFC959
Geographische Verzonung von VoIP zur
Authentifizierung der Verkehrsursprünge zur
Abrechnung und Erkennung von
Verbindungsursprüngen für Notrufe und
GPL
GSM
H
HTTP
I
IETF
IP
ISDN
ISO
ISP
Mehrwertdiensten
General Public License
Global System for Mobile Communications
Hypertext Transfer Protocol
RFC1945, RFC2616
Internet Engineering Task Force
Internet Protocol
Integrated Services Digital Network
International Organization for Standardization
Internet Service Provider
Abkürzungsverzeichnis
| 73
Diplomarbeit
Stefan Abu Salah
Abkürzung
L
LAC
LDAP
P
PAR
PCM
PHP
PKI
PLIP
PSTN
Q
QoS
R
RADIUS
RSVP
RTCP
RTP
S
SAP
SDP
SER
SIP
SMTP
SQL
SSH
T
TCP
TDDSG
T·XMD
U
UAC/UAS
UDP
UMTS
UTF
V
VoIP
Beschreibung
RFC
Lightweight Directory Access Protocol
RFC2251
Puls-Code-Modulation
Hypertext Preprocessor
Public-Key-Infrastruktur
Physical Line IP
Public Switched Telephone Network
Quality of Service
Remote Authentication Dial-In User Service
Resource Reservation Protocol
RealTime Control Protocol
Real-Time Transport Protocol
RFC2138, RFC2139
RFC2205
RFC1890
RFC1889
Session Description Protocol
SIP Express Router
Session Initiation Protocol
Simple Mail Transfer Protocol
Structured Query Language
Secure shell
RFC2327
Transmission Control Protocol
Teledienstedatenschutzgesetz
TECON eXtended Mediation Device
RFC793
RFC3261, RFC2543
RFC821
User Agent Client/User Agent Server
User Datagram Protocol
Universal Mobile Telecommunications System
Unicode Transformation Format
RFC768
Voice over IP
Abkürzungsverzeichnis
| 74
Diplomarbeit
Stefan Abu Salah
18 Literaturverzeichnis
18.1 Printmedien
ID
[SIP]
[SQL]
[IPv6]
[RAD]
[TCP]
[GEO]
[TEC]
Titel
Autor
ISBN
Titel
Autor
ISBN
Titel
Autor
ISBN
Titel
Autor
ISBN
Titel
Autor
ISBN
Titel
Autor
Buch
SIP Multimediale Dienste im Internet
Rupp/Siegmund/Lautenschlager
3-89864-167-8
MySQL – Das offizelle Handbuch
Widenius/Axmark
3-8266-1351-1
IPv6 – Das Migrationsbuch
Hein/Reisner
3-7723-7390-9
RADIUS
Hassell
0-596-00322-6
TCP/IP
Hein
3-8266-4094-2
GeoVIPA
Fröhlich/Weyerstraß
Verlag
Titel
Autor
Das TECON eXtended Mediation Device
--TECON
dpunkt
mitp
Franzis'
O'Reilly
mitp
TECON/WeyTeCon
18.2 Internetquellen
ID
[sql]
[ber]
[rad]
[ser]
[rtp]
[sip]
[tdd]
[sno]
[cis]
[kph]
Link
http://www.little-idiot.de/mysql/mysql.html
http://developer.berlios.de
http://www.freeradius.org
http://www.iptel.org/ser
http://www.portaone.com/resources/downloads
http://www.informatik.uni-bremen.de/~prelle/terena/cookbook/main
http://www.online-recht.de/vorges.html?TDDSG
http://www.snom.com/snom200_release_notes.html
http://www.cisco.com/en/US/products/hw/phones/ps379/products_data_she
et09186a0080091984.html
http://www.wirlab.net/kphone/
Literaturverzeichnis
| 75
Diplomarbeit
Stefan Abu Salah
Literaturverzeichnis
| 76
Diplomarbeit
Stefan Abu Salah
19 Anhang
19.1 Änderungen am Quellcode des SER : msgparser.c
/*
* $Id: msg_parser.c,v 1.34.4.1 2003/11/24 14:00:34 janakj Exp $
*
* sip msg. header proxy parser
*
*
* Copyright (C) 2001-2003 Fhg Fokus
*
* This file is part of ser, a free SIP server.
*
* ser is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version
*
* For a license to use the ser software under conditions
* other than those described here, or to purchase support for this
* software, please contact iptel.org by e-mail at the following addresses:
*
[email protected]
*
* ser is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* History:
* --------* 2003-02-28 scratchpad compatibility abandoned (jiri)
* 2003-01-29 scrathcpad removed (jiri)
* 2003-01-27 next baby-step to removing ZT - PRESERVE_ZT (jiri)
* 2003-03-31 removed msg->repl_add_rm (andrei)
* 2003-04-26 ZSW (jiri)
* 2003-05-01 parser extended to support Accept header field (janakj)
*/
#include <string.h>
#include <stdlib.h>
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
"../comp_defs.h"
"msg_parser.h"
"parser_f.h"
"../ut.h"
"../error.h"
"../dprint.h"
"../data_lump_rpl.h"
"../mem/mem.h"
"../error.h"
"../globals.h"
"parse_hname2.h"
"parse_uri.h"
"parse_content.h"
Anhang
| 77
Diplomarbeit
Stefan Abu Salah
#ifdef DEBUG_DMALLOC
#include <mem/dmalloc.h>
#endif
#define parse_hname(_b,_e,_h) parse_hname2((_b),(_e),(_h))
/*
/*
/*
/*
/*
######## ERWEITERUNG LOKALISIERUNG ########
#
Diplomarbeit
#
#
Stefan Abu Salah 11.06.2005
#
###########################################
#
#
#
###########################################
*/
*/
*/
*/
*/
#include <mysql/mysql.h>
#include <time.h>
#include <stdio.h>
#define MAX_MSG_LEN 1000
#define CSV_SEPERATOR ";"
// Datenbankeinstellungen
#define HOST "localhost"
#define USER "debian-sys-maint"
#define PASSWORD "k8WmUQg2rumvueLk"
#define DBASE "tecon"
#define SOCKET NULL
#define PORT 3306
#define FLAG 0
#define SQL_QUERY 2000
// Längendefinitionen
#define CALL_ID 100
#define ACCT_STATUS_TYPE 500
#define TIMESTAMP 20
#define REALTIME 20
#define FROM 100
#define PLIP 20
#define CHIP 20
#define TO 100
#define AUDIO_CODEC 50
#define SERVICE_TYPE 50
#define ACCT_SESSION_ID 100
#define CALLING_STATION_ID 200
#define CALLED_STATION_ID 200
#define SESSION_STATUS 10
#define
#define
#define
#define
#define
#define
#define
NAME 50
VORNAME 50
STRASSE 200
HN 10
ORT 200
PLZ 10
ZUSATZ 200
// Notrufeinträge
#define EMEGENCY_CALL "[email protected]"
Anhang
| 78
Diplomarbeit
Stefan Abu Salah
// Loging Einstellungen
#define SQL_QUERY_LOG 1
#define SQL_ANSWER_LOG 1
#define LOC_DEBUG 1
#define LOC_LOG_SIPMSG 1
// Struktur zur Aufname der Gesprächsdaten
struct loc_csv {
int sip_code;
char acct_status_type[ACCT_STATUS_TYPE],
start_time[TIMESTAMP],
end_time[TIMESTAMP],
start_realtime[REALTIME],
end_realtime[REALTIME],
calling_station_id[CALLING_STATION_ID],
aplip[PLIP],
bplip[PLIP],
dstip[PLIP],
ch_ip[CHIP],
called_station_id[CALLED_STATION_ID],
audio_codec[AUDIO_CODEC],
acct_session_id[ACCT_SESSION_ID],
session_status[SESSION_STATUS],
totag[ACCT_SESSION_ID],
fromtag[ACCT_SESSION_ID],
service_type[SERVICE_TYPE],
azusatz[ZUSATZ],
};
aname[NAME],
avorname[VORNAME],
astrasse[STRASSE],
ahn[HN],
aort[ORT],
aplz[PLZ],
bname[NAME],
bvorname[VORNAME],
bstrasse[STRASSE],
bhn[HN],
bort[ORT],
bplz[PLZ],
bzusatz[ZUSATZ];
// Funktionsprototypen
void loc_csv( char item[] );
void loc_logfile( char item[] );
char *loc_timestamp( void );
char *loc_realtime( char format[] );
char *loc_sqlquery( char query[],char url[], char user[], char pw[], char dbase[]
);
char *loc_msg2csv( struct sip_msg* msg );
void loc_inv_msg( struct sip_msg* msg );
void loc_bye_msg( struct sip_msg* msg );
void loc_ack_msg( struct sip_msg* msg );
void loc_ok_msg( struct sip_msg* msg );
void loc_fai_msg( struct sip_msg* msg );
int loc_get_msg( struct sip_msg* msg );
char *loc_get_msg_item( struct sip_msg* msg, char item[], char *start, char
*stop );
char *loc_get_isp( struct loc_csv *call);
/* ########## ENDE DER ERWEITERUNG ########### */
Anhang
| 79
Diplomarbeit
Stefan Abu Salah
/* number of via's encounteded */
int via_cnt;
/* returns pointer to next header line, and fill hdr_f ;
* if at end of header returns pointer to the last crlf (always buf)*/
char* get_hdr_field(char* buf, char* end, struct hdr_field* hdr)
{
char* tmp;
char *match;
struct via_body *vb;
struct cseq_body* cseq_b;
struct to_body* to_b;
int integer;
if ((*buf)=='\n' || (*buf)=='\r'){
/* double crlf or lflf or crcr */
DBG("found end of header\n");
hdr->type=HDR_EOH;
return buf;
}
...
flags=HDR_VIA;
break;
default:
DBG("unknown type %d\n",fl->type);
goto error;
}
msg->unparsed=tmp;
/*find first Via: */
first_via=0;
second_via=0;
if (parse_headers(msg, flags, 0)==-1) goto error;
/*
/*
/*
/*
/*
######## ERWEITERUNG LOKALISIERUNG ########
#
Diplomarbeit
#
#
Stefan Abu Salah 11.06.2005
#
###########################################
#
# Abgreifen der SIP-Nachrichten
#
###########################################
*/
*/
*/
*/
*/
if( loc_get_msg(msg) )
DBG("loc_get_msg: failed\n");
/* ########## ENDE DER ERWEITERUNG ########### */
//
char tmp1 [100000];
//
char tmp2 [10000] = "";
//
char tmp4 [10000] = "";
//
loc_logfile("");
//
loc_logfile(" <<<<<<<<<<<<<<<<<<<<<<<<< parse_msg
>>>>>>>>>>>>>>>>>>>>>>>>>>>> ");
//
//
//
if(msg->from)
Anhang
| 80
Diplomarbeit
Stefan Abu Salah
...
}
/*
/*
/*
/*
/*
if ( parse_headers(msg, HDR_FROM|HDR_TO|HDR_CALLID|HDR_CSEQ,0)!=-1
&& msg->from && msg->to && msg->callid && msg->cseq ) {
return 1;
} else {
ser_error=E_BAD_TUPEL;
return 0;
}
######## ERWEITERUNG LOKALISIERUNG ########
#
Diplomarbeit
#
#
Stefan Abu Salah 11.06.2005
#
###########################################
#
# Lokalisierung
#
###########################################
*/
*/
*/
*/
*/
char * loc_msg2str( struct loc_csv* call, char sep[], char sepeol[] )
{
static char str_cat[10000],
*str_catp;
strcpy(str_cat,call->acct_status_type);
strcat(str_cat,sep);
strcat(str_cat,call->start_time);
strcat(str_cat,sep);
strcat(str_cat,call->end_time);
strcat(str_cat,sep);
strcat(str_cat,call->start_realtime);
strcat(str_cat,sep);
strcat(str_cat,call->end_realtime);
strcat(str_cat,sep);
strcat(str_cat,call->calling_station_id);
strcat(str_cat,sep);
strcat(str_cat,call->aplip);
strcat(str_cat,sep);
strcat(str_cat,call->bplip);
strcat(str_cat,sep);
strcat(str_cat,call->dstip);
strcat(str_cat,sep);
strcat(str_cat,call->ch_ip);
strcat(str_cat,sep);
strcat(str_cat,call->called_station_id);
strcat(str_cat,sep);
strcat(str_cat,call->audio_codec);
strcat(str_cat,sep);
strcat(str_cat,call->acct_session_id);
strcat(str_cat,sep);
strcat(str_cat,call->session_status);
strcat(str_cat,sep);
strcat(str_cat,call->totag);
strcat(str_cat,sep);
strcat(str_cat,call->fromtag);
strcat(str_cat,sep);
strcat(str_cat,call->service_type);
Anhang
| 81
Diplomarbeit
Stefan Abu Salah
strcat(str_cat,sep);
strcat(str_cat,call->aname);
strcat(str_cat,sep);
strcat(str_cat,call->avorname);
strcat(str_cat,sep);
strcat(str_cat,call->aort);
strcat(str_cat,sep);
strcat(str_cat,call->aplz);
strcat(str_cat,sep);
strcat(str_cat,call->astrasse);
strcat(str_cat,sep);
strcat(str_cat,call->ahn);
strcat(str_cat,sep);
strcat(str_cat,call->azusatz);
strcat(str_cat,sep);
strcat(str_cat,call->bname);
strcat(str_cat,sep);
strcat(str_cat,call->bvorname);
strcat(str_cat,sep);
strcat(str_cat,call->bort);
strcat(str_cat,sep);
strcat(str_cat,call->bplz);
strcat(str_cat,sep);
strcat(str_cat,call->bstrasse);
strcat(str_cat,sep);
strcat(str_cat,call->bhn);
strcat(str_cat,sep);
strcat(str_cat,call->bzusatz);
strcat(str_cat,sepeol);
}
str_catp = str_cat;
return str_catp;
struct loc_csv * loc_analyse_msg( struct sip_msg *msg )
{
static struct loc_csv *call = NULL;
char tmp [100] = "";
call = (struct loc_csv *) malloc(sizeof(struct loc_csv));
// Erzeugen der Eventzeiten
strcpy(call->start_time,loc_timestamp());
strcpy(call->start_realtime,loc_realtime("%Y%m%d%H%M%S"));
strcpy(call->end_time,loc_timestamp());
strcpy(call->end_realtime,loc_realtime("%Y%m%d%H%M%S"));
strcpy(call->calling_station_id,loc_get_msg_item(msg,"From:","ip:",">"));
// Auslesen der source - IP
sprintf(tmp,"%d.",msg->rcv.src_ip.u.addr[0]);
strcpy(call->aplip,tmp);
sprintf(tmp,"%d.",msg->rcv.src_ip.u.addr[1]);
strcat(call->aplip,tmp);
sprintf(tmp,"%d.",msg->rcv.src_ip.u.addr[2]);
strcat(call->aplip,tmp);
sprintf(tmp,"%d",msg->rcv.src_ip.u.addr[3]);
strcat(call->aplip,tmp);
Anhang
| 82
Diplomarbeit
Stefan Abu Salah
strcpy(call->bplip,"n/a");
// Auslesen der destination IP
sprintf(tmp,"%d.",msg->rcv.dst_ip.u.addr[0]);
strcpy(call->dstip,tmp);
sprintf(tmp,"%d.",msg->rcv.dst_ip.u.addr[1]);
strcat(call->dstip,tmp);
sprintf(tmp,"%d.",msg->rcv.dst_ip.u.addr[2]);
strcat(call->dstip,tmp);
sprintf(tmp,"%d",msg->rcv.dst_ip.u.addr[3]);
strcat(call->dstip,tmp);
strcpy(call->ch_ip,"n/a");
strcpy(call->called_station_id,loc_get_msg_item(msg,"To:","ip:",">"));
strcpy(call->audio_codec,"n/a");
strcpy(call->acct_session_id,loc_get_msg_item(msg,"Call-ID: ",NULL,"\r"));
strcpy(call->session_status,"n/a");
strcpy(call->totag,loc_get_msg_item(msg,"To:","ag=","\r"));
strcpy(call->fromtag,loc_get_msg_item(msg,"From:","ag=","\r"));
strcpy(call->service_type,loc_get_msg_item(msg,"s=",NULL,"\r"));
strcpy(call->aname,"n/a");
strcpy(call->avorname,"n/a");
strcpy(call->astrasse,"n/a");
strcpy(call->ahn,"n/a");
strcpy(call->aort,"n/a");
strcpy(call->aplz,"n/a");
strcpy(call->azusatz,"n/a");
strcpy(call->bname,"n/a");
strcpy(call->bvorname,"n/a");
strcpy(call->bstrasse,"n/a");
strcpy(call->bhn,"n/a");
strcpy(call->bort,"n/a");
strcpy(call->bplz,"n/a");
strcpy(call->bzusatz,"n/a");
return call;
}
int loc_get_msg( struct sip_msg* msg )
{
struct loc_csv* call = NULL;
int i = 0;
char
*item = NULL;
char
*sql_answer = NULL;
char
*address = NULL;
char
tmp[10000] = "";
char inv_query[SQL_QUERY] = "INSERT INTO connection
(acct_status_type,start_time,end_time,start_realtime,end_realtime,calling_station_
id,aplip,bplip,dstip,ch_ip,called_station_id,audio_codec,acct_session_id,session_s
tatus,totag,fromtag,service_type,aname,avorname,astrasse,ahn,aort,aplz,azusatz,bna
me,bvorname,bstrasse,bhn,bort,bplz,bzusatz) VALUES(\"";
char
char
char
char
char
char
char
bye_query[SQL_QUERY] = "UPDATE connection SET ";
bye_query1[SQL_QUERY]= "WHERE acct_session_id=";
sql_acct_status_type[SQL_QUERY] ="acct_status_type=";
start_time[SQL_QUERY] ="start_time=";
end_time[SQL_QUERY] ="end_time=";
start_realtime[SQL_QUERY] ="start_realtime=";
end_realtime[SQL_QUERY] ="end_realtime=";
Anhang
| 83
Diplomarbeit
Stefan Abu Salah
char
char
char
char
char
char
char
char
char
char
char
char
calling_station_id[SQL_QUERY] ="calling_station_id=";
aplip[SQL_QUERY] ="aplip=";
bplip[SQL_QUERY] ="bplip=";
dstip[SQL_QUERY] ="dstip=";
ch_ip[SQL_QUERY] ="ch_ip=";
called_station_id[SQL_QUERY] ="called_station_id=";
audio_codec[SQL_QUERY] ="audio_codec=";
acct_session_id[SQL_QUERY] ="acct_session_id=";
session_status[SQL_QUERY] ="session_status=";
totag[SQL_QUERY] ="totag=";
fromtag[SQL_QUERY] ="fromtag=";
service_type[SQL_QUERY] ="service_type=";
char ok_query[SQL_QUERY] = "UPDATE connection SET audio_codec=\"",
ok_query1[SQL_QUERY]= "\",bplip=\"",
ok_query2[SQL_QUERY]= "\",bname=\"",
ok_query3[SQL_QUERY]= "\",bvorname=\"",
ok_query4[SQL_QUERY]= "\",bstrasse=\"",
ok_query5[SQL_QUERY]= "\",bhn=\"",
ok_query6[SQL_QUERY]= "\",bort=\"",
ok_query7[SQL_QUERY]= "\",bplz=\"",
ok_query8[SQL_QUERY]= "\",acct_status_type=\"",
ok_query9[SQL_QUERY]= "\" WHERE acct_session_id=\"";
char csv_query[SQL_QUERY] = "SELECT
acct_status_type,start_time,end_time,calling_station_id,aplip,bplip,dstip,ch_ip,ca
lled_station_id,audio_codec,acct_session_id,session_status,totag,fromtag,service_t
ype,aname,avorname,astrasse,ahn,aort,aplz,azusatz,bname,bvorname,bstrasse,bhn,bort
,bplz,bzusatz FROM connection WHERE (acct_session_id=\"";
char sdp_query[SQL_QUERY] = "SELECT acct_status_type FROM connection WHERE
(acct_session_id=\"";
char fai_query[SQL_QUERY] = "SELECT acct_status_type FROM connection WHERE
(acct_session_id=\"";
#ifdef LOC_LOG_SIPMSG
strcpy(tmp,msg->first_line.u.request.method.s);
loc_logfile(tmp);
#endif
// Message Typ ? (INVITE || BYE || ACK || ... )
// Verteilen auf die jeweiligen Funktionen
if( strstr(msg->first_line.u.request.method.s,"INVITE") != NULL
&& strstr(msg->first_line.u.request.method.s,"SIP/2.0 200 OK") == NULL
&& strstr(msg->first_line.u.request.method.s,"Trying") == NULL
&& strstr(msg->first_line.u.request.method.s,"Ringing") == NULL
&& strstr(msg->first_line.u.request.method.s,"REGISTER") == NULL
&& strstr(msg->first_line.u.request.method.s,"SIP/2.0 487") == NULL
&& strstr(msg->first_line.u.request.method.s,"SIP/2.0 483") == NULL)
{
// Auslesen der Header Informationen
call = loc_analyse_msg( msg );
// ist schon ein Eintrag vorhanden?
strcat(fai_query,call->acct_session_id);
strcat(fai_query,"\")");
if( loc_sqlquery(fai_query,HOST,USER,PASSWORD,DBASE) != NULL )
return 0;
Anhang
| 84
Diplomarbeit
Stefan Abu Salah
strcat(sdp_query,call->acct_session_id);
strcat(sdp_query,"\" AND acct_status_type=\"");
strcat(sdp_query,"INVITE");
strcat(sdp_query,"\")");
NULL )
// Ist bereits eine INVITE-Verbindung mit dieser call_id vorhanden?
if( (sql_answer = loc_sqlquery(sdp_query,HOST,USER,PASSWORD,DBASE)) !=
else
strcpy(call->acct_status_type,"SDP");
strcpy(call->acct_status_type,"FAILED");
// Abfrage der Adressdaten des A-Teilnehmers über den Provider
address = loc_get_isp( call );
if( address != NULL )
{
item = strtok (address,";");
}
else
{
while (item != NULL)
{
if(i==0)
strcpy(call->aname,item);
if(i==1)
strcpy(call->avorname,item);
if(i==2)
strcpy(call->astrasse,item);
if(i==3)
strcpy(call->ahn,item);
if(i==4)
strcpy(call->aort,item);
if(i==5)
strcpy(call->aplz,item);
if(i==6)
strcpy(call->azusatz,item);
item = strtok (NULL, ";");
i++;
}
strcpy(tmp,"Adressauflösung nicht möglich (");
strcat(tmp,call->aplip);
strcat(tmp,")");
loc_logfile(tmp);
}
// INSERT IN DIE DATENBANK
// Erstellen eines neuen Datenbankeintrags für eine neue Verbindung
// Es fehlt noch die B-PLIP
strcpy(tmp,loc_msg2str(call,"\",\"","\""));
strcat(tmp,")");
strcat(inv_query,tmp);
if(strcmp( call->acct_status_type,"FAILED") == 0 )
loc_sqlquery(inv_query,HOST,USER,PASSWORD,DBASE);
#ifdef LOC_DEBUG
strcpy(tmp,loc_msg2str(call,";",";"));
loc_logfile(tmp);
#endif
if( strcmp(call->called_station_id,EMEGENCY_CALL) == 0 )
loc_logfile("NOTRUF -- sende SNMP-Trap");
Anhang
| 85
Diplomarbeit
Stefan Abu Salah
}
else if( strstr(msg->first_line.u.request.method.s,"BYE") != NULL
&& strstr(msg->first_line.u.request.method.s,"OK") == NULL
&& strstr(msg->first_line.u.request.method.s,"REGISTER") == NULL
{
)
// Auslesen der Header Informationen
call = loc_analyse_msg( msg );
strcat(sdp_query,call->acct_session_id);
strcat(sdp_query,"\" AND acct_status_type=");
strcat(sdp_query,"\"BYE\" AND bplip=\"n/a\"");
strcat(sdp_query,")");
NULL )
if( (sql_answer = loc_sqlquery(sdp_query,HOST,USER,PASSWORD,DBASE)) !=
return 0;
strcpy(call->acct_status_type,"BYE");
// UPDATE IN DIE DATENBANK
// Einfügen des Statustyps BYE und aktualisieren der end Zeiten
strcat(bye_query,sql_acct_status_type);
strcat(bye_query,"\"BYE\",");
strcat(bye_query,end_time);
strcat(bye_query,"\"");
strcat(bye_query,loc_timestamp());
strcat(bye_query,"\",");
strcat(bye_query,end_realtime);
strcat(bye_query,"\"");
strcat(bye_query,loc_realtime("%Y%m%d%H%M%S"));
strcat(bye_query,"\"");
strcat(bye_query,bye_query1);
strcat(bye_query,"\"");
strcat(bye_query,call->acct_session_id);
strcat(bye_query,"\"");
loc_sqlquery(bye_query,HOST,USER,PASSWORD,DBASE);
#ifdef LOC_DEBUG
strcpy(tmp,loc_msg2str(call,";",";"));
loc_logfile(tmp);
#endif
// Erstellen eines CSV - Eintrags
strcat(csv_query,call->acct_session_id);
strcat(csv_query,"\" AND acct_status_type=\"");
strcat(csv_query,call->acct_status_type);
strcat(csv_query,"\")");
// Erzeugen eines csv - Eintrags
sql_answer = loc_sqlquery(csv_query,HOST,USER,PASSWORD,DBASE);
strcpy(tmp,sql_answer);
loc_csv( tmp );
}
else if( strstr(msg->first_line.u.request.method.s,"SIP/2.0 200 OK") != NULL
&& strstr(msg->first_line.u.request.method.s,"Trying") == NULL
Anhang
| 86
Diplomarbeit
Stefan Abu Salah
{
&&
&&
&&
&&
strstr(msg->first_line.u.request.method.s,"Ringing") == NULL
strstr(msg->first_line.u.request.method.s,"BYE") == NULL
strstr(msg->first_line.u.request.method.s,"REGISTER") == NULL
strstr(msg->first_line.u.request.method.s,"CANCEL") == NULL )
// Auslesen der Header Informationen
call = loc_analyse_msg( msg );
// Audio Codec nur bei OK-Message relevant
strcpy(call->audio_codec,loc_get_msg_item(msg,"a=rtp","ap:","\r"));
strcpy(call->acct_status_type,"OK");
strcat(sdp_query,call->acct_session_id);
strcat(sdp_query,"\" AND acct_status_type=");
strcat(sdp_query,"\"FAILED\" AND bplip=\"n/a\"");
strcat(sdp_query,")");
NULL )
// Ist noch keine INVITE-Verbindung mit dieser call_id vorhanden?
if( (sql_answer = loc_sqlquery(sdp_query,HOST,USER,PASSWORD,DBASE)) !=
{
// Abfrage welchem ISP gehört die IP
// und A-PLIP und B-PLIP bei den ermittelten Providern
address = loc_get_isp( call );
if( address != NULL )
{
item = strtok (address,";");
}
else
{
while (item != NULL)
{
if(i==0)
strcpy(call->bname,item);
if(i==1)
strcpy(call->bvorname,item);
if(i==2)
strcpy(call->bstrasse,item);
if(i==3)
strcpy(call->bhn,item);
if(i==4)
strcpy(call->bort,item);
if(i==5)
strcpy(call->bplz,item);
if(i==6)
strcpy(call->bzusatz,item);
item = strtok (NULL, ";");
i++;
}
strcpy(tmp,"Adressauflösung nicht möglich (");
strcat(tmp,call->aplip);
strcat(tmp,")");
loc_logfile(tmp);
}
strcpy(call->acct_status_type,"INVITE");
strcat(csv_query,call->acct_session_id);
strcat(csv_query,"\" AND (acct_status_type=\"");
strcat(csv_query,call->acct_status_type);
strcat(csv_query,"\"))");
Anhang
| 87
Diplomarbeit
Stefan Abu Salah
// Herausfinder der B-Teilnehmer PLIP aus der OK Message
// ( call->plip1 ist hier die B-PLIP )
// Update auf die Datenbank
strcat(ok_query,call->audio_codec);
strcat(ok_query,ok_query1);
strcat(ok_query,call->aplip);
strcat(ok_query,ok_query2);
strcat(ok_query,call->bname);
strcat(ok_query,ok_query3);
strcat(ok_query,call->bvorname);
strcat(ok_query,ok_query4);
strcat(ok_query,call->bstrasse);
strcat(ok_query,ok_query5);
strcat(ok_query,call->bhn);
strcat(ok_query,ok_query6);
strcat(ok_query,call->bort);
strcat(ok_query,ok_query7);
strcat(ok_query,call->bplz);
strcat(ok_query,ok_query8);
strcat(ok_query,"INVITE");
strcat(ok_query,ok_query9);
strcat(ok_query,call->acct_session_id);
strcat(ok_query,"\"");
loc_sqlquery(ok_query,HOST,USER,PASSWORD,DBASE);
}
else
{
}
strcpy(call->acct_status_type,"SDP");
strcat(csv_query,call->acct_session_id);
strcat(csv_query,"\" AND (acct_status_type=\"");
strcat(csv_query,call->acct_status_type);
strcat(csv_query,"\" AND start_time=\"");
strcat(csv_query,call->start_time);
strcat(csv_query,"\"))");
#ifdef LOC_DEBUG
strcpy(tmp,loc_msg2str(call,";",";"));
loc_logfile(tmp);
#endif
// Erzeugen eines csv - Eintrags
NULL )
if( (sql_answer = loc_sqlquery(csv_query,HOST,USER,PASSWORD,DBASE)) !=
{
}
strcpy(tmp,sql_answer);
loc_csv( tmp );
}
else if( strstr(msg->first_line.u.request.method.s,"FAILED") != NULL
&& strstr(msg->first_line.u.request.method.s,"REGISTER") == NULL )
{
// Auslesen der Header Informationen
call = loc_analyse_msg( msg );
Anhang
| 88
Diplomarbeit
Stefan Abu Salah
strcpy(call->acct_status_type,"FAILED");
strcpy(tmp,loc_msg2str(call,"\",\"","\""));
strcat(tmp,")");
strcat(inv_query,tmp);
loc_sqlquery(inv_query,HOST,USER,PASSWORD,DBASE);
#ifdef LOC_DEBUG
strcpy(tmp,loc_msg2str(call,";",";"));
loc_logfile(tmp);
#endif
// Erzeugen eines csv - Eintrags
strcat(csv_query,call->acct_session_id);
strcat(csv_query,"\" AND acct_status_type=\"");
strcat(csv_query,call->acct_status_type);
strcat(csv_query,"\")");
// Erzeugen eines csv - Eintrags
sql_answer = loc_sqlquery(csv_query,HOST,USER,PASSWORD,DBASE);
strcpy(tmp,sql_answer);
loc_csv( tmp );
}
else if( strstr(msg->first_line.u.request.method.s,"REGISTER") != NULL
|| strstr(msg->first_line.u.request.method.s,"SUBSCRIBE") != NULL )
{
// Auslesen der Header Informationen
//call = loc_analyse_msg( msg );
//strcpy(call->acct_status_type,"REGISTER");
#ifdef LOC_DEBUG
//strcpy(tmp,loc_msg2str(call,";",";"));
//loc_logfile(tmp);
#endif
}
else if( strstr(msg->first_line.u.request.method.s,"CANCEL") != NULL
&& strstr(msg->first_line.u.request.method.s,"SIP/2.0 200 OK") == NULL
&& strstr(msg->first_line.u.request.method.s,"REGISTER") == NULL )
{
// Auslesen der Header Informationen
call = loc_analyse_msg( msg );
strcpy(call->acct_status_type,"CANCEL");
strcpy(tmp,loc_msg2str(call,"\",\"","\""));
strcat(tmp,")");
strcat(inv_query,tmp);
loc_sqlquery(inv_query,HOST,USER,PASSWORD,DBASE);
#ifdef LOC_DEBUG
strcpy(tmp,loc_msg2str(call,";",";"));
loc_logfile(tmp);
#endif
// Erstellen eines csv - Eintrags
strcat(csv_query,call->acct_session_id);
strcat(csv_query,"\" AND acct_status_type=\"");
Anhang
| 89
Diplomarbeit
Stefan Abu Salah
strcat(csv_query,call->acct_status_type);
strcat(csv_query,"\")");
// Erzeugen eines csv - Eintrags
sql_answer = loc_sqlquery(csv_query,HOST,USER,PASSWORD,DBASE);
strcpy(tmp,sql_answer);
loc_csv( tmp );
}
else if( strstr(msg->first_line.u.request.method.s,"ACK") != NULL
&& strstr(msg->first_line.u.request.method.s,"REGISTER") == NULL
{
)
// Auslesen der Header Informationen
//call = loc_analyse_msg( msg );
//strcpy(call->acct_status_type,"ACK");
#ifdef LOC_DEBUG
//strcpy(tmp,loc_msg2str(call,";",";"));
//loc_logfile(tmp);
#endif
}
else if( strstr(msg->first_line.u.request.method.s,"SIP/2.0 483") != NULL
&& strstr(msg->first_line.u.request.method.s,"SIP/2.0 200 OK") == NULL
&& strstr(msg->first_line.u.request.method.s,"Trying") == NULL
&& strstr(msg->first_line.u.request.method.s,"trying") == NULL
&& strstr(msg->first_line.u.request.method.s,"Ringing") == NULL
&& strstr(msg->first_line.u.request.method.s,"ringing") == NULL
&& strstr(msg->first_line.u.request.method.s,"REGISTER") == NULL
&& strstr(msg->first_line.u.request.method.s,"SIP/2.0 487") == NULL )
{
// Auslesen der Header Informationen
call = loc_analyse_msg( msg );
strcat(sdp_query,call->acct_session_id);
strcat(sdp_query,"\" AND acct_status_type=");
strcat(sdp_query,"\"CANCEL\" AND bplip=\"n/a\"");
strcat(sdp_query,")");
NULL )
if( (sql_answer = loc_sqlquery(sdp_query,HOST,USER,PASSWORD,DBASE)) !=
return 0;
strcpy(call->acct_status_type,"FAILED");
strcpy(tmp,loc_msg2str(call,"\",\"","\""));
strcat(tmp,")");
strcat(inv_query,tmp);
loc_sqlquery(inv_query,HOST,USER,PASSWORD,DBASE);
#ifdef LOC_DEBUG
strcpy(tmp,loc_msg2str(call,";",";"));
loc_logfile(tmp);
#endif
// Erstellen eines csv - Eintrags
strcat(csv_query,call->acct_session_id);
strcat(csv_query,"\" AND acct_status_type=\"");
strcat(csv_query,call->acct_status_type);
strcat(csv_query,"\")");
// Erzeugen eines csv - Eintrags
sql_answer = loc_sqlquery(csv_query,HOST,USER,PASSWORD,DBASE);
Anhang
| 90
Diplomarbeit
Stefan Abu Salah
strcpy(tmp,sql_answer);
loc_csv( tmp );
}
else
{
}
}
//strcpy(call->acct_status_type,"N/A");
#ifdef LOC_DEBUG
//strcpy(tmp,loc_msg2str(call,";",";"));
//loc_logfile(tmp);
#endif
return 0;
char *loc_get_address( char query[], char plip[], struct loc_csv *msg )
{
int i = 0;
char *item;
char
organisation[100]="",
url[100]="",
user[100]="",
pw[100]="",
dbase[100]="",
newquery[350]="";
char add_query[1000] = "";
item = strtok (query,";");
while (item != NULL)
{
if(i==0)
strcpy(organisation,item);
if(i==1)
strcpy(url,item);
if(i==2)
strcpy(user,item);
if(i==3)
strcpy(pw,item);
if(i==4)
strcpy(dbase,item);
if(i==5)
strcpy(newquery,item);
}
item = strtok (NULL, ";");
i++;
strcpy(add_query,newquery);
strcat(add_query,"\"");
strcat(add_query,plip);
strcat(add_query,"\"");
}
return loc_sqlquery( add_query,url,user,pw,dbase );
char *loc_get_isp( struct loc_csv* call )
{
int i = 0;
char isp_query[SQL_QUERY] = "SELECT organisation,url,user,pw,dbase,query FROM
isps WHERE (ip_from<=\"";
Anhang
| 91
Diplomarbeit
Stefan Abu Salah
char *item = NULL;
char
ip1[4] = "000",
ip2[4] = "000",
ip3[4] = "000",
ip4[4] = "000",
ip[30] = "",
tmp[SQL_QUERY] = "",
plip[PLIP] = "";
strcpy(plip,call->aplip);
strcpy(ip1,"000\0");
strcpy(ip2,"000\0");
strcpy(ip3,"000\0");
strcpy(ip4,"000\0");
item = strtok (plip,".");
while (item != NULL)
{
if(i==0)
{
strcpy(ip1,item);
}
if(i==1)
{
strcpy(ip2,item);
}
if(i==2)
{
strcpy(ip3,item);
}
if(i==3)
{
strcpy(ip4,item);
}
}
item = strtok (NULL, ".");
i++;
if(strlen(ip2)==1)
{
ip2[2] = ip2[0];
ip2[1] = '0';
ip2[0] = '0';
ip2[3] = '\0';
}
if(strlen(ip2)==2)
{
ip2[2] = ip2[1];
ip2[1] = ip2[0];
ip2[0] = '0';
ip2[3] = '\0';
}
if(strlen(ip3)==1)
{
ip3[2] = ip3[0];
ip3[1] = '0';
ip3[0] = '0';
ip3[3] = '\0';
}
if(strlen(ip3)==2)
{
ip3[2] = ip3[1];
Anhang
| 92
Diplomarbeit
Stefan Abu Salah
ip3[1] = ip3[0];
ip3[0] = '0';
ip3[3] = '\0';
}
if(strlen(ip4)==1)
{
ip4[2] = ip4[0];
ip4[1] = '0';
ip4[0] = '0';
ip4[3] = '\0';
}
if(strlen(ip4)==2)
{
ip4[2] = ip4[1];
ip4[1] = ip4[0];
ip4[0] = '0';
ip4[3] = '\0';
}
strcat(ip,ip1);
strcat(ip,ip2);
strcat(ip,ip3);
strcat(ip,ip4);
ip[12] = '\0';
strcat(isp_query,ip);
strcat(isp_query,"\" AND ip_to>=\"");
strcat(isp_query,ip);
strcat(isp_query,"\")");
if( (item = loc_sqlquery(isp_query,HOST,USER,PASSWORD,DBASE)) != NULL )
strcpy(tmp,item);
else
return NULL;
}
return loc_get_address( tmp, ip, call );
char *loc_get_msg_item( struct sip_msg* msg, char item[], char *start, char
*stop )
{
char *pt = NULL;
char tmp[200] = "";
int i = 0 , j = 0;
i=strlen(item);
if((pt = strstr(msg->first_line.u.request.method.s,item)))
{
if( start == NULL )
{
do
{
tmp[j] = pt[i];
tmp[j+1] = '\0';
j++;
i++;
}while( pt[i] != '\r' && pt[i] != '\n' && pt[i] != stop[0] );
}
else
{
do
{
if( pt[i] == start[0] && pt[i+1] == start[1] && pt[i+2]
Anhang
| 93
Diplomarbeit
Stefan Abu Salah
== start[2] )
{
[i+3] != stop[0] );
do
{
tmp[j] = pt[i+3];
tmp[j+1] = '\0';
j++;
i++;
}while( pt[i+3] != '\r' && pt[i+3] != '\n' && pt
}
i++;
}while( pt[i] != '\r' && pt[i] != '\n' );
}
else
{
}
}
strcpy(tmp,"n/a");
if( strcmp(tmp,"") == 0 )
strcpy(tmp,"n/a");
}
pt = tmp;
return pt;
char *loc_sql2csv( struct sip_msg* msg )
{
char *csv = NULL;
//char csv_query[SQL_QUERY] = "SELECT * FROM connection WHERE
(acct_session_id=\"";
}
return csv;
char *loc_sqlquery( char query[],char url[], char user[], char pw[], char dbase
[] )
{
MYSQL *sql;
MYSQL_RES *result;
MYSQL_ROW row;
int count = 0, i = 0;
char *answer = NULL;
char tmp[1000] = "",
sql_answer_log[1000] = " ==> ";
// Initialisierung der SQL Verbindung
sql = mysql_init(NULL);
#ifdef SQL_QUERY_LOG
loc_logfile(query);
#endif
if( sql == NULL )
{
return NULL;
Anhang
| 94
Diplomarbeit
Stefan Abu Salah
}
// Verbindung mit dem Server wird aufgebaut ...
//if( mysql_real_connect(sql,HOST,USER,PASSWORD,DBASE,PORT,SOCKET,FLAG ) ==
NULL )
if( mysql_real_connect(sql,url,user,pw,dbase,PORT,SOCKET,FLAG ) == NULL )
{
// Trennen der Verbindung
answer = mysql_error(sql);
strcpy(tmp,answer);
loc_logfile(answer);
mysql_close(sql);
return NULL;
}
if(strstr(query,"SELECT") != NULL)
{
// Erfolgreich Verbunden. Nun kommen die Abfragen der DB
// Nachschauen ob plip zu dem zeitpunkt vergeben war, wenn ja
// speichern der Addresse und des names in der Variablen
// address
if( mysql_real_query( sql,query,strlen(query) ) != 0 )
{
// Fehler in der Anfrage
answer = mysql_error(sql);
strcpy(tmp,answer);
loc_logfile(answer);
mysql_close(sql);
return NULL;
}
else
{
result = mysql_store_result( sql );
count = mysql_num_fields( result );
while( (row = mysql_fetch_row( result )) )
{
for( i=0;i<count;i++)
{
strcat(tmp,row[i]);
strcat(tmp,";");
}
answer = tmp;
}
mysql_free_result(result);
// Trennen der Verbindung
mysql_close(sql);
#ifdef SQL_ANSWER_LOG
strcat(sql_answer_log,tmp);
loc_logfile(sql_answer_log);
#endif
if( strlen(sql_answer_log) < 10 )
{
loc_logfile("NULL mal NULL ist NULL ist NULL");
return NULL;
}
// Rückgabe der Addressdaten
return answer;
Anhang
| 95
Diplomarbeit
Stefan Abu Salah
}
}
else if(strstr(query,"INSERT") != NULL || strstr(query,"UPDATE") != NULL )
{
hin!
if( mysql_real_query( sql,query,strlen(query) ) != 0 )
{
// Fehler in der Anfrage
answer = mysql_error(sql);
strcpy(tmp,answer);
loc_logfile(answer);
mysql_close(sql);
return NULL;// hier muss noch eine "richtige" Dateischreiberei
}
}
else if(strstr(query,"DELETE") != NULL)
{
mysql_close(sql);
}
mysql_close(sql);
return NULL;
}
void loc_logfile( char item[] )
{
// hier muss noch eine "richtige" Dateischreiberei hin!
FILE *log;
char logpath[1000] = "/usr/local/var/log/ser/log/log-";
char item_str[10000] = "";
char tmp[1000] = "";
strcpy(tmp,loc_realtime("%Y%m%d"));
strcat(logpath,tmp);
strcpy(item_str,loc_realtime("%H:%M:%S : "));
strcat(item_str,item);
//strcat(item_str,'\n');
item_str[strlen(item_str)] = '\n';
log = fopen(logpath,"a+");
if( log==NULL )
{
return;
}
fprintf(log,"%s",item_str);
fclose(log);
}
void loc_csv( char item[] )
{
// hier muss noch eine "richtige" Dateischreiberei hin!
FILE *csv;
char item_str[10000] = "";
char csvpath[1000] = "/usr/local/var/log/ser/csv/detail-";
char tmp[1000] ="";
Anhang
| 96
Diplomarbeit
Stefan Abu Salah
strcpy(tmp,loc_realtime("%Y%m%d"));
strcat(csvpath,tmp);
strcat(csvpath,".csv");
strcpy(item_str,item);
item_str[strlen(item_str)] = '\n';
//strcat(item_str,'\n');
csv = fopen(csvpath,"a+");
}
if( csv==NULL )
{
return;
}
fprintf(csv,"%s",item_str);
fclose(csv);
char *loc_realtime( char format[] )
{
time_t event_time;
char *realtime = NULL;
char realt[100];
time(&event_time);
// format zB : "%Y%m%d%H%M%S"
strftime( realt, sizeof(realt),format,localtime(&event_time));
realtime = realt;
}
return realtime;
char *loc_timestamp( void )
{
time_t event_time;
char *timestamp = NULL;
char timest[100];
sprintf(timest,"%ld",time(&event_time) );
timestamp = timest;
}
return timestamp;
/* ########## ENDE DER ERWEITERUNG ########### */
Anhang
| 97
Diplomarbeit
Stefan Abu Salah
19.2 Änderungen am Quellcode des RTPProxy : main.c
/*
/*
/*
/*
/*
######## ERWEITERUNG LOKALISIERUNG ########
#
Diplomarbeit
#
#
Stefan Abu Salah 22.07.2005
#
###########################################
#
# Watchdog Implementierung
#
###########################################
*/
*/
*/
*/
*/
#include <mysql/mysql.h>
#define LOG_STREAMS
// Datenbankeinstellungen
#define HOST "localhost"
#define USER "debian-sys-maint"
#define PASSWORD "k8WmUQg2rumvueLk"
#define DBASE "tecon"
#define SOCKET NULL
#define PORT 3306
#define FLAG 0
#define SQL_QUERY 2000
// Angaben in Sekunden
#define STREAM_UPDATE 60
#define SQL_UPDATE 120
// Struktur zur Aufnahme der Verbindungen
struct rtp_streams
{
long int timestamp;
char call_id[100];
struct rtp_streams *next;
};
struct rtp_streams *first_stream;
// Funktionsprototypen
struct rtp_streams * add_rtp_stream( char call_id[], long int );
void del_rtp_stream( char call_id[] );
void log_rtp_stream( struct rtp_streams * stream ,char []);
struct rtp_streams * search_rtp_stream( char call_id[] );
void chk_rtp_stream( char call_id[] );
void rtp_stream2sql( );
char *loc_sqlquery( char query[],char url[], char user[], char pw[], char dbase
[] );
char *loc_realtime( char format[] );
char *loc_timestamp( void );
/* ########################################### */
...
if (sp->addr[sidx] == NULL || GET_RTP(sp)->rtps[sidx] != NULL) {
sp->pcount[3]++;
goto do_record;
}
Anhang
| 98
Diplomarbeit
Stefan Abu Salah
/*
/*
/*
/*
/*
######## ERWEITERUNG LOKALISIERUNG ########
#
Diplomarbeit
#
#
Stefan Abu Salah 22.07.2005
#
###########################################
#
# Watchdog Implementierung
#
###########################################
*/
*/
*/
*/
*/
time_t event_time;
char tmp[1000]="";
// Jede Minute nachschaen ob der rtp-Stream noch läuft
if( (time(&event_time) % STREAM_UPDATE) == 0 )
{
// Ist der RTP-Stream mit der Kennung "callid" noch nicht aktualisiert
worden?
if( chk_new_rtp_stream( sp->call_id, time(&event_time) ) != 0 )
{
chk_rtp_stream( sp->call_id );
if( (time(&event_time) % SQL_UPDATE) == 0 )
rtp_stream2sql( );
}
}
/* ########################################### */
sp->pcount[2]++;
for (i = (dmode && len < LBR_THRS) ? 2 : 1; i > 0; i--) {
sendto(sp->fds[sidx], buf, len, 0, sp->addr[sidx],
...
/*
/*
/*
/*
/*
######## ERWEITERUNG LOKALISIERUNG ########
#
Diplomarbeit
#
#
Stefan Abu Salah 22.07.2005
#
###########################################
#
# Watchdog Implementierung
#
###########################################
struct rtp_streams *
{
*/
*/
*/
*/
*/
add_rtp_stream( char call_id[], long int timestamp )
static struct rtp_streams *pt;
if( first_stream == NULL )
{
if((first_stream = (struct rtp_streams *) malloc(sizeof(struct
rtp_streams))) == NULL)
return;
first_stream->timestamp=timestamp;
strcpy(first_stream->call_id,call_id);
Anhang
| 99
Diplomarbeit
Stefan Abu Salah
}
else
{
first_stream->next=NULL;
pt = first_stream;
pt=first_stream;
while(pt->next != NULL)
pt=pt->next;
if((pt->next =(struct rtp_streams *)malloc(sizeof(struct
rtp_streams))) == NULL)
return;
pt->timestamp=timestamp;
strcpy(pt->call_id,call_id);
pt->next=NULL;
}
}
return pt;
void del_rtp_stream( char call_id[] )
{
struct rtp_streams *pt, *pt1;
if(first_stream != NULL)
{
if(strcmp(first_stream->call_id,call_id) == 0)
{
pt=first_stream->next;
free(first_stream);
first_stream=pt;
}
else
{
pt=first_stream;
while(pt->next != NULL)
{
pt1=pt->next;
if(strcmp(pt1->call_id,call_id) == 0)
{
pt->next=pt1->next;
free(pt1);
break;
}
pt=pt1;
}
}
}
}
int chk_new_rtp_stream( char call_id[] , int event_time )
{
struct rtp_streams *pt;
pt = first_stream;
if( pt != NULL )
{
if( strcmp(pt->call_id,call_id) == 0 )
if( pt->timestamp == event_time )
return 0;
else
return -1;
Anhang
| 100
Diplomarbeit
Stefan Abu Salah
while( pt->next != NULL )
{
if( strcmp(pt->call_id,call_id) == 0 )
if( pt->timestamp == event_time )
return 0;
else
return -1;
pt=pt->next;
}
}
// kein Eintrag gefunden
return -1;
}
void chk_rtp_stream( char call_id[] )
{
struct rtp_streams * stream;
time_t event_time;
// Suche nach der Callid in den bereits gespeicherten streams
if( (stream = search_rtp_stream( call_id ) ) != NULL )
{
// wenn die Callid gefunden wurde, ändere das Feld timestamp auf den
aktuellen Wert
stream->timestamp = time(&event_time);
}
else
{
// Wurde diese Callid nicht gefunden, lege einen neuen Datensatz an
stream = add_rtp_stream( call_id, time(&event_time) );
}
log_rtp_stream(stream,NULL);
}
struct rtp_streams * search_rtp_stream( char call_id[] )
{
static struct rtp_streams *pt;
pt = first_stream;
if( pt != NULL )
{
if( strcmp(pt->call_id,call_id) == 0 )
return pt;
}
while( pt->next != NULL )
{
if( strcmp(pt->call_id,call_id) == 0 )
return pt;
pt=pt->next;
}
return NULL;
}
void rtp_stream2sql( )
{
struct rtp_streams *pt;
Anhang
| 101
Diplomarbeit
Stefan Abu Salah
char
char
char
char
char
char
query[SQL_QUERY] = "UPDATE connection SET ";
query1[SQL_QUERY]= "WHERE acct_session_id=";
sql_acct_status_type[SQL_QUERY] ="acct_status_type=";
end_time[SQL_QUERY] ="end_time=";
end_realtime[SQL_QUERY] ="end_realtime=";
tmp[100] ="";
char query_tmp[SQL_QUERY] ="";
pt = first_stream;
if( pt != NULL )
{
// SQL UPDATE
strcpy(query_tmp,query);
strcat(query_tmp,end_time);
strcat(query_tmp,"\"");
strcpy(tmp,loc_timestamp());
strcat(query_tmp,tmp);
strcat(query_tmp,"\",");
strcat(query_tmp,end_realtime);
strcat(query_tmp,"\"");
strcpy(tmp,loc_realtime("%Y%m%d%H%M%S"));
strcat(query_tmp,tmp);
strcat(query_tmp,"\"");
strcat(query_tmp,query1);
strcat(query_tmp,"\"");
strcat(query_tmp,pt->call_id);
strcat(query_tmp,"\"");
loc_sqlquery(query_tmp,HOST,USER,PASSWORD,DBASE);
while( pt->next != NULL )
{
// SQL UPDATE
strcpy(query_tmp,query);
strcat(query_tmp,end_time);
strcat(query_tmp,"\"");
strcpy(tmp,loc_timestamp());
strcat(query_tmp,tmp);
strcat(query_tmp,"\",");
strcat(query_tmp,end_realtime);
strcat(query_tmp,"\"");
strcpy(tmp,loc_realtime("%Y%m%d%H%M%S"));
strcat(query_tmp,tmp);
strcat(query_tmp,"\"");
strcat(query_tmp,query1);
strcat(query_tmp,"\"");
strcat(query_tmp,pt->call_id);
strcat(query_tmp,"\"");
loc_sqlquery(query_tmp,HOST,USER,PASSWORD,DBASE);
}
}
pt=pt->next;
}
void log_rtp_stream( struct rtp_streams * stream, char test[] )
{
// hier muss noch eine "richtige" Dateischreiberei hin!
FILE *log;
Anhang
| 102
Diplomarbeit
Stefan Abu Salah
char item_str[10000] = "";
char path[1000] = "/usr/local/var/log/rtpproxy/test";
char tmp[1000] ="";
if(stream != NULL ){
sprintf(tmp,"%ld",stream->timestamp);
strcpy(item_str,tmp);
strcat(item_str," ");
strcat(item_str,stream->call_id);
}
if(test != NULL)
{
strcat(item_str," ");
strcat(item_str,test);
}
item_str[strlen(item_str)] = '\n';
log = fopen(path,"a+");
if( log==NULL )
{
return;
}
fprintf(log,"%s",item_str);
fclose(log);
}
char *loc_sqlquery( char query[],char url[], char user[], char pw[], char dbase
[] )
{
MYSQL *sql;
MYSQL_RES *result;
MYSQL_ROW row;
int count = 0, i = 0;
char *answer = NULL;
char tmp[1000] = "",
sql_answer_log[1000] = " ==> ";
// Initialisierung der SQL Verbindung
sql = mysql_init(NULL);
#ifdef SQL_QUERY_LOG
loc_logfile(query);
#endif
if( sql == NULL )
{
return NULL;
}
// Verbindung mit dem Server wird aufgebaut ...
//if( mysql_real_connect(sql,HOST,USER,PASSWORD,DBASE,PORT,SOCKET,FLAG ) ==
NULL )
if( mysql_real_connect(sql,url,user,pw,dbase,PORT,SOCKET,FLAG ) == NULL )
{
// Trennen der Verbindung
answer = mysql_error(sql);
strcpy(tmp,answer);
//loc_logfile(answer);
mysql_close(sql);
return NULL;
}
Anhang
| 103
Diplomarbeit
Stefan Abu Salah
if(strstr(query,"SELECT") != NULL)
{
// Erfolgreich Verbunden. Nun kommen die Abfragen der DB
// Nachschauen ob plip zu dem zeitpunkt vergeben war, wenn ja
// speichern der Addresse und des names in der Variablen
// address
if( mysql_real_query( sql,query,strlen(query) ) != 0 )
{
// Fehler in der Anfrage
answer = mysql_error(sql);
strcpy(tmp,answer);
//loc_logfile(answer);
mysql_close(sql);
return NULL;
}
else
{
result = mysql_store_result( sql );
count = mysql_num_fields( result );
while( (row = mysql_fetch_row( result )) )
{
for( i=0;i<count;i++)
{
strcat(tmp,row[i]);
strcat(tmp,";");
}
answer = tmp;
}
mysql_free_result(result);
// Trennen der Verbindung
mysql_close(sql);
#ifdef SQL_ANSWER_LOG
strcat(sql_answer_log,tmp);
//loc_logfile(sql_answer_log);
#endif
}
// Rückgabe der Addressdaten
return answer;
}
else if(strstr(query,"INSERT") != NULL || strstr(query,"UPDATE") != NULL )
{
hin!
if( mysql_real_query( sql,query,strlen(query) ) != 0 )
{
// Fehler in der Anfrage
answer = mysql_error(sql);
strcpy(tmp,answer);
//loc_logfile(answer);
mysql_close(sql);
return NULL;// hier muss noch eine "richtige" Dateischreiberei
}
}
else if(strstr(query,"DELETE") != NULL)
Anhang
| 104
Diplomarbeit
Stefan Abu Salah
{
mysql_close(sql);
}
mysql_close(sql);
return NULL;
}
char *loc_realtime( char format[] )
{
time_t event_time;
char *realtime = NULL;
char realt[100];
time(&event_time);
// format zB : "%Y%m%d%H%M%S"
strftime( realt, sizeof(realt),format,localtime(&event_time));
realtime = realt;
}
return realtime;
char *loc_timestamp( void )
{
time_t event_time;
char *timestamp = NULL;
char timest[100];
sprintf(timest,"%ld",time(&event_time) );
timestamp = timest;
}
return timestamp;
/* ########################################### */
Anhang
| 105
Diplomarbeit
Stefan Abu Salah
19.3 SER.cfg
#
# $Id: ser.cfg,v 1.21.4.1 2003/11/10 15:35:15 andrei Exp $
#
# simple quick-start config script
#
# ----------- global configuration parameters -----------------------debug=3
# debug level (cmd line: -dddddddddd)
fork=yes
log_stderror=no
# (cmd line: -E)
# Uncomment these lines to enter debugging mode
#debug=7
#fork=no
log_stderror=yes
check_via=yes
# (cmd. line: -v)
dns=no
# (cmd. line: -r)
rev_dns=no
# (cmd. line: -R)
port=5060
children=2
fifo="/tmp/ser_fifo"
listen=139.6.16.73
# ------------------ module loading ---------------------------------# Uncomment this if you want to use SQL database
# loadmodule "/usr/local/lib/ser/modules/mysql.so"
loadmodule "/usr/local/lib/ser/modules/sl.so"
loadmodule "/usr/local/lib/ser/modules/tm.so"
loadmodule "/usr/local/lib/ser/modules/rr.so"
loadmodule "/usr/local/lib/ser/modules/maxfwd.so"
loadmodule "/usr/local/lib/ser/modules/usrloc.so"
loadmodule "/usr/local/lib/ser/modules/registrar.so"
loadmodule "/usr/local/lib/ser/modules/auth_radius.so"
loadmodule "/usr/local/lib/ser/modules/acc.so"
# loadmodule "/usr/local/lib/ser/modules/"
#loadmodule "/usr/local/lib/ser/modules/auth_db.so"
# Uncomment this if you want digest authentication
# mysql.so must be loaded !
loadmodule "/usr/local/lib/ser/modules/auth.so"
# loadmodule "/usr/local/lib/ser/modules/auth_db.so"
# NAT-Traversal usw
#loadmodule "/usr/local/lib/ser/modules/mediaproxy.so"
loadmodule "/usr/local/lib/ser/modules/nathelper.so"
# ----------------- setting module-specific parameters --------------# -- usrloc params -# modparam("usrloc", "db_mode",
0)
# Uncomment this if you want to use SQL database
# for persistent storage and comment the previous line
Anhang
| 106
Diplomarbeit
Stefan Abu Salah
# modparam("usrloc", "db_mode", 2)
#
#
#
#
#
#
#
#
#
-- auth params -Uncomment if you are using auth module
modparam("auth_db", "calculate_ha1", yes)
If you set "calculate_ha1" parameter to yes (which true in this config),
uncomment also the following parameter)
modparam("auth_db", "password_column", "password")
# -- rr params -# add value to ;lr param to make some broken UAs happy
modparam("rr", "enable_full_lr", 1)
# -------- Parameter des Nathelper - Moduls -------#modparam("nathelper", "rtpproxy_sock", "udp:127.0.0.1")
modparam("nathelper", "rtpproxy_sock", "/var/run/rtpproxy.sock")
modparam("acc","radius_config","/usr/local/etc/radiusclient/radiusclient.conf")
modparam("acc", "service_type", 15)
modparam("acc", "radius_flag", 1)
#mit z.B.
3 versuchen
modparam("acc", "radius_missed_flag", 3)
modparam("acc", "failed_transactions", 1)
modparam("acc", "report_ack", 0)
modparam("acc", "log_fmt", "miocfsu")
# -------------------------
request routing logic -------------------
# me, myself & I:
alias="139.6.16.73"
# alias="3000:0:0:12::30"
# alias="sipserver.ipv6.fh-koeln.de"
# alias="sipserver"
# main routing logic
route {
# initial sanity checks -- messages with
# max_forwars == 0, or excessively long requests,
# or those that don't addressed to us
if (!mf_process_maxfwd_header("10")) {
sl_send_reply("483", "Too Many Hops");
break;
};
if (msg:len > max_len) {
sl_send_reply("513", "Message too big");
break;
};
# route invitation request to other domains
if (!(uri == myself) && method == "INVITE") {
record_route();
if (!t_relay())
sl_reply_error();
break;
};
Anhang
| 107
Diplomarbeit
Stefan Abu Salah
if (method=="INVITE") {
log(1, "INVITE\n");
setflag(1); /* set for accounting (the same value as in log_flag!) */
};
if (method=="BYE") {
log (1, "BYE\n");
setflag(1);
};
if (method=="CANCEL") {
log (1, "CANCEL\n");
setflag(1);
};
# if (method=="NOTIFY") {
# log (1, "NOTIFY\n");
# };
if (method=="ACK") {
log (1, "ACK\n");
};
if (method=="OPTIONS") {
log (1, "OPTIONS\n");
};
if (method=="OK") {
log (1, "OK\n");
};
if (method=="CONNECTED") {
log (1, "CONNECTED\n");
};
if (method=="TRYING") {
log (1, "TRYING\n");
};
if (method=="RINGING") {
log (1, "RINGING\n");
};
if (method=="MESSAGE") {
log (1, "MESSAGE\n");
};
if (method == "REGISTER") {
# Uncomment this if you want to use digest authentication
if (!radius_www_authorize("139.6.16.73")) {
www_challenge("139.6.16.73", "0");
break;
};
if (af == inet) {
save("location_inet4");
} else {
sl_send_reply("403", "Anmeldung fehlgeschlagen!");
};
break;
};
if (method == "INVITE") {
if (lookup("location_inet4")) {
# Comment out three lines below if you want
# RTP for IPv4->IPv4 calls to go directly
# between UAs
if (af == inet) {
if (force_rtp_proxy("FAII"))
t_on_reply("1");
Anhang
| 108
Diplomarbeit
Stefan Abu Salah
unbekannt!");
};
};
} else {
sl_send_reply("403", "User nicht erreichbar oder
};
break;
if (method == "BYE" || method == "CANCEL")
unforce_rtp_proxy();
# Do strict routing if pre-loaded route headers present
if (loose_route())
{
t_relay();
break;
};
if (method == "INVITE")
{
record_route();
};
#
#
#
#
#
#
#
#
#
if( uri=~"^sip:110@.*" )
{
if( !t_relay() )
{
sl_reply_error();
break;
}
break;
};
if( !lookup("location") )
{
if( !t_relay() )
{
sl_reply_error();
};
break;
};
}
if (!t_relay())
sl_reply_error();
onreply_route[1] {
if (!(status=~"183" || status=~"200"))
break;
force_rtp_proxy("FA");
}
Anhang
| 109
Diplomarbeit
Stefan Abu Salah
19.4 Makefile.defs (SER)
Binden der MySQL-Librarys
...
ifneq ($(found_lock_method), yes)
$(warning
No locking method found so far, trying SYS V sems)
DEFS+= -DUSE_SYSV_SEM # try sys v sems
found_lock_method=yes
endif
# Mysql für Lokalisierung
LIBS+= -L/usr/include/mysql -lmysqlclient
endif
...
# ifeq ($(makefile_defs, 1)
19.5 Makefile (rtpproxy)
Binden der MySQL-Librarys
...
INSTALL_STRIP_PROGRAM = ${SHELL} $(install_sh) -c -s
LDFLAGS =
LIBOBJS =
LIBS = -L/usr/include/mysql -lmysqlclient
LTLIBOBJS =
MAINT = #
MAINTAINER_MODE_FALSE =
...
Anhang
| 110
Herunterladen