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