Univerzita Karlova v Praze Matematicko-fyzikální fakulta DIPLOMOVÁ PRÁCE
Michal Dvořák
Real-time analyzátor protokolů přenosu VolP Katedra softwarového inženýrství Vedoucí diplomové práce: Doc. Ing. Václav Jirovský, CSc. Studijní program: Informatika, Softwarové systémy
Rád bych poděkoval svému vedoucímu, docentu Václavu Jírovskému, za odborné rady a trpělivost. Dále děkuji panu inženýrovi Jiřímu Malkovskému z Českého Telecomu za poskytnutí poslední verze doporučení ITU-T H.225, H.245 a H.323 Implementers Guide.
Prohlašuji, že jsem svou diplomovou práci napsal samostatně a výhradně s použitím citovaných pramenů. Souhlasím se zapůjčováním práce. V Praze dne 8.8.2006 ",
2
Obsah 1 o protokolech voice over IP 1.1 H.323 - základní inform.ace 1.1.1 Topologie sítě H.323 1.1.2 H.323 - protokoly 1.1.3 H.225.0 Call Signalling 1.1.4 H.225.0 RAS 1.1.5 H.245 1.1.6 RTP 1.1.7 RTCP 1.1.8 Audio/video kodeky 1.1.9 Datové aplikace (V. 150, T.120, T.38) 2 Vymezení cílů práce 2.1 Jaké informace by měl program detekovat. 2.2 Předběžné technické požadavky a omezení. 3 Podrobněj analýza problému 3.1 H.323 - spojovací a rozpojovací procedury 4 Návrh implementace 4.1 Detekce hovoru 4.2 Dekódování zpráv protokolů H.225 a H.245 4.3 Návrh aplikace 4.3.1 Rozdělení aplikace do vláken 5 Detaily implementace 5.1 Důležité třídy , 5.1.1 Zachytávání a analýza dat 5.1.2 Práce se síťovými protokoly 5.1.3 výstupy programu 5.1.4 Schéma datového toku v aplikaci. 5.2 Konkrétní implementace abstraktních tříd 6 Závěr 7 Seznam použité literatury ší
3
,
5 5 5 6 6 7 7 7 7 7 7 8 8 8 10 10 14 14 16 17 17 19 19 19 21 22 24 24 27 28
Abstrakt Název práce: Real-time analyzátor protokolů přenosu Vol? Autor: Michal
Dvořák
Katedra (ústav): Katedra softwarového inženýrství Vedoucí diplomové práce: Doc. Ing. Václav Jirovský, CSc. e-mail vedoucího:
[email protected]!.cuni.cz Abstrakt: Práce má za cíl na základě studia standardů pro přenos hlasových služeb sítí internet navrhnout aplikaci pracující v reálném čase a umožňující sledovat a vyhodnocovat tento typ provozu. Práce se zaměřuje na sledování standardu H 323. Součástí práce je i implementace. Klíčová
slova: h.323 voip monitorování
Title: Real-time analyzer ofVoIP transmission protocols Author: Michal Dvořák Department: Department ofSoftware Engineering Supervisor: Doc. Ing. Václav Jirovský, CSc. Supervisor's e-mail address:
[email protected]!cuni.cz Abstract: This thesis' goal is to design an application which would allow real-time monitoring and analyzing ofservices for transferring voice over the Internet network, based on the study oj the relevant standards. The thesis focuses on monitoring the H323 standard. An implementation ts a part ojthis thesis. Keywords: h.323 voip monitoring
4
1 O protokolech voice over IP Myšlenka internetové telefonie je už poměrně stará 1, nicméně až v posledních několika letech začala být kapacita průměrných internetových linek dostatečná pro její masové uvedení do praxe. Spolu s neustálým rozšiřováním této technologie se přirozeně objevuje také potřeba tento druh komunikace monitorovat a údaje o ní zaznamenávat pro potřeby pozdější analýzy. Existuje několik různých standardů pro implementaci VoIP, v současné době jsou hlavní zajímavé dva: •
H.323 - starší standard organizace ITU-T (International Telecommunication Union, Telecommunication Section)
•
SIP -
novější
standard organizace IETF (Internet Engineering Task Force)
Tato práce bude pokrývat starší standard H.323.
1.1
H.323 - základní informace
Standard H.323 byl publikován roku 1996 jakožto základ pro datovou, hlasovou a obrazovou komunikaci v sítích s paketovým přenosem dat. Zaměřuje se obzvláště na sítě, které negarantují kvalitu služby - tedy pakety se v nich mohou ztrácet a nedají se prioritizovat. Není závislý na konkrétních síťových technologiích ani topologiích, cílem bylo, aby se dal nasadit pokud možno kdekoliv. H.323 je takzvaný "zastřešující" standard, protože se sám odkazuje na celou řadu jiných standardů ITU. Vychází ze starších telekomunikačních standardů, kupříkladu Q.931, což je signalizační protokol v síti ISDN. V síti H.323 tento protokol využívá a rozšiřuje protokol H.225. Abychom pochopili, jak vlastně síť H.323 funguje, podívejme najejí vlastnosti blíže.
1.1.1 Síť
Topologie
H.323 se skládá ze
čtyř
sítě
H.323
hlavních typů komponent (v síti nemusejí být přítomny všechny):
1. terminály 2. brány 3. správci 4. jednotky Meu
Terminály Terminály představují koncové body každého spojení v síti H.323. Terminál musí podporovat přenos zvuku pomocí standardu G.711 a řídící protokoly H.225, H.245 a RAS. Případně může podporovat jiné audio kodeky, přenos videa nebo dat.
Brány Brána slouží k propojení sítě H.323 se sítí fungující na principu přepojování okruhů, typicky s klasickou telefonní sítí nebo s ISDN. Má za úkol konverzi různých datových formátů a řídících funkcí použitých v rámci spojení. Brána je nepovinný prvek sítě H.323. 1 Za průkopnickou práci v této oblasti se dá považovat Network Voice Protocol, který poprvé implementoval v roce 1973 Danny Cohen z University of Southem Califomia v prostředí tehdejšího ARPANETu. Protokol je popsán v RFC 741.
5
Správci
Správce (v originále Gatekeeper) patří také mezi nepovinné prvky a poskytuje různé řídící funkce. Každý správce má přidělený určitý rozsah působnosti (tzv. zónu) a všechny terminály v této zóně jsou povinny jeho služeb využívat. Hlavní funkce správce jsou překlad adres, služby pro navazování či odmítání hovorů a správa přenosového pásma. Jednotky MCU
Jednotky MeD (multipoint control unit) se používají při konferencích mezi více než dvěma uživateli. Starají se o správné navázání a ukončení vícebodového spojení, míchání audio a video proudů a správnou distribuci dat.
1.1.2
H.323 - protokoly
Jak už bylo uvedeno, je H.323 standardem zastřešujícím pod sebou řadu různých komunikačních a jiných protokolů. Na následujícím obrázku je seznam těch základních, implementovaných nad sítí TCP/IP.
RTCP
Obr. 1: Protokoly použité ve standardu H.323
Funkce jednotlivých protokolů jsou následující:
1.1.3
H.225.0 Call Signalling
Protokol Call Signalling se používá pro navázání a ukončení spojení a jeho podpora je tak pro 6
zařízení odpovídající standardu H.323 zcela klíčová - bez něj se prostě nikam nedovoláme. Je částečně založen na protokolu Q.931, což je signalizační protokol používaný v síti ISDN a jeho použití usnadňuje vzájemné propojení sítí H.323 a ISDN. Tomuto protokolu budeme nadále říkat zkráceně H.225.
1.1.4
H.225.0 RAS
Protokol pro signalizaci mezi terminálem a správcem. Pomocí něj se terminály II správce registrují a žádají o povolení navázat spojení. Tomuto protokolu budeme nadále říkat zkráceně RAS.
1.1.5
H.245
Flexibilita standardu H.323 vyžaduje, aby se koncová zařízení před zahájením audio/video komunikace dohodla na vzájemně kompatibilních nastaveních. Protokol H.245 se stará o •
výměnu
informací o schopnostech jednotlivých
zařízení
(co se
týče přenosu
zvuku a
obrazu) •
otevírání a zavírání logických kanálů (audio, video, data)
•
řízení toku dat
1.1.6
RTP
RTP (Real-time Transport Protocol) zajišťuje přenos audiovizuálních dat v reálném čase. Přenos se provádí pomocí paketů, kdy každý paket je opatřen časovým razítkem a číslem v sekvenci, což umožňuje cílovému zařízení přehrát pakety ve správném pořadí, co nejlépe se vyrovnat se ztrátou paketu, případně zahodit duplicitní pakety.
1.1.7
RTCP
Real-time Transport Control Protocol. funkce.
1.1.8
protokol k RTP - implementuje jeho
řídící
Audio/video kodeky
Implementují funkce pro
1.1.9
Doplňkový
převádění
audiovizuálních informací do digitální podoby a zpět.
Datové aplikace (V.150, T.120, T.38)
Slouží pro přenos textu, obrázků či jakýchkoliv jiných dat, které je potřeba přenášet mimo základní audiovizuální kanály. Tyto protokoly nespadají do rámce této práce a v dalším textu je budeme ignorovat.
7
2 Vymezení cílů práce Výsledkem mé práce by měla být sonda, umožňující monitorovat komunikační provoz podle standardu H.323 na síti TCP/IP. Měla by být schopna zachytit hovory probíhající na jednom síťovém segmentu a zaznamenat o nich důležité statistické informace. Tyto informace by měla být schopna jednak zobrazit, jednak uložit pro pozdější zpracování. Pro jednoduchost se omezíme na hovory s dvěma koncovými body. Detekci a analýzu konferencí necháme na další případné rozšíření.
2.1
Jaké informace by měl program detekovat
Samozřejmě
v první řadě síťovou adresu volajícího a volaného, čas zahájení a hovoru. Tyto požadavky vyplývají zcela přirozeně ze zadání práce. A co dále?
ukončení
Nabízí se třeba sledování šířky přenosového pásma zabrané daným hovorem. Na druhý pohled se ovšem tato informace jeví jako méně atraktivní - programů na monitorování vytížení sítě existuje mnoho, pro získání těchto informací člověk nepotřebuje aplikaci monitorující specificky provoz VoIP. Na druhou stranu se při znalosti použitých protokolů jistě dají z probíhajícího spojení vyčíst atributy, které obecné síťové monitory nezjistí. Jako příklad byly vybrány aliasy, neboli textové popisky terminálů to, jestli při hovoru probíhala signalizace DTMF či nikoliv.
účastnících
se spojení, a
Signály DTMF představují tzv. "tónovou volbu" a jejich detekci navrhl Ing. Jiří Malkovský z Ceského Telecomu, kterému by se taková informace hodila při detekci takzvaného telekomunikačního fraudu, při kterém si někdo pronajme od ČT internetovou linku a poté skrze ni poskytuje telefonní služby. Volání přes takovou službu vypadá pak tak, že volající se přes standard H.323 připojí k poskytovatelově počítači a pak přes tónovou volbu zadá číslo telefonu, kam chce skutečně volat. Takže pokud je některý počítač podezřelý z telekomunikačního fraudu, může informace o tom, jestli při hovorech na něj směřovaných dochází či nedochází k přenosu signálů DTMF, podezření bud' potvrdit, nebo vyvrátit. '\tl
Informací, které můžeme uchovávat je samozřejmě mnohem více. Dekódování obrazu a videa v reálném čase kvůli výpočetní náročnosti (v případě mnoha hovorů naráz) pravděpodobně nepřipadá v úvahu, ani k němu není žádný zvláštní důvod. Ale audiovizuální data by se dala kupříkladu zachytávat a ukládat pro pozdější přehrání. Dal by se zapisovat seznam použitých kodeků pro každý hovor. I ta zmíněná zabraná šířka přenosového pásma by se nakonec dala měřit a ukládat. Nicméně pro základní funkčnost zcela postačí údaje uvedené v předchozích odstavcích.
2.2
Předběžné
technické požadavky a omezení
Jaké technické aspekty programu se dají určit už v této fázi? V první řadě musí program zjevně být schopen zachytávat veškerý dostupný síťový provoz. K tomuto účelu existuje na unixových systémech knihovna libpcap, na Windows její obdoba WinPcap ([1]). Což nás přivádí k otázce vývojového prostředí. vývoj bude probíhat na platformě Windows. Je to čistě z toho důvodu, že je na něj autor práce zvyklý. Pokud by se v průběhu práce ukázalo, že toto prostředí s sebou přináší nějaké nezanedbatelné nevýhody, bude zvážena možnost změny vývojové platformy na unixovou. Tak jako tak, výsledný kód by měl být pokud možno platformově nezávislý, neboť ne každý je fanoušek operačních systémů od Microsoftu. Není to sice priorita, ale snaha bude psát kód tak, aby jeho případná portace na jiný operační systém nebyla příliš složitá.
Jako programovací jazyk byl zvolen C++, který produkuje výkonný nativní binární kód a přitom umožňuje objektový přístup, který (při správném použití) vede k relativně přehlednému zdrojovému kódu. se značně objemným provozem. S objemem přenesených dat a nárůstem počtu současných spojení standardu H.323 totiž zjevně naroste i výpočetní náročnost a může se snadno stát, že ani nejvýkonnější dostupný procesor nebude potřebám real-time analýzy dostačovat. Aplikace by tudíž měla být schopna využít možností víceprocesorových strojů, z čehož vyplývá, že by měla být v každém případě vícevláknová. Tím samozřejmě vznikne přidaná práce se synchronizací jednotlivých vláken, zároveň však bude naše aplikace škálovatelná. Aplikaci by
mělo
být možné nasadit i na
sítě
Pokud se podíváme na současnou nabídku aplikací, umožňujících monitorování provozu H.323, zjistíme, že je jich velmi málo a všechny jsou komerční. Tady se naše implementace může oproti konkurenci vydělit tím, že bude otevřená a dostupná zdarma. Z toho vyplývá požadavek na to, aby, pokud při vývoji použijeme knihovny třetích stran, byly tyto pokud možno také otevřené a zdarma. Knihovna WinPcap, kterou použijeme k zachytávání síťového provozu tuto podmínku splňuje. být rozšiřitelná, a to jak ve smyslu sledování jiných komunikačních protokolů, než H.323, tak ve smyslu fungování nad jinými síťovými technologiemi, než je nejobvyklejší TCP/IP.
Nakonec by aplikace
měla
Q
3
Podrobnější
analýza problému
v této kapitole bychom se měli podrobněji podívat na to, jakou funkčnost musí naše aplikace mít, aby mohla splnit cíle uvedené v kapitole 2 a jaké problémy bude muset překonat. Začneme tím, že se podrobněji podíváme na provoz sítě H.323.
3.1
H.323 - spojovací a rozpojovací procedury
Pokud máme monitorovat hovory podle standardu H.323, musíme v první řadě umět detekovat zahájení a ukončení spojení. Podívejme se tedy podrobněji na kroky potřebné k ustavení a zrušení spojení tohoto standardu. Budeme uvažovat síť se dvěma terminály a jedním správcem. (Obrázky a popisy procedur vycházejí z dokumentu "ITU-T Recommendation H.323" [3])
Zahájení hovoru T1
---
Správce
T2
1. ARQ
------------,---,-_.,-"_.,-".".
I
I
2. ACF _.---_....-
I
~---_.-
3. SETUP
4. CALL PROCEEDING
I
1
7. ALERTING
8. CONNECT
----~
-
--
-
~
H.225.0 RAS H.225.0 Call Signalling
Obr. 2: Ustaveni hovoru
1. Terminál Tl žádá správce o povolení přístupu k sítí pomocí zprávy ARQ (Admission Request) protokolu RAS. 2. Správce povoluje terminálu Tl přístup zprávou ACF (Admission Confinn) protokolu RAS. 3. Terminál Tl posílá terminálu T2 zprávu Setup protokolu H.225 a žádá tak o spojení. 4. T2 odpovídá zprávou Call Proceeding. 5. Nyní musí T2 požádat správce o povolení přijmout hovor, činí tak znovu pomocí zprávy ARQ. 6. Správce povoluje zprávou ACF terminálu T2 přijetí hovoru. 7. Terminál T2 zpravuje terminál Tl o ustavení spojení (zatím pouze na úrovni protokolu H.225) zprávou Alerting. (Na straně T2 nyní "vyzvání telefon'") 8. Terminál T2 potvrzuje přijetí hovoru zprávou Connect protokolu H.225. (Uživatel na
1(\
straně
T2 "zvedl sluchátko".)
Zahájení hovoru - pokračování Správce
T1 l ..
T2 9. TerminalCapabilitySet
I
i I
i
10. TerminalCapabilitySetAck
~
~_1~_~~l1ni~~I<::ap~~nitySe~
.
. 12. TerminalCapabilitySetAck
I . - • • • • • • • • • • -0 . . .
__ •
"
••
0'0
.......
,.
~
... 13. Op~~LogicaIChannel
.. ~
14.0penLogicalChannelAck .............. .... ..................... .. ,,"'
,
.
"
15. OpenLogicalChannel .. ..............
....
.... ...... - ..
..
,
,
,
,
,
"
.
16. OpenLogicalChannelAck
i
~I I
I :
..................................... H.245
Obr. 3: Řidicl spojeni H.245
9. Mezi terminály je ustaven komunikační kanál protokolu H.245. Tl posílá tímto protokolem zprávu TerminalCapabilitySet, ve které dává terminálu T2 vědět, jaké audio/video/datové přenosy podporuje a s jakými kodeky. 10. T2 potvrzuje příjem zprávou TerminalCapabilitySetAck. 11. T2 posílá Tl seznam svých podporovaných formátů komunikace... 12....a Tl to zprávou TerminalCapabilitySetAck potvrzuje. 13. Tl otevírá komunikační kanál (pro přenos audia/videa/dat) zprávou openLogicalChanne1. Data tohoto kanálu budou přenášena pomocí transportního protokolu RTP. Zároveň zpráva obsahuje transportní adresu (IP adresu a port), kterou Tl vyhradil řídícímu protokolu RTCP. 14. T2 potvrzuje založení jednosměrného komunikačního kanálu (z Tl do T2) zprávou openLogicalChannelAck. Tato zpráva obsahuje transportní adresu, na které T2 očekává data tohoto kanálu. 15. T2 zprávou openLogicalChannel otevírá komunikační kanál směrem k Tl. Zpráva obsahuje také transportní adresu, na které bude T2 přijímat zprávy RTCP. 16. Tl potvrzuje založení jednosměrného komunikačního kanálu (z T2 do Tl). Potvrzující zpráva openLogicalChannelAck obsahuje transportní adresu, na které bude Tl očekávat data tohoto kanálu. Od nynějška je navázána obousměrná komunikace.
11
Průběh
hovoru T1
Správce
T2
17. RTP - multimediální data, .~
r
, 18. RTP - multimediální data p
•
•
•
•
•
•••••
Ip
......
19. zprávy RTCP
I
I
r·~~·~·~·~~~vY~T~~.
...
Obr. 4: Přenos multimediálních dat a jeho řízení
17. Tl 18. T2 19. Tl 20. T2
posílá T2 multimediální data zapouzdřená v protokolu RTP. posílá Tl multimediální data zapouzdřená v protokolu RTP. posílá T2 řídící zprávy protokolu RTCP. posílá Tl řídící zprávy protokolu RTCP.
Ukončení
hovoru T1
T2
Správce
21. EndSessionCommand
-.-o. .....
'''.'
"."...
22. EndSessionCommand
23. RELEASE COMPLETE 24. DRQ
------_._----_
24. DRQ _--.----.-..---..-----...--------- ---
.•
----,-~-- .....-~
---
25. DCF ------_ _._--_......_--_.....----..-. -.-.
-_._ __._ _ ...... .. -.. .
_~
~
..
..
'-"
-..- •..
-- - --_._'-.,..._,,_25. _-- .....DCF "'- .. _. ..
H.225.0 RAS H.225.0 Call Signalling
..................... ~ H.245
Obr. 5:
Ukončení hovoru
21. T2 zahajuje ukončení spojení. Zasílá Tl protokolem H.245 zprávu 12
22. 23. 24. 25.
EndSessionCommand. Tl potvrzuje ukončení také zprávou EndSessionCommand. T2 zakončuje hovor zprávou Release Complete protokolu H.225. Tl i T2 dávají správci vědět o ukončení hovoru zprávouDRQ (Disengage Request). Správce potvrzuje ukončení zprávou DCF (Disengage Confirm).
Uvažme nyní, jaké protokoly se komunikace podle standardu H.323 účastní a jak moc důležité pro funkci naší aplikace jsou. Nejdříve si ještě jednou vypišme seznam protokolů, které jsme viděli na obrázcích 2 až 5 a jejich funkce: •
RAS - komunikace mezi terminály a správcem - zahrnuje administrativní informace ohledně provozu sítě, účtování hovorů a podobně
•
H.225 - komunikace mezi terminály - zahrnuje ustavení a ukončení hovoru a výměnu různých informačních zpráv
•
H.245 - komunikace mezi terminály - zahrnuje řídící informace nezbytné pro správnou výměnu audiovizuálních a jiných dat
•
RTP - komunikace mezi terminály - zajišťuje přenos samotných audiovizuálních dat
•
RTCP - komunikace mezi terminály provoz spojení RTP
zajišťuje přenos
zpráv
ovlivňujících
a
řídících
Protokol RAS můžeme ze svých úvah zcela vypustit. Na první pohled by se sice zdál jako ideální zdroj informací - terminály v něm správci posílají informace o započatých a ukončených hovorech, ale a) správce v síti nemusí vůbec být, b) i když v ní je, nemusí nutně komunikace mezi ním a terminálem procházet naším segmentem sítě, zatímco spojení terminálu s jiným terminálem může, a bylo by trapné, kdyby v takovém případě naše sonda nebyla schopna žádné informace poskytnout. Protokolem, který nás bude naopak eminentně zajímat, je H.225. Komunikační kanál tohoto protokolu se naváže jako první a ukončí jako poslední a jeho zprávy SETUP, CONNECr a RELEASE COMPLETE představují přirozené ohraničení hovoru. Zároveň nám tento protokol, na rozdíl od ostatních, poskytne i informace o odmítnutých hovorech (tj. hovorech, kde druhá strana nezvedla sluchátko). Protokol H.245 není pro provoz sondy tak podstatný, nicméně i z něj se dají získat některé zajímavé informace. Například se zde dají nalézt informace o odeslání signálu DTMF, konkrétně ve zprávě Indication, (která na obrázcích není uvedena, ale je popsána ve specifikaci H.245). Protokoly RTP a RTCP jsou zhruba na hranici či spíše těsně za hranicí rámce, který jsme si pro tuto práci vytyčili. Sondu by mělo být možné o zachytávání těchto protokolů pokud možno bezbolestně rozšířit, ale v základní implementaci je tato funkčnost nadbytečná.
13
4 Návrh implementace Nyní máme dostatečné informace pro to, abychom by měl náš program mít?
začali
vymýšlet implementaci. Jaké
části
•
Zaprvé to bude samozřejmě část, která bude (s pomocí knihovny WinPcap) zachytávat síťové pakety a předávat je k dalšímu zpracování.
•
Zachycené pakety se budou muset nějakou dobu skladovat - mohou totiž dojít ve špatném pořadí a ve chvíli, kdy detekuje začátek spojení H.323 by už další jeho pakety mohly být ztracené.
•
Zachycování paketů se provádí na linkové vrstvě. Budeme tudíž potřebovat kód, který z nich dokáže vybrat, případně sestavit, data síťové, transportní a aplikační vrstvy. Pokud chceme zachovat možnost rozšiřitelnosti o jiné síťové technologie než TCP/IP, měl by se tento síťový kód oddělen od zbytku aplikace vrstvou abstrakce.
•
Další část kódu se musí starat o sledování a dekódování dat protokolů standardu H.323 a produkování výstupů. Pokud chceme zachovat rozšiřitelnost o další sledované standardy VoIP, měla by i tato část kódu být oddělena od zbytku vrstvou abstrakce.
To by tedy byl návrh na té nejobecnější úrovni. Pojďme se velmi hrubě navržených komponent naší aplikace.
4.1
teď
zamyslet nad detaily
těchto
Detekce hovoru
Prvním detailem, který nám zjevně chybí na cestě k funkčnímu programu, je způsob, jakým detekovat síťové spojení dle standardu 11.323. Máme část kódu 'A', která zachytává síťová data, a část 'B', která analyzuje protokoly H.323, ale zatím nevíme, jak by měla část 'A' poznat, která data má posílat části 'B' a která nikoliv. Analýza spojovacích a rozpojovacích procedur v kapitole 3 vede k závěru, že bychom se měli snažit o detekci protokolu H.225. Toto spojení existuje po celou dobu hovoru, navazuje se jako první a ruší jako poslední. Pokud dostane analyzátor toto spojení k ruce, dokáže si z něj už informace o dalších probíhajících spojeních získat a zachytávací části si o ně říct. Další věc, kterou o spojení H.225 víme, je, že první zpráva, která po zpráva SETUP.
něm
projde, je vždy
Abychom mohli začít sledovat spojení protokolu H.225, musíme v první řadě vymyslet způsob, jakým je v záplavě síťových paketů rozpoznat. Zprávy protokolu H.225 se posílají po spolehlivém spojení, v IP síti je to TCP spojení. Na úrovni linkové vrstvy, ze které dostáváme data, se ovšem i spolehlivé spojení rozpadá na jednotlivé pakety. Každý zachycený paket tudíž musíme podrobit analýze a rozhodnout, jestli představuje začátek H.225 spojení nebo ne, a pokud ano, začít ho podrobněji sledovat. Vzhledem k tomu, že paketů může být potenciálně velké množství a sonda má fungovat v reálném čase, nemůže být tato analýza příliš složitá. Pro pořádek připomeňme, že pro analýzu máme k dispozici data od linkové vrstvy výše. Standard H.323 se dá implementovat nad různými linkovými, síťovými a transportními vrstvami, přičemž jeho implementace se nad různými protokoly může lišit. Analýza tudíž může, v některých případech možná musí, vzít data nižších vrstev v úvahu. V rámci naší práce se omezíme na analýzu standardu H.323 v síti TCP/IP. Takže jaké máme možnosti:
14
1. Pustit na každý paket dekodér H.225 a zjistit, jestli dostaneme zprávu SETUP. Pokud ano, našli jsem začátek hovoru. O
výhody: analýza je dokonale přesná
O nevýhody: analýza je zbytečně výpočetně náročná. Zprávy protokolu H.225 jsou kódovány podle standardu ASN.l PER2, který není zcela triviální rozkódovat. Kromě toho se zpráva nemusí vejít do jediného paketu a dohledávání dalších paketů dále zvýší náročnost. " 2. Rídit se podle cílového portu. Terminály fungující v prostředí TCP/lP obvykle naslouchají příchozím spojením na portu 1720 (viz např. [6]). Mohli bychom tedy u každého paketu zkontrolovat, zda cílový port je 1720 a pokud ano, dál se spojením zabývat, a pokud ne, ignorovat je.
O výhody: výpočetní náročnost veškerá žádná O
nevýhody: pokud budou terminály komunikovat na jiném portu než 1720, budou jejich spojení pro naši sondu neviditelná. To jistě není dobré. Takových případů by sice nemělo být mnoho - pokud chce být terminál kompatibilní s jinými, musí posílat spojení H.225 na port 1720, ale nějaká proprietární řešení mohou teoreticky používat jiný port, a sonda by měla, pokud možno, fungovat i na nich.
3. Využijeme toho, co víme o fungování protokolu H.225 nad TCP a fungování samotného TCP. Zprávy H.225 se nejprve balí do paketů TPKT, což je formát popsaný v RFC 1006 (ISO transport services on top of the TCP, viz [2]) a byl vytvořen za účelem tunelování protokolů vyšších vrstev síťového ISO modelu skrze TCP. Použití TPKT nad TCP svým způsobem kombinuje vlastnosti protokolů TCP a UDP stejně jako UDP se data přenáší v paketech, ale na rozdíl od UDP běží po spolehlivém a spojovaném kanálu. Pakety tedy vždy dojdou na místo určení (pokud se spojení zcela nerozpadne) a dojdou ve stejném pořadí, v jakém byly odeslány. Formát paketu je následující (první čtyři bajty tvoří hlavičku):
C ~:jr~~- ]r~~:~~~J~=~~~~~~~p~~i~J_1
~~jt 5
n data paketu oe
Obr. 6: Formátpaketu TPKT
•
verze je vždy 3
•
délka paketu je mezi 7 a 65535
Vzhledem k tomu, že TCP spojení se na síťové vrstvě rozpadá na pakety typicky o jiné délce, než je délka paketu TPKT, může se hlavička obecně nacházet prakticky na libovolné pozici TCP paketu. Nicméně vzhledem k tomu, že zpráva SETUP protokolu H.225 je vždy první zpráva, která po daném kanálu přenese, víme, že hlavička jejího TPKT paketu bude hned na začátku dat prvního TCP paketu. Z toho nám vyplývá jednoduchá analýza - u každého paketu zkontrolujeme, jestli patří do protokolu TCP, pokud ano, tak jestli má první bajt po TCP hlavičce hodnotu 3 a třetí a čtvrtý bajt reprezentují šestnáctibitové číslo větší nebo rovno 7, a pokud teprve pokud jsou všechny tyto podmínky splněné, budeme se jím dále zabývat. O výhody: výpočetní nenáročnost -
naprostou většinu paketů můžeme rovnou vyřadit jako nezajímavé, jen TCP pakety, které začínají trojkou podrobíme dalšímu zkoumání. Zároveň tím zachytíme i taková spojení, která by se odehrávala na
2
ASN.l = Abstract Syntax Notation One je telekomunikačnístandard pro popisování datových struktur. PER = Packed Encoding Rules je způsob uložení zpráv ASN.l v komprimovaném tvaru.
15
I!
nestandardním portu. O nevýhody: oproti možnosti 2 větší počet chybných pozitivních výsledků analýzypři předpokladu posílání náhodných dat přes protokol TCP bude trojkou začínat každý 256. paket, který pak budeme zbytečně podrobněji analyzovat. Na druhou stranu také oproti možnosti 2 tu budeme mít nulové množství chybných negativních výsledků.
V naší práci byla nakonec po zvážení všech výhod a nevýhod implementována metoda 3. Pokud by se ukázal počet chybných pozitivních výsledků předběžné analýzy paketu jako příliš vysoký, můžeme ho dále snížit podmínkou, že druhý bajt hlavičky TPKT musí být O. Tím by se počet chybných pozitivních výsledků snížil na zhruba 1 z 65536. Tento požadavek byl ale zahrnut až do třetí verze specifikace protokolu H.225, mohlo by se tudíž stát, že zařízení vyrobená podle první nebo druhé verze ho nebudou dodržovat.
4.2
Dekódování zpráv protokolů H.225 a H.245
Standardy ITU H.225 a H.245 ([4] a [5]) definují zprávy těchto dvou protokolů pomocí ASN.1, což je formální jazyk pro abstraktní popis datových struktur. Je to společný standard organizací ISO a ITU. Pro tento jazyk existuje několik dodatečných. standardů definujících různé soubory pravidel pro převod těchto datových struktur do digitální podoby. Pro H.225 i H.245 se používají pravidla PER (Packed Encoding Rules). Vzhledem k tomu, že dekódování A8N.1 PER je poměrně netriviální, je to výborný kandidát na použití kódu nějaké třetí strany. Bohužel pro nás jsou dekodéry tohoto standardu v naprosté většině komerční, a ty, co jsou přístupné zdarma, nejsou příliš funkční. Proto se jako nejlepší šance jeví znovupoužití dekódovacích částí některé volně dostupné implementace standardu H.323. Nejstarší, a po dlouhou dobu jediná, taková implementace je OpenH323 ([7]), od konce roku 2004 mu konkuruje "Objective Open H.323 for C" (ooh323c) ([8]) od firmy Objective Systems. Tato firma je výrobcem kompilátoru' datových struktur A8N.l jménem ASN1C. Tento kompilátor je (podle očekávání) komerční, nicméně pomocí něj vyvinutý framework pro implementaci standardu H.323 byl uvolněn jako open source zdarma pod licencí OPL. Tento framework byl použit, neboť autorovi připadal mnohem přehlednější a pochopitelnější než odpovídající části programu OpenH323.
3 Kompilátor jazyka A8N.l dostane na vstupu popis datových struktur v jazyce A8N.l a na výstupu vygeneruje třídy v nějakém programovacím jazyku umožňující kódování a dekódování daných datových struktur.
16
4.3
Návrh aplikace
Začíná se nám tedy rýsovat rozdělení aplikace do několika funkčních celků. Z předchozí
analýzy vyplývá zhruba následující struktura: dekodér ASN. 1 PER (ooh323c)
...
~···r
analyzátor H.323 ' - - - - - - _ _--J
dekodér síťových protokolů zahaj sledován í dalšího síťového spojení (pokud je třeba)
v
I
sklad iště
paketů
.--.-.----..-..---.-.--.......
předběžná
analýza
paketů
zachytávač paketů
t WinPcap
---------
pakety na síti -
pošli data tohoto spojení anlyzátoru H.323
-
-
-
-
-
-
-
-
-
-
-
•
Obr. 7: Návrh toku dat v aplikaci
Obdélníky představují jednotlivé části (předpokládané třídy) programu, šedivé části jsou implementované kódem třetí strany. Plné šipky představují tok dat, čerchované představují signály, které slouží k řízení toku dat. Základní idea zachytávače dat je taková, že pakety, které patří již sledovaným spojením pošle skrz dekodér síťových protokolů analyzátoru H.323, ty, které nikoliv, pošle na předběžnou analýzu, na zařadí případně spojení mezi sledovaná. Všechny pakety také uloží do skladiště paketů pro (případné) pozdější využití. Předběžná
analýza má za cíl pouze co nejrychleji rozhodnout, jestli je daný paket zajímavý nebo ne. Pokud ano, začne se spojení podrobněji sledovat a analyzovat. Funkce ostatních částí by
4.3.1
měla
něčím
být z obrázku zřejmá.
Rozdělení
aplikace do vláken
Nyní, když máme již hrubou představu, jak by naše aplikace měla fungovat, nastal čas vrátit se k požadavku na škálovatelnost a zamyslet se nad tím, jak by se navržená funkčnost dala rozdělit do více vláken. První celkem samozřejmý nápad je oddělit získávání dat od jejich analýzy. Zachytávač paketů spolu s předběžným analyzátorem by běžely v jednom vlákně, analýza spojení H.323 v druhém. Při takovémto rozdělení však dokážeme využít maximálně dva procesory. Kromě toho - v případě velkého množství současně probíhajících hovorů - by také mohla výpočetní náročnost druhého vlákna velmi vzrůst. To vedlo k následující implementaci:
zachytávač paketů
17
a
předběžný
analyzátor
zůstanou
nadále v jednom vlákně, ale pro analýzu každého hovoru se založí zvláštní vlákno. Toto řešení je pružnější a umožní rozklad na víceméně libovolné množství procesorů (samozřejmě shora omezené počtem právě probíhajících hovorů). Předběžný
analyzátor paketu by měl být výpočetně co nejméně náročný, takže zůstane v jednom vlákně. Kdyby se ukázalo, že výpočetní náročnost tohoto vlákna ve velké sítí příliš narůstá, mohlo by se vytvořit více instancí a pakety mezi ně dělit. Nicméně pro základní implementaci necháme předběžnou analýzu v jednom vlákně.
18
5 Detaily implementace
v
této kapitole budou popsány detaily skutečné implementace. Celý zdrojový kód je k dispozici na přiloženém CD spolu se spustitelnou podobou a testovacími daty.
5.1
Důležité třídy
5.1.1
Zachytávání a analýza dat
class NetworkReader : public Thread {
public: NetworkReader(ProtocolStack * protocolStack, packet_checkers packetCheckers, MessageRouter * router); -NetworkReader(void); virtual void Stop(void); };
Tato třída se stará o zachytávání paketů a jejich předběžnou analýzu. Pokud jsou pakety vyhodnoceny jako zajímavé, vytvoří se objekt PhonecallReader, který začne dané spojení sledovat. Každý paket se také uloží do cache, ve které nějakou dobu zůstane (to je z toho důvodu, že pakety mohou přijít v nesprávném pořadí a mohli bychom tak zahodit paket, který budeme v blízké budoucnosti potřebovat). Třída se spouští v samostatném vlákně. class NetStreamList {
public: NetStreamList(void); -NetStreamList(void) ; void add(NetStreamlnfo *streamlnfo, NetSocket *netSocket); bool remove(NetStreamlnfo *streamlnfo); bool contains(NetStreamlnfo * streamlnfo); NetSocket * getNetSocket(NetStreamlnfo * streamlnfo); void lock(void); void unlock(void); };
Třída
NetStreamList slouží jako seznam síťových spojení, která právě sledujeme. Když NetworkReader vyhodnotí nějaký paket jako zajímavý, vytvoří objekt NetSocket, který reprezentuje toto spojení a uloží ho do tohoto seznamu spolu s objektem NetStreamlnfo, který dané spojení popisuje a identifikuje. Další pakety z daného spojení už NetworkReader neanalyzuje, ale posílá je rovnou sem. Třída
obsahuje funkce na zjištění, jestli obsahuje dané spojení, funkce pro jeho přidání a odebrání. Jelikož k tomuto seznamu může přistupovat několik vláken naráz, obsahuje funkce na své zamčení a opětovné odemčení (provádí se přes mutex). class PacketCache {
public: PacketCache(void) ; -PacketCache(void); bool addPacket(packet_data * packetData); vector<packet_data *> getPackets(NetStreamlnfo * streamlnfo, ProtocolStack * protocolStack); };
Třída
PacketCache slouží jako skladiště pro zachycené pakety. Doba skladování se dá nastavit. Při přidání každého nového paketu se zároveň vymažou ty, které jsou příliš staré.
19
Funkce getPackets potom slouží k vybrání všech paketů, které patří k určitému síťovému spojení. Vrací ovšem pouze kopie paketů - idea je taková, že každý zachycený paket, bez ohledu na to, jestli je analyzován jako zajímavý nebo ne, jestli si ho někdo z cache vybere nebo ne, zůstane v cachi k dispozici po celý určený časový interval. Pak teprve bude , vymazan. class PhonecallReader : public Thread {
public: PhonecallReader(void); void setStreamList(NetStreamList * watchedStreamList); void setPacketCache(PacketCache * packetCache); virtual void setlnitialSocket(NetSocket * socket) = O; void setProtocolStack(ProtocolStack *protocolStack); void setMessageRouter(MessageRouter *router); virtual -PhonecallReader(void); inline unsigned int getPhonecallID() { return phonecallID; protected: NetSocket * startWatchingConnection(NetStreamlnfo * streamlnfo, timeval fromTime); void stopWatchingConnection(NetSocket * socket); void sendDisregardMessage(void); void sendCalllnitMessage(string callerAddress, string calleeAddress, vector<string> callerAliases, vector<string> calleeAliases, timeval time); void sendCallOpenMessage(string callerAddress, string calleeAddress, vector<string> callerAliases, vector<string> calleeAliases, timeval time); void sendCallRejectMessage(string callerAddress, string calleeAddress, vector<string> callerAliases, vector<string> calleeAliases, timeval time); void sendCallCloseMessage(string callerAddress, string calleeAddress, vector<string> callerAliases, vector<string> calleeAliases, timeval time); void sendDTMFMessage(string dtmf, timeval time); };
abstraktního předka tříd pro sledování jednoho telefonního hovoru. V naší aplikaci má pouze jednoho konkrétního potomka, kterým je třída H323CallReader pro sledování hovorů podle standardu H.323. Třída, respektive každý její potomek, se pouští v samostatném vlákně.
PhonecallReader
představuje
Mezi public funkcemi je kromě konstruktoru, destruktoru, a funkcí pro předání odkazů na některé důležité objekty zajímavá funkce setlnitialSocket, která předá instanci PhonecallReaderu první síťové spojení, které má začít sledovat - totiž to spojení, které NetworkReader při předběžné analýze vyhodnotil jako zajímavé. Protected část obsahuje několik funkcí, které budou typicky pročež jsou implementované už tady.
•
potřebovat
všichni potomci,
startWatchingConnection vytvoří NetSocket pro sledování spojení popsaného objektem streamlnfo a zařadí jej do seznamu NetStreamList. Parametr fromTime představuje
hranici v
dispozici nějaké
čase,
od které se má dané spojení sledovat. Pokud z dřívější pakety, budou se ignorovat.
něj
máme k
•
stopWatchingConnection odstraní dané spojení ze seznamu NetStreamList.
•
sendCall/nitMessage, sendCallOpenMessage, sendCa//RejectMessage, sendCallCloseMessage a sendDTMFMessage slouží k zasílání zpráv na front-end o funkce
tom, že daný hovor byl inicializován, přijat, odmítnut, ukončen nebo že došlo k přenosu impulsu DTMF. sendDisregardMessage pošle front-endu zprávu, že má všechny předchozí zprávy o daném hovoru ignorovat. 20
5.1.2
Práce se sít'ovými protokoly
Protokoly standardu H.323 (či jiných sledovaných standardů) nemusejí být provozovány pouze nad sítí TCP/lP, ale i nad jinými (kupříkladu IPx/SPX, nebo IPv6). Ačkoliv v současné implementaci naše sonda pracuje pouze s TCP/lP, měla by být připravena na přidání podpory dalších síťových prostředí. Z toho vyplývá požadavek na striktní oddělení kódu tříd zděděných ze třídy PhonecallReader od kódu zajišťující podporu síťových a transportních protokolů. Stejně tak i co nejvíc ostatních částí sondy by mělo být nezávislých na síťové platformě, aby byly v případě rozšíření jednoduše znovupoužitelné. To vedlo k vytvoření následující abstraktní třídy ProtocolStack, která zajišťuje abstraktní přístup k síťovým a transportním protokolům a datům: class ProtocolStack {
public: virtual int getProtocolStackld(void); virtual bool getNetworkPacketlnfo(const u_char * networkPacket, packet_data * info); virtual NetStrearnlnfo * getNetStrearnlnfo(const packet_data * packetData, NetStreamlnfo * strearnlnfo); virtual NetStrearnlnfo * getReversedDirectionStreamlnfo( NetStreamlnfo * strearnlnfo); virtual NetSocket * createNetSocket(NetStreamlnfo * strearnlnfo); virtual bool packetBelongs(NetStrearnlnfo *streamlnfo, const packet_data * packetData); virtual NetStrearnlnfo * getNetStrearnlnfo(NetSocket * socket); };
Použité datové struktury: •
packet_data je datová struktura uchovávající v sobě data zachyceného paketu, informace o použitém linkovém, síťovém a transportním protokolu a odkazy na začátek dat síťové, transportní a aplikační vrstvy v datech paketu
•
NetStreamlnfo je (abstraktní) třída popisující jedno konkrétní spojení probíhající ve sledované síti. V síti TCP/IP popisuje data tekoucí z jedné IP adresy a jednoho portu do druhé IP adresy a druhého portu.
•
NetSocket je abstraktní třída, která extrahuje aplikační data z paketů jednoho síťového spojení. Z ní jsou zděděny dvě abstraktní třídyContinuousSocket a DatagramSocket reprezentující spojované a nespojované sockety. ContinuousSocket vrací souvislý proud dat, DatagramSocket obsahy jednotlivých paketů.
Podrobnější popis
funkcí
třídy
ProtocolStack:
•
getProtocolStackld vrací ID identifikující danou implementaci této abstraktní třídy.
•
getNetworkPacketlnfo vyplní ve vstupně/výstupní struktuře packet_data údaje o protokolech a datech síťové a transportní vrstvy. Vrací false v případě chyby.
•
getNetStreamlnfo vrátí objekt NetStreamlnfo popisující spojení, jehož částí je paket packetData. V rámci optimalizace výkonu znovupoužije již existující objekt streamlnfo, pokud ho dostane.
•
getReversedDirectionStreamlnfo - vzhledem k tomu, že NetStreamlnfo popisuje spojení pouze v jednom směru, slouží tato funkce k vytvoření objektu popisujícího stejné spojení v opačném směru.
•
createNetSocket vytvoří objekt NetSocket, který bude v našem programu reprezentovat spojení odpovídající popisnému objektu streamlnfo.
21
•
packetBelongs vrací trne, pokud daný paket patří do daného síťového spojení.
•
getNetStreamlnfo je pomocná funkce, která vytvoří objekt NetStreamlnfo popisující spojení reprezentované daným objektem NetSocket.
Tato vrstva abstrakce umožňuje maximální možné oddělení tříd Phonecal/Reader od síťových protokolů, nad kterými běží. Bohužel ne ve všech případech je možné stoprocentní oddělení. Jedna část kódu, která většinou s abstraktní vrstvou pracovat nebude je předběžný analyzátor paketů, který určuje, jestli dané síťové spojení vypadá zajímavě nebo ne. Vzhledem k tomu, že tato analýza se provádí nad každým paketem, provádět pokaždé přechod do abstraktní vrstvy by jednak nebylo příliš efektivní, za druhé by nás to připravilo o informace z nižších síťových vrstev, které nám při této předběžné analýze mohou pomoci. kdy použití abstraktní vrstvy není možné, je otevírání nových komunikačních kanálů. Kupříkladu ve třídě H323Ca//Reader začínáme se známým komunikačním kanálem H.225, ale (pokud všechno probíhá správně), dostaneme na něm brzy zprávu s údaji o transportní adrese, na které se otevře kanál protokolu H.245 a potřebujeme tudíž síťové vrstvě nějak sdělit, že toto spojení potřebujeme také sledovat. To bohužel nejde udělat bez kusu kódu, který rozumí jak datům protokolu H.225, tak síťové vrstvě, nad kterou tento protokol Druhý
případ,
běží.
Tento kus kódu je tomto případě oddělen od zbytku třídy H323Ca/1Reader do zdrojového souboru h323_network_support.cpp. Jedná se však pouze o tři nepříliš rozsáhlé funkce a jinak je H323Ca//Reader od síťové vrstvy zcela oddělen, Linková vrstva
S linkovou vrstvou se v aplikaci příliš nepracuje, jediná funkce, která je na ní použita, je globální funkce getNetworkLayerPacket, která vrátí na paketu linkové vrstvy odkaz na data síťové vrstvy. Tato funkce je momentálně definována pouze pro linkovou vrstvu typu Ethernet, ale neměl by být problém rozšířit ji o libovolnou další linkovou vrstvu.
5.1.3
výstupy programu
Jedna oblast, kterou jsme při návrhu aplikace trochu přešli, jsou aplikační výstupy. Vzhledem k tomu, že se snažíme naši aplikaci vytvořit pokud možno rozšiřitelnou a modulární, nabízí se přirozeně požadavek na rozšiřitelnost i co se výstupů týče. Toho by se dosahovalo poměrně obtížně v případě, že by si každý PhonecallReader definoval své vlastní výstupy. Proto strukturu aplikace v tomto směru poněkud rozšíříme. V aplikaci bude definováno obecné rozhraní pro zasílání zpráva několik základních typů těchto zpráv (typu "hovor zahájen", "hovor ukončen") s několika základními atributy ("volající", "volaný" , "čas" atd.) a každý PhonecallReader bude tyto zprávy produkovat a posílat na zmíněné rozhraní. Tím dosáhneme vítané flexibility, protože (v závislosti na tom, jaké třídy pro zpracování těchto zpráv napíšeme) pak můžeme s výstupními údaji udělat prakticky cokoliv - vypsat je na konzoli, zobrazit je v grafické aplikaci, uložit do souboru, uložit do databáze, poslat e-mailem - fantazii se meze nekladou. Zmíněné
rozhraní pro zasílání zpráv má následující podobu:
class MessageRouter {
public: MessageRouter(void); -MessageRouter(void) ; void sendMessage(Message void Stop(void);
* message);
22
};
Pro každou vygenerovanou zprávu zavolá daný Phoneca//Reader funkci sendMessage a o nic víc se nemusí starat. MessageRouter tuto zprávu potom rozešle všem modulům na zpracování zpráv (viz níže). Funkce Stop potom slouží k zastavení a ukončení všech těchto modulů. Třída
Message vypadá následovně:
class Message {
public: virtual int getMessageTypeld(void); virtual bool isDescendantOf(int messageTypeld); int getSenderld(void) { return senderld; }; int getPhonecallld(void) { return phonecallld; }; void setSenderld(int id) { this->senderld = id; }; void setPhonecallld(int id) { this->phonecallld = id; virtual Message * makeCopy(void) = o;
};
};
Každá třída odvozená od typu Message má své unikátní ID, které vrací funkce getMessageTypeld. Funkce isDescendantOfvrací informaci o tom, jestli je třída dané zprávy potomkem třídy s daným ID. Senderld je pole pro identifikaci třídy odesilatele zprávy a v současné implementaci není využito. Phonecallld je unikátní identifikátor hovoru v rámci daného spuštění naší aplikace. Zprávy se stejným Phonecallld patří ke stejnému hovoru. Funkce makeCopy podle
očekávání
Samotné zpracování zpráv
slouží k vytvoření kopie zprávy.
provádějí
potomci
třídy
MessageProcessor, která vypadá
následovně:
class MessageProcessor : public Thread {
public: MessageProcessor(void); -MessageProcessor(void); virtual void sendMessage(Message
* message);
};
Třída
se pouští v samostatném vlákně (aby zpracování zpráv neblokovalo odesílající PhonecallReader), ale jinak je její rozhraní velmi jednoduché. Jediná zajímavá funkce je sendMessage, která slouží pro přijímání zpráv od MessageRouteru.
23
5.1.4
Schéma datového toku v aplikaci
Na obrázku 7 v kapitole 4 jsme viděli předběžný návrh komponent naší aplikace a datového toku mezi nimi. Ted', když už máme všechny části implementované (byť některé jen na abstraktní úrovni), můžeme si na obrázek doplnit konkrétní jména tříd. Kromě toho došlo k rozšíření návrhu o třídy pro výstup, které také doplníme.
I
MessageProcessor
1.--------
MessageRouter j~
~
dekodér ASN. 1 PER (ooh323c)
~
PhonecallReader ProtocolStack
i
zahaj sledování dalšího síťového spojení
(pokudje třeba) I
I PacketCache 141-
-
--- - - - -- --
NetworkReader
--~ ..
t WinPcap
i
-
- - - - - - - - - pakety na síti Obr. 8: Doplněná struktura aplikace s tokem dat
pošli data tohoto spojení anlyzátoru H.323
-
-
-
-
-
Předběžná
-
-
analýza paketů není nakonec implementována jako samostatná statická metoda každého konkrétního potomka třídy PhonecallReader.
5.2
Konkrétní implementace abstraktních
-
-
třída,
-
-
.
ale jako
tříd
v minulé podkapitole jsme v
seznamu tříd v některých případech uvedli pouze abstraktní třídy, které implementují rozhraní viditelné z ostatních částí programu. Tyto třídy ale pochopitelně musejí mít i potomky, kteří implementují jejich abstraktní funkce. Tady si je ,,, popiseme.
ProtocolStack Abstraktní třída ProtocolStack má jedinou implementaci, a to IPProtocoIStack, která implementuje kód pro práci se síťovými a transportními protokoly TCP/IP. Je to samozřejmě logická volba, jelikož TCP/IP je dnes zdaleka nejrozšířenější síťové prostředí a všechny volně dostupné implementace standardu H.323 (nebo alespoň všechny, které jsou autorovi známy) fungují právě nad ním. Vedle samotné třídy IPProtocolStack je definována také třída TCPUDPStreamInfo (potomek třídy NetStreamInfo) jakožto třída popisující jedno konkrétní spojení protokolem TCP nebo UDP a třída TCPSocket rozšiřující abstraktní třídu ContinuousSocket, která se stará o extrahování aplikačních dat z TCP paketů (kód je založen na informacích z [9]).
24
Logicky by se nabízela ještě třída UDPSocket, která by byla potomkem DatagramSocket a která by vracela aplikační data paketů protokolu UDP, ale vzhledem k tomu, že sledování protokolu UDP není v současné implementaci naší sondy zapotřebí, nebyla třída UDPSocket zatím implementována. PhonecallReader
PhonecallReader má taktéž jednu implementaci, a to
třídu
H323CallReader. Toto je, dalo by
se říci, nejdůležitější třída celé aplikace. Ostatní třídy jsou tu jen proto, aby této třídě umožnily fungovat a bez ní by celá práce pozbyla smyslu. Třída implementuje sledování a dekódování protokolů H.225 a H.245 a v závislosti na zachycených zprávách těchto protokolů generuje zprávy vlastní (pro komponentu MessageRouter). Pro dekódování zpráv zapsaných podle standardu ASN.l PERje použita knihovna "Objective Open H.323 for C" od firmy Objective Systems. Následuje seznam zachytávaných zpráv protokolů H.225 a H.245. Zprávy protokolu H.225: •
Každá zachycená zpráva protokolu H.225 se vypíše do logu. Následně se zkontroluje, jestli neobsahuje alias (neboli jméno) volajícího nebo volaného, pokud ano, tak se zapamatuje a pošle se v některé následující zprávě. Zkontroluje se, jestli zpráva neobsahuje informace o signálu DTMF, pokud ano, vygeneruje se zpráva PhonecallDTMFMessage. Zkontroluje se, jestli zpráva neobsahuje tunelované zprávy protokolu H.245, pokud ano, tak se zpracují.
•
SETUP - Pokud první zpráva na kanálu H.225 není SETUP, je sledování hovoru ukončeno, protože jsme se zjevně napojili někde v půlce a tento hovor by měla sledovat jiná instance H323CallReaderu. Jinak se ze zprávy vytáhnou aliasy volajícího a volaného a vygeneruje se zpráva PhonecalllnitMessage. Kromě toho se také začne sledovat síťové spojení H.225 v opačném směru. (Na začátku dostane H323CallReader ke sledování pouze jednosměrné spojení.)
•
CALL PROCEEDING - Zpráva může obsahovat informaci o transportní adrese (typicky IP adresa + port), na které očekává druhá strana data protokolu H.245. Pokud tuto informaci skutečně obsahuje, zahájí se sledování daného síťového spojení (v obou směrech).
•
ALERTING - Může obsahovat transportní adresu kanálu H.245. Postupuje se jako u zprávy CALL PROCEEDING.
•
CONNECT - Vygeneruje se zpráva PhonecallOpenMessage. Také může obsahovat transportní adresu kanálu H.245. Postupuje se stejně jako u zprávy CALL PROCEEDING.
•
FACILITY -
•
PROGRESS - I tato zpráva
•
RELEASE COMPLETE - Vygeneruje se zpráva PhonecallCloseMessage. Daná instance H323CallReaderu se ukončí.
Může
stejně
také obsahovat transportní adresu kanálu H.245. může
obsahovat transportní adresu kanálu H.245.
Zprávy protokolu H.245: •
Každá zachycená zpráva protokolu H.245 se zaloguje.
•
Indication - Může obsahovat informace o signálu DTMF. Pokud ano, vygeneruje se zpráva Phoneca/1DTMFMessage. 25
V rámci tříde je definována také statická funkce checkPacket, která provádí předběžnou analýzu paketu. Princip fungování této funkce je podrobněji popsán v podkapitole 4.1. Message
Od třídy Message je odvozena třída PhonecallMessage, od které jsou odvozeny třídy Phonecalllnitbdessage, PhonecallOpenMessage, PhonecallRejectMessage, PhonecallCloseMessage, PhonecalllnfoMessage a PhonecallDTMFMessage. Ve svých atributech mohou nést adresu a alias volajícího a volaného a čas, kdy událost nastala. MessageProcessor
Abstraktní třída MessageProcessor má dvě implementace. Za prvé je to PhonecallMessageProcessor, který data o hovorech vypisuje na konzoli a do souboru esv (comma separated values -lze importovat do většiny tabulkových procesorů). Druhou implementací je RemoteMessageProcessor, který umožňuje zprávy posílat přes TCP spojení na jiný počítač, tam je přijímat a předávat MessageRouteru. V konfiguračním souboru se dá nastavit, jestli má být RemoteMessageProcessor odesilatel nebo příjemce zpráva jestli má fungovat jako server nebo klient. Tyto dvě implementace umožňují, aby byla samotná sonda spuštěna na jednom klient, který data zobrazuje a ukládá, na jiném počítači, či alespoň v jiné konzoli.
26
počítači
a
Závěr
6
Vytvořili jsme
aplikaci, která je schopna spolehlivě detekovat hovory podle standardu H.323 a vypisovat o nich informace, které se dají dále statisticky zpracovat (například v tabulkovém procesoru). Aplikace je škálovatelná a používá pouze volně dostupné knihovny. Aplikace je snadno rozšiřitelná o sledování dalších technologií VoIP, funkčnost nad jinými síťovými protokoly než TCP/lP a o další možnosti zobrazování a ukládání získaných dat. Má ovšem i několik nedostatků a ne zcela dotažených částí: •
Pokud je v síti H.323 správce, může v některých případech routovat hovor přes sebe. Aplikace v současné době neobsahuje detekci tohoto jevu, routovaný hovor se tak zobrazí jako dva různé hovory.
•
Zprávy DTMF se od čtvrté verze specifikace H.323 (z roku 2001) mohou kromě protokolů H.225 a H.245 přenášet také v protokolu RTP (konkrétní způsob je definován v [10]). Vzhledem k tomu, že současná implementace protokol RTP nezachytává, projde takový způsob zaslání signálu DTMF nepovšimnut.
Pokud by se aplikace měla dále rozvíjet, rozhodně by to (kromě opravení zmíněných nedostatků) v první řadě mělo být směrem k lepšímu zobrazování a ukládání dat. Místo prostého výpisu na konzoli by se mohla vyrobit slušivá okenní aplikace, která by mohla mít i nějaké statistické funkce v sobě zabudované (např. zobrazení uzlů s největším počtem hovorů). Také ukládání dat by se místo do textového souboru mohlo provádět do databáze. Třída
H323CallReader by se mohla rozšířit o zachytávání samotných audiovizuálních dat a jejich ukládání do souboru nebo databáze.
Nabízí se také implementace nového PhonecallReaderu, který by zachytával provoz VolP podle novějšího standardu SIP. Tento standard získal během doby, po niž vznikala tato práce, na popularitě a dnes už by mohl být rozšířenější, než starší H.323. Nicméně
i bez těchto komerčním aplikacím.
rozšíření
vznikl program, který nabízí funkce doposud vlastní pouze
27
7 Seznam použité literatury [1]
WinPcap: The Windows Packet Capture Library homepage - http://www.winpcap.org
[2]
Rose Marshall T., Cass Dwight E. (1987): RFC 1006 - ISO Transport Service on top of
the TCP Version: 3 [3]
ITU
Telecommunication
Standardization
Sector
(2001):
H323:
Packet-based
multimedia communications systems, Version 4
o:
CaII signalling protocols and media stream packetization for packet-based multimedia communication systems, Version 5
[4] ITU Telecommunication Standardization Sector (2003): H225.
[5]
ITU Telecommunication Standardization Sector (2003): H245.· Control protocol for
multimedia communication, Version 5 [6] ITU Telecommunication Standardization Sector (2003): H323 System Implementers
Guide [7]
OpenH323 Project homepage - http://openh323.org
[8]
Objective Open H.323 for C homepage - http://www.obj-sys.com/open/index.shtml
[9]
Information Sciences Institute, University of Southern California (1981): RFC 793 -
Transmission Control Protoco/ [10] Schulzrinne H., Petrack S. (2000): RFC 2833 - RTP Payload for DTMF Digits,
Te/ephony Tones and Te/ephony Signa/s
28