Faculteit Toegepaste Wetenschappen Vakgroep Informatietechnologie Voorzitter: Prof. Dr. Ir. P. LAGASSE
Een peer-to-peer gebaseerde Presence Service voor Multimedia Toepassingen door Frédéric ITERBEKE Stijn MELIS
Promotoren: Prof. F. DE TURCK en Prof. B. DHOEDT Scriptiebegeleiders: B. DE VLEESCHAUWER en Dr.Ir. S. GOEMAN
Scriptie ingediend tot het behalen van de academische graad van licentiaat in de informatica
Academiejaar 20052006
Faculteit Toegepaste Wetenschappen Vakgroep Informatietechnologie Voorzitter: Prof. Dr. Ir. P. LAGASSE
Een peer-to-peer gebaseerde Presence Service voor Multimedia Toepassingen door Frédéric ITERBEKE Stijn MELIS
Promotoren: Prof. F. DE TURCK en Prof. B. DHOEDT Scriptiebegeleiders: B. DE VLEESCHAUWER en Dr.Ir. S. GOEMAN
Scriptie ingediend tot het behalen van de academische graad van licentiaat in de informatica
Academiejaar 20052006
Dankwoord
Allereerst wensen we onze promotoren Prof. Filip De Turck en Prof. Bart Dhoedt te bedanken. Verder wensen we ook zeker onze dank te betuigen aan Bart De Vleeschauwer die instond voor de meer dan adequate begeleiding en feedback gedurende het gehele jaar, en van wie we de bureaudeur geregeld hebben platgelopen. Onze dank gaat ook uit naar Stefan Goeman van Siemens voor de externe opvolging en de raadgevingen bij het schrijven van het boek. We wensen ook Bruno Van Den Bossche te bedanken voor de raadgevingen omtrent SIPp en de optimalisaties voor garbage collection in Java.
Ook Stijn Verstichel wordt van harte bedankt
voor de gegeven tips. We wensen ook elkaar te bedanken voor de goede samenwerking doorheen het jaar. Verder gaat natuurlijk ook dank uit naar onze vriend(inn)en en familieleden die ons gesteund hebben in de soms stressvolle momenten die we tijdens de loop van de scriptie hebben gekend.
Frédéric Iterbeke en Stijn Melis, mei 2006
Voorwoord
In deze scriptie werd een VoIP applicatie ontwikkeld met ondersteuning voor presence informatie en extra gebruikersvoorkeuren, gebaseerd op een peer-to-peer netwerk.
Daar wij beiden ook
gebruikers zijn van zowel messaging-, VoIP- en p2p-applicaties en graag implementeren, leek het ons zeer interessant om zelf een gelijkaardige applicatie te maken.
Als we terugblikken op het voorbije jaar en eens onze mailbox in het vakje Thesis herbekijken, dan kunnen we niet anders dan besluiten dat het een rijkgevuld jaar geweest is. De mails met vragen die we in het begin naar onze begeleider stuurden brengen nu spontaan een glimlach op ons gezicht als we er nu over nadenken hoe onwetend we op dat moment nog waren over de componenten van de ontwikkelde applicatie. Geleidelijk aan groeide onze kennis hierover, en voor we het goed en wel beseften waren we volledig ondergedompeld in de wereld van SIP, RTP, presence informatie, DHT's e.d. Onze samenwerking is gedurende een geheel jaar zeer vlot verlopen, wat ook wel te verwachten was daar we vrienden zijn.
Er was veelal de mogelijkheid om na het werken samen nog wat
gitaar te spelen en wat te keuvelen. De voldoening bij het bereiken van bepaalde grote doelen van de scriptie deed ons menigmaal een vreugdekreet slaken aan onze computer. Ondanks enkele problemen waar we zelf weinig aan konden verhelpen, was ook het testen in het testlab vrij aangenaam door de medestudenten die ons lot deelden en ook zeker door de goede begeleiding. Ons slaaptekort tijdens de laatste weken werd ook meermaals onderdrukt door een stevige dosis koe en/of cola.
Algemeen zijn we beiden tevreden over het werk dat we verricht hebben, en hopen we dat de lezer hier een interessant relaas zal terugvinden.
Frédéric Iterbeke en Stijn Melis, mei 2006
Toelating tot bruikleen
De auteurs geven de toelating deze scriptie voor consultatie beschikbaar te stellen en delen van de scriptie te kopiëren voor persoonlijk gebruik. Elk ander gebruik valt onder de beperkingen van het auteursrecht, in het bijzonder met betrekking tot de verplichting de bron uitdrukkelijk te vermelden bij het aanhalen van resultaten uit deze scriptie.
Frédéric Iterbeke en Stijn Melis, mei 2006
Een peer-to-peer gebaseerde Presence Service voor Multimedia Toepassingen door Frédéric ITERBEKE Stijn MELIS Scriptie ingediend tot het behalen van de academische graad van licentiaat in de informatica Academiejaar 20052006 Promotoren: Prof. F. DE TURCK en Prof. B. DHOEDT Scriptiebegeleiders: B. DE VLEESCHAUWER en Dr.Ir. S. GOEMAN Faculteit Toegepaste Wetenschappen Universiteit Gent Vakgroep Informatietechnologie Voorzitter: Prof. Dr. Ir. P. LAGASSE
Samenvatting In deze scriptie werd een peer-to-peer gebaseerde Voice-Over-IP applicatie met ondersteuning voor presence informatie ontworpen en ontwikkeld. Er werd gebruik gemaakt van het Session Initiation Protocol voor opzetten van de communicatie tussen gebruikers.
Persistente gebrui-
kersdata zoals een lijst van contactpersonen en voorkeuren met betrekking tot bereikbaarheid, alsook de presence informatie zelf werden door middel van XML ondersteund. Om het gehele systeem p2p te maken werd gebruik gemaakt van een gedistribueerde hashtabel. We stellen een architectuur voor met 2 basiscomponenten: Node en SuperNode. De Node vormt de clientkant van het systeem, die onder meer het opzetten van een VoIP sessie met andere gebruikers, het opvragen en publiceren van presence informatie en het deniëren van voorkeuren omvat. Deze voorkeuren voorzien de mogelijkheid om bepaalde (groepen van) gebruikers al dan niet te blokkeren. De SuperNode, de serverkant, omvat het opslaan en beheren van de persistente gebruikersdata, het routeren van SIP berichten, het beheer van presence informatie en het monitoren van de onderliggende p2p laag. Vervolgens leggen we de implementatie van de architectuur uit, en worden enkele basistesten besproken die de performantie van het systeem nagaan. Hierbij werd vooral naar de optimale waarde voor de call rate gepeild, die tussen 10 en 15 calls per seconde bedraagt. Daarna stellen we nog enkele uitbreidingen voor, en tenslotte worden de globale conclusies beschreven.
Trefwoorden presence, p2p, DHT, SIP, VoIP
A peer-to-peer based presence service for multimedia applications Fr´ed´eric Iterbeke, Stijn Melis Supervisor(s): Bart Dhoedt, Filip De Turck, Stefan Goeman, Bart De Vleeschauwer Abstract— This article describes how a presence service for multimedia applications such as Voice-over-IP (VoIP) can be implemented in a peer-topeer network. This presence service allows users not only to publish their presence and query other users’ presence, but also incorporates a contact list and a means of specifying whether one would like to allow or deny communication with (groups of) other users at any given time. For session setup and management the Session Initition Protocol (SIP) is used, while the Real-Time Transport Protocol (RTP) is used to handle audio communication. User data is persistently stored on a peer-to-peer (p2p) network in a distributed manner, using a distributed hashtable (DHT). A software architecture will be put forward to implement these requirements by means of two highlevel components: the Node, which handles all client-side aspects of the system such as calling other users, querying presence and setting preferences, and the SuperNode, which handles all serverside aspects such as storage and management of persistent user data, user location, call routing, presence management and monitoring of the underlying p2p network. Through testing we determined that the number of SuperNodes in the network should be adapted to ensure that a SuperNode does not receive call setup requests in excess of 12 CAPS. Keywords—presence, peer-to-peer, distributed hashtable, Session Initiation Protocol, Voice-over-IP
I. I NTRODUCTION
W
ITH the introduction of Skype ([1]), the telecommunication industry saw the beginning of the end for traditional telephony, which is being pushed out of the market in favor of VoIP. VoIP presents a cheaper solution for telephony since its users already pay for their Internet connection, and no additional costs except bandwidth are attached to it. With regards to VoIP, the Session Initiation Protocol (SIP)([2]) stands out amongst other protocols. SIP is a protocol used to set up sessions between users. Currently, SIP-based communication networks rely on central servers to guarantee their functionality. In this thesis, we investigate the possibility of a completely decentralised peer-to-peer SIP-based system. The proposed system should offer several features. Users should be able to invite each other to a VoIP session, publish presence information and obtain presence from other users. Furthermore, users should be able to define preferences, and thus have the ability to block or unblock certain (groups of) users. Users should be able to login from different locations, and the system should guarantee the consistency of the users’ persistent data. These features should be reliably integrated in a p2p network, i.e. the system should be able to cope with changes in the underlying network. F. Iterbeke and S. Melis are final-year students in the master in computer science. The master thesis corresponding to this article has been written in collaboration with the INTEC Broadband Communications Networks research group, Ghent University (UGent), Gent, Belgium. E-mail:
[email protected] and
[email protected]
In the next paragraphs, we will discuss how these requirements were met. We will propose an architecture for the desired system, and discuss how the different goals were achieved therein. Finally some testresults and a conclusion will be given.
II. T HE ARCHITECTURE We started by dividing the architecture into a client component, the Node, and a server component, a SuperNode. Typically, many Nodes will connect to one SuperNode.
A. The Node The Node is the part of the application the user will be working with. It enables the user to invite other users, maintain a contact list, subscribe to and publish presence information, and define preferences. These preferences provide a means to block or unblock a (group of) user(s) during a period of time. The Node also manages the RTP ([3]) session once an invitation has been accepted. Preferences are published to the user’s responsible SuperNode using a SIP PUBLISH message with a self defined XML content. Users can be added or removed from the contact list using SUBSCRIBE messages with another self defined XML content. Using the Node GUI one can also start and stop a SuperNode.
B. The SuperNode (SN) The SN is divided into two large parts: the SIP proxy, containing a registrar and a presence server; and the DHT. The SIP proxy (based on [4]) is responsible for handling all SIPrelated communication. The presence server acts as a Presence Agent (PA), and handles all presence-related SIP traffic (i.e. SIP SUBSCRIBE, PUBLISH and NOTIFY messages)([5]), while the registrar handles SIP REGISTER messages. The DHT component handles the distributed side of the application, using a slightly modified version of Bunshin DHT [6]. It helps to route SIP messages destined to users on other SuperNodes, and persistently stores user data mapping the user’s SIP URI to his data. User data, such as contact list and preferences, is stored in XML format. To ensure no data is lost when SuperNodes leave the network, user data is also redundantly stored on one or more other SuperNodes. The SN itself manages users and redirects them when necessary (when responsabilities for users change due to a SuperNode joining or leaving the network).
III. H OW THE REQUIREMENTS WERE MET USING THIS ARCHITECTURE
Using this architecture the goals were all achieved. Users can invite other users to a VoIP session, using the INVITE SIP message with SDP content, which the caller’s proxy routes to its destination using the DHT to find the callee’s proxy if necessary. Each message will maximally traverse 2 proxy hops. Presence information can be published using the SIP PUBLISH message with a PIDF ([7]) content. PIDF is an XML format that represents presence information. Since PIDF only supports an “open” or “closed” presence status, we extended it to allow for other types of presence information (i.e. “Online”, “Away”, . . . ). Users can subscribe to eachothers presence information using the SIP SUBSCRIBE message. A subscriber is notified by the notifier’s PA which sends a SIP NOTIFY message with the notifier’s PIDF as content. To allow users to block or let through one another, we implemented a firewall-like rule-system. These rules can be defined by the user, and are sent to his responsible SN using a SIP PUBLISH message with a self defined PreferencesXML document as content. The SN then updates that user’s XML data with the data it received. The SN also enforces these rules by checking the sender of messages for that user against the defined rules. Persistent user data consists of the contact list and preferences. Since a user receives his XML file whenever he logs in, a user can login from any location or device and still have the same contact list and preferences. The system copes with changes in the network in the following way: whenever a SN loses responsability over a user (due to another SN joining or leaving the network), it redirects the user to that user’s new responsible proxy, of which the address is looked up by its DHT component. When a SN decides to leave the network, it attempts to redirect its users. Since the SN is still in the network (and thus still holds responsability over the users), it can’t provide the nodes with their new responsible proxy. It instead provides the users with its own address, who then check if the received address is equal to their current proxy’s address. If so, the users perform a delayed redirect, which means they wait for a period of time, and then request the address of their (new) responsible proxy from the bootstrap SN (the SN which started the network). Thus, the users can again log in on their new proxy. The redirection and bootstrap calls between components were implemented using RMI.
IV. T ESTRESULTS Once the application was implemented we tested its performance using SIPp ([8]) to see how it coped with different amounts of traffic. We analyzed the impact of retransmissions, garbage collection optimisations ([9]) and the DHT on the response time and effective call rate. When an estimate for a number of CAPS (CAlls Per Second) is given, we mean that the number of SuperNodes in the p2p network should be adapted to make sure that SuperNodes do not receive call setup requests in excess of the given number. First of all we point out that these results apply to a single-
processor machine. On more high-end machines (i.e. dual core, hyperthreading) better results should be achieved. For setting an optimal value for the call rate two distinct approaches can be taken: if one prefers a high throughput, retransmissions should not be used, and a value of 12 to 15 CAPS provides a fairly high throughput, while still guaranteeing acceptable response and call setup times, though some calls (typically 1 to 2%) might get lost due to package loss. If one prefers low response times on the other hand, 5 CAPS is a good value (still without retransmissions). If retransmissions are used, less calls will get lost, but response times will rise. We then propose a call rate of 10 CAPS, so response times will still be reasonable and almost no calls will get lost. To improve response times, one can use garbage collection optimisations. The downside to this is that optimal parameters must be experimentally determined per system. As to the impact of the DHT, no real conclusions could be made. We can say that response times will rise, since another hop is added to the message flow and the DHT also uses some time to retrieve the next hop. V. C ONCLUSION All desired features are offered by the implementation of the presented architecture. A call rate of 12 to 15 CAPS can be achieved if one ensures that enough SuperNodes are present in the network to serve all connected Nodes, and calls are set up evenly distributed over the available SuperNodes. R EFERENCES [1] “Skype. The whole world can talk for free” http://www.skype.com/ [2] J. Rosenberg, H. Schulzrinne, G. Camarillo, A. Johnston, J. Peterson, R. Sparks, M. Handley, E. Schooler, “SIP: Session Initiation Protocol”, RFC 3261, Internet Engineering Task Force, June 2002 http://www.ietf.org/rfc/rfc3261.txt [3] H. Schulzrinne, S. Casner, R. Frederick, V. Jacobson, “RTP: A Transport Protocol for Real-Time Applications”, RFC 1889, Internet Engineering Task Force, January 1996 http://www.ietf.org/rfc/rfc1889.txt [4] “NIST SIP IP Telephony” http://snad.ncsl.nist.gov/proj/iptel/ [5] A. Niemi, Ed., “Session Initiation Protocol (SIP) Extension for Event State Publication”, RFC 3903, Internet Engineering Task Force October 2004, http://www.ietf.org/rfc/rfc3903.txt [6] R. Mondjar, P. Garca, C. Pairot, “Bunshin: DHT for distributed applications”, XIII Jornadas de Concurrencia y Sistemas Distribuidos (JCSD), I Congreso Espaol de Informtica (CEDI 2005), Granada, Spain, September 2005 http://planet.urv.es/bunshin/papers/Bunshin CEDI2005 Translation.pdf [7] H. Sugano, S. Fujimoto, G. Klyne, A. Bateman, W. Carr, J. Peterson, “Presence Information Data Format (PIDF)”, RFC 3863, Internet Engineering Task Force, August 2004 http://www.ietf.org/rfc/rfc3863.txt [8] O. Jacques, “SIPp : a free Open Source test tool / traffic generator for the SIP protocol” http://sipp.sourceforge.net/ [9] B. Van Den Bossche, F. De Turck, P. Demeester, B. Dhoedt, “Enabling Java-based VoIP backend platforms through JVM performance tuning”, published in VoIP Mase ’06 workshop, IEEE Catalog Number 06EX1301, March 2005 http://dev2dev.bea.com/pub/a/2006/05/voip-jvm-tuning.html
Inhoudsopgave 1 Inleiding
1
1.1
Situering . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
1
1.2
Doelstelling
3
1.3
Overzicht van de volgende hoofdstukken
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2 Gebruikte technologiën
4
5
2.1
Session Initiation Protocol (SIP)
. . . . . . . . . . . . . . . . . . . . . . . . . . .
5
2.2
SIP-berichten . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
10
2.2.1
Headers
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
10
2.2.2
REGISTER . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
12
2.2.3
INVITE en bijbehorende berichten . . . . . . . . . . . . . . . . . . . . . .
13
2.2.4
SUBSCRIBE
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
14
2.2.5
PUBLISH . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
15
2.2.6
NOTIFY
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
17
2.3
Session Description Protocol (SDP) . . . . . . . . . . . . . . . . . . . . . . . . . .
17
2.4
Real-time Transport Protocol (RTP) . . . . . . . . . . . . . . . . . . . . . . . . .
18
2.5
Presence Information Data Format (PIDF)
. . . . . . . . . . . . . . . . . . . . .
19
2.6
Distributed Hashtable (DHT) . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
20
2.6.1
Routeringslaag (routing layer) . . . . . . . . . . . . . . . . . . . . . . . . .
21
2.6.2
Opslaglaag (storage layer) . . . . . . . . . . . . . . . . . . . . . . . . . . .
22
2.6.3
Voorbeeld . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
23
3 High-Level Architectuur van het systeem
26
3.1
Inleiding . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
26
3.2
Node . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
28
i
Inhoudsopgave
3.3
3.4
ii
3.2.1
SIP-Client . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
28
3.2.2
VoIP-Manager
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
36
3.2.3
GUI
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
36
Supernode . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
37
3.3.1
SIP-proxy . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
38
3.3.2
Gedistribueerde hashtabel (DHT) . . . . . . . . . . . . . . . . . . . . . . .
42
3.3.3
Verdere functies . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
46
Extensible Markup Language (XML) formaten
. . . . . . . . . . . . . . . . . . .
48
3.4.1
De UserXML
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
48
3.4.2
Het Presence Information Data Format (PIDF) . . . . . . . . . . . . . . .
49
3.4.3
De BuddyXML . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
50
3.4.4
De PreferencesXML
51
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
4 Software Architectuur 4.1
4.2
4.3
54 . . . . . . . . . . . . . . . . . . . .
54
4.1.1
SIP en SDP . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
54
4.1.2
Mediastreaming . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
55
4.1.3
DHT . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
55
4.1.4
JDOM . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
56
4.1.5
Remote Method Invocation (RMI)
. . . . . . . . . . . . . . . . . . . . . .
56
Beschrijving van de geïmplementeerde klassen . . . . . . . . . . . . . . . . . . . .
57
4.2.1
Node package . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
57
4.2.2
SuperNode package . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
61
4.2.3
DHT package . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
67
4.2.4
Verdere klassen en interfaces in het SuperNode package
. . . . . . . . . .
68
Sequentie-diagrammen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
72
4.3.1
Login
72
4.3.2
Het toevoegen van een contactpersoon aan de lijst met contactpersonen
.
74
4.3.3
Het starten van een SuperNode . . . . . . . . . . . . . . . . . . . . . . . .
75
4.3.4
Het afsluiten van een SuperNode
77
4.3.5
Het uitnodigen van een andere gebruiker tot het opzetten van een mediasessie 79
4.3.6
Het afsluiten van een Node
Overzicht van gebruikte softwarebibliotheken
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . .
80
Inhoudsopgave
iii
5 Evaluatie
81
5.1
Globale parameters . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
82
5.2
Test zonder retransmissies noch optimalisaties met één SuperNode
. . . . . . . .
85
5.2.1
5 CAPS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
85
5.2.2
10 CAPS
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
86
5.2.3
15 CAPS
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
87
5.2.4
20 CAPS
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
89
5.2.5
Conclusie
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
91
Test zonder retransmissies met optimalisaties met één SuperNode . . . . . . . . .
92
5.3.1
5 CAPS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
93
5.3.2
10 CAPS
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
94
5.3.3
15 CAPS
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
95
5.3.4
20 CAPS
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
97
5.3.5
Conclusie
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
98
5.3
5.4
5.5
Test met retransmissies met optimalisaties met één SuperNode
. . . . . . . . . .
99
5.4.1
5 CAPS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
99
5.4.2
10 CAPS
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
100
5.4.3
15 CAPS
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
101
5.4.4
20 CAPS
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
103
5.4.5
Conclusie
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
105
Test zonder retransmissies met optimalisaties met twee SuperNodes . . . . . . . .
106
5.5.1
10 CAPS
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
108
5.5.2
15 CAPS
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
109
5.5.3
Conclusies . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
111
6 Verder Werk 6.1
6.2
113
Verbetering van de huidige applicatie . . . . . . . . . . . . . . . . . . . . . . . . .
113
6.1.1
Preferences
113
6.1.2
Redirection van de subscribers
. . . . . . . . . . . . . . . . . . . . . . . .
115
6.1.3
Proxy volledig stateless maken
. . . . . . . . . . . . . . . . . . . . . . . .
116
6.1.4
Notify onder Linux . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
117
6.1.5
Proxy geheugenlek
117
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Mogelijke uitbreidingen op de applicatie
. . . . . . . . . . . . . . . . . . . . . . .
118
Inhoudsopgave
iv
6.2.1
Persistentie van subscribers
. . . . . . . . . . . . . . . . . . . . . . . . . .
118
6.2.2
Security . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
119
6.2.3
Firewall/NAT-Traversal
. . . . . . . . . . . . . . . . . . . . . . . . . . . .
120
6.2.4
Authenticatieservice
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
121
6.2.5
Caching . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
122
6.2.6
Automatisch starten van een SuperNode . . . . . . . . . . . . . . . . . . .
122
6.2.7
Echo cancellation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
122
7 Conclusie
123
7.1
Toetsen van de applicatie aan de opgegeven doelstellingen
. . . . . . . . . . . . .
124
7.2
Conclusies getrokken uit de behaalde testresultaten . . . . . . . . . . . . . . . . .
125
7.3
Algemene conclusie . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
126
A Legende bij UML Diagrammen
127
B SIP ow voor enkele SIP berichten
128
B.1
REGISTER . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
128
B.2
INVITE . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
129
B.3
BYE . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
129
B.4
SUBSCRIBE
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
130
B.5
PUBLISH . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
130
C Layout van de bijgevoegde CD-ROM
131
D Opmerkingen in verband met het opstarten van het programma
134
D.1
D.2
Conguratiebestanden
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
134
D.1.1
Conguratiebestanden voor de Node
. . . . . . . . . . . . . . . . . . . . .
134
D.1.2
Conguratiebestanden voor de SuperNode . . . . . . . . . . . . . . . . . .
135
Opstarten van het programma . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
137
Lijst van gebruikte afkortingen CAPS
Calls Per Second
DHT
Distributed Hashtable
DNS
Domain Name System
DoS
Denial of Service
GUI
Graphical User Interface
ID
Identier
IETF
Internet Engineering Task Force
JAIN
Java APIs for Integrated Networks
JMF
Java Media Framework
JVM
Java Virtual Machine
MMS NAT NIST p2p PA
Maximum Message Size
Network Address Translation
National Institute for Standards and Technology
Peer-to-peer
Presence Agent
PIDF
Presence Information Data Format
QOS
Quality Of Service
RFC
Request For Comment
v
Inhoudsopgave
RMI
Remote Method Invocation
RPID
Rich Presence Information Data Format
RTCP
Real-Time Control Protocol
RTP
Real-Time Transport Protocol
SDP
Session Description Protocol
SIP
Session Initiation Protocol
STUN TCP
Tranmission Control Protocol
TURN UA
Simple Traversal of UDP Through Network Address Translators
Traversal Using Relay NAT
User Agent
UAC
User Agent Client
UAS
User Agent Server
UDP
User Datagram Protocol
UML
Unied Modeling Language
URI
Uniform Resource Identier
VoIP
Voice-over IP
XML
Extensible Markup Language
vi
Hoofdstuk 1
Inleiding In dit hoofdstuk zal de scriptie eerst en vooral gesitueerd worden in de context van de informatica in het algemeen. Ook zullen de doelstellingen naar voren gebracht worden. Verder zal ook een kort overzicht gegeven worden van de volgende hoofdstukken.
1.1 Situering Het verschijnen van Skype ([1]) betekende voor de telecommunicatiesector het begin van het einde voor traditionele telefonie, die stilaan van de markt verdreven wordt door Voice-over-IP (VoIP). VoIP voorziet in een goedkopere oplossing voor telefonie, aangezien gebruikers toch al betalen voor hun Internetverbinding en er geen meerkost aan verbonden is buiten het gebruik van bandbreedte. Populaire messaging applicaties ondersteunen reeds VoIP en soms zelfs video conferencing over het Internet. Veelal worden voor het opzetten van gesprekken in zo'n VoIP netwerk nog centrale servers gebruikt. Dit heeft tot gevolg dat de hele infrastructuur afhankelijk is van de goede werking van deze centrale servers, en deze beheerd en onderhouden moeten worden. Bij peer-to-peer netwerken is dit echter anders, en Skype was één van de eerste VoIP programma's dat dit succesvol uit wist te buiten. In tegenstelling tot de klassieke client-server architecturen, die gebruik maken van krachtige en intelligente centrale servers, maken (zuivere) p2p netwerken geen gebruik van centrale servers. Bij p2p netwerken zijn de peers de enige intelligente componenten, het netwerk wordt enkel
1
Hoofdstuk 1. Inleiding
2
gebruikt voor het routeren van berichten (zie guur 1.1). Op deze manier wordt men minder afhankelijk van een individuele server (of serverpark), aangezien elke component in het netwerk bijdraagt tot de betrouwbaarheid van het netwerk.
C
C
C
C
Client
S
Server
P
S
C
C
P
P
P
P P
Client-Server
Peer
Peer-to-peer
Figuur 1.1: Client-Server vs. Peer-to-peer.
Voornamelijk worden p2p netwerken gebruikt voor de uitwisseling van data (d.i.
lesharing).
Bekende voorbeelden van zulke systemen zijn onder meer Kazaa, Emule/Edonkey, DirectConnect en LimeWire. Zoals reeds vermeld is er sinds kort echter ook een VoIP p2p systeem vrij beschikbaar, zijnde Skype ([1]). Via Skype kunnen computergebruikers vrij en kosteloos met elkaar telefoneren en chatten (instant messaging). Er zijn echter nog een aantal aspecten aan het Skype p2p systeem die kunnen verbeterd worden :
•
Het gebruik van presence informatie is vrij beperkt, i.e. enkel online/oine indicatie (en varianten hiervan) wordt voorzien. Het gebruik van meerdere terminals per gebruiker, wat intelligent routeren noodzakelijk maakt, wordt momenteel ook niet beschouwd.
•
Een gebruiker wil waarschijnlijk niet op elk moment beschikbaar zijn voor iedereen. Skype biedt hier echter geen voorziening voor.
Momenteel is het nog niet duidelijk hoe dit in een puur p2p model moet gebracht worden, en misschien moet een hybride systeem gebruikt worden waarbij een aantal aspecten toch door centrale servers behandeld worden. Het is onder andere de bedoeling van deze scriptie om dit te onderzoeken, en hierop een antwoord te vinden.
Hoofdstuk 1. Inleiding
3
Met betrekking tot VoIP, instant messaging en chatting, treedt één protocol sterk naar voren, nl.
het Session Initiation Protocol (SIP). Dit protocol wordt gebruikt om multimediasessies
(voice, video, instant messaging, . . . )
op te zetten tussen verschillende eindgebruikers.
Mo-
menteel maken SIP-gebaseerde communicatie netwerken ook gebruik van een aantal centrale servers om bepaalde functionaliteit te realiseren. Er wordt echter ook onderzoek verricht naar SIP-gebaseerde P2P netwerken [2]. Het grote voordeel van een SIP-gebaseerd systeem is dat SIP (en uitbreidingen op SIP) gestandaardiseerd wordt binnen de Internet Engineering Task Force (IETF) aan de hand van Requests For Comment (RFCs) ([3], [4], [5] en [6]).
SIP-gebaseerde
toepassingen zouden dus op een vrij eenvoudige manier in staat moeten zijn om met elkaar samen te werken, iets wat met niet-gestandaardiseerde systemen vrijwel ondenkbaar is.
1.2 Doelstelling Het uiteindelijke doel van deze scriptie is het ontwerpen en implementeren van een prototype voor een volledig gedecentraliseerde p2p-gebaseerde multimedia applicatie met ondersteuning voor presence. Als het type multimedia werd er, zoals voorheen gezegd, gekozen voor VoIP. Dit wil zeggen dat het systeem in staat moet zijn om gebruikers toe te laten met elkaar een VoIP communicatie sessie op te zetten, en dit door middel van onder meer SIP. Verder moet presence informatie van gebruikers beschikbaar kunnen gemaakt worden voor andere gebruikers. Gebruikers moeten ook in staat zijn om zgn. preferences op te geven. Deze preferences omvatten een regelsysteem om andere (groepen van) gebruikers tijdelijk te blokkeren of toe te laten. Het dient bovendien ook mogelijk te zijn om gebruikers te laten inloggen vanop verschillende locaties en het systeem moet hen steeds in staat stellen te beschikken over een aantal basisinstellingen, zoals preferences en contactlijsten. Dit alles moet op een persistente en betrouwbare manier aangeboden worden in een p2p netwerk, dat gebruik maakt van zo weinig mogelijke centrale componenten. De applicatie moet dus om kunnen gaan met veranderingen in het p2p netwerk.
Hoofdstuk 1. Inleiding
4
1.3 Overzicht van de volgende hoofdstukken Er zal eerst en vooral een overzicht gegeven worden van de belangrijkste technologiën die gebruikt werden. Dit zal in hoofdstuk 2 gebeuren.
Hoofdstukken 3 en 4 behandelen de weg die bewandeld werd bij het ontwerpen en implementeren van de applicatie. Hoofdstuk 3 legt de focus op de high-level architectuur van het systeem, en de ontwerpsbeslissingen die onderweg gemaakt werden. Ook zal er aandacht besteed worden aan de diverse XML-formaten die gebruikt worden door het systeem. De eigenlijke implementatie zal toegelicht worden in hoofdstuk 4. Hierbij zullen ook sequentiediagrammen en UML-schema's aan bod komen.
In hoofdstuk 5 zal er uitgeweid worden over de diverse testresultaten die bekomen zijn met behulp van het systeem.
In hoofdstuk 6 zullen enkele mogelijke uitbreidingen en verbeteringen van het systeem voorgesteld worden.
En in het laatste hoofdstuk ten slotte zullen de conclusies geformuleerd worden.
Hoofdstuk 2
Gebruikte technologiën Er werd bij de ontwikkeling van deze thesis veel beroep gedaan op bestaande technologiën. In dit hoofdstuk zal de lezer vertrouwd gemaakt worden met deze gebruikte technologiën. Enkele voorbeelden zijn : SIP, SDP, RTP, DHT, . . . Het is echter geenszins de bedoeling hier een gedetailleerde beschrijving te geven van de gebruikte technologiën.
2.1 Session Initiation Protocol (SIP) Het Session Initiation Protocol (SIP) is een protocol om sessies op te zetten, te modiëren en af te sluiten over een IP-netwerk. Een sessie kan een telefoongesprek zijn, maar kan evengoed een video-conferentie met diverse partijen of een instant messaging sessie zijn. Ook is er ondersteuning voor het doorsturen en opvragen van presence informatie.
Hieronder verstaan we vooral
de beschikbaarheidsstatus die een gebruiker kenbaar maakt aan andere gebruikers en alles wat daarbij komt kijken, zoals het opvragen en veranderen van deze informatie.
De belangrijkste functie van SIP is ook de basis van het opzetten van sessies, namelijk de identicatie van de locatie van de gebruikers. Deze dienst vormt de hoeksteen van heel het SIP systeem. SIP zelf stelt de gebruiker (in de meeste gevallen) niet in staat om te communiceren, daarvoor wordt bij voorkeur een ander protocol gebruikt.
Twee protocols die vaak gebruikt worden in
samenwerking met SIP, zijn het Real-time Transport Protocol (RTP) en Session Description Protocol (SDP) (zie verder). SIP is een standaard die beschreven wordt in meerdere Request For Comments (RFC 2543 en
5
Hoofdstuk 2. Gebruikte technologiën
6
later [3]), beheerd door de Internet Engineering Task Force (IETF) en evolueert nog steeds (getuige daarvan de vele extenties die er ondertussen al bijgevoegd zijn, waarvan de belangrijkste voor dit werk [4], [5] en [6] zijn). Verschillende SIP ow diagrammen zijn te vinden in appendix B. Een SIP-entiteit wordt altijd voorgesteld door een SIP-URI. Deze SIP-URI is analoog aan een e-mailadres en heeft de vorm sip:username@domain, vb. sip:
[email protected]. Op het moment dat een entiteit zich beschikbaar wil stellen voor communicatie, zal die zich vanaf een bepaalde locatie registreren. Deze locatie is dus de plaats waar de entiteit zich op dat moment bevindt, en de binding tussen de entiteit en zijn locatie wordt bijgehouden door een locatiedienst (een SIP registrar, cfr. infra). De locatie zelf wordt bijgehouden in een URI. Dit kan een telefoonnummer zijn of een SIP-URI (van de vorm user@hostip:port, vb.
[email protected]:5060) Dit systeem is te vergelijken met een telefoonboek:
een naam wordt afgebeeld op (één of
meerdere) telefoonnummers, waarop de entiteit voorgesteld door de naam al dan niet te bereiken is. De nummers zelf kunnen veranderen, bijvoorbeeld als de entiteit verhuist, maar de naam zal nooit veranderen. Het voordeel van de locatiedienst is dat het voor de buitenwereld (andere gebruikers) niet meer nodig is het expliciete contactadres van een entiteit op te slaan. Op deze manier worden de entiteiten dus mobieler en wordt het voor hen mogelijk zich vanop meerdere plaatsen en toestellen (pc, gsm, pda,...) beschikbaar te stellen, terwijl de buitenwereld de locatiedienst kan bevragen om de entiteit te bereiken.
De basis van SIP zijn eigenlijk de User Agents (UA). Een UA handelt de SIP-communicatie voor een welbepaalde user af. Deze zijn onder te verdelen in een User Agent Server (UAS) en User Agent Client (UAC). UAS en UAC zijn enkel logische entiteiten, elke UA heeft zowel een UAS en een UAC. UAC is het deel van de user agent dewelke requests zendt en responses ontvangt. UAS is het deel dat responses zendt en requests ontvangt. Een user agent zal zich gedragen als UAC als hij een INVITE bericht stuurt en daarop een response ontvangt. Degene die gebeld wordt (callee), zal zich gedragen als UAS, aangezien deze het INVITE request ontvangt, en een response stuurt. stoppen d.m.v.
Als de callee dan beslist de sessie te
een BYE bericht, dan worden de rollen omgekeerd en gedraagt de callee zich
als UAC (hij stuurt immers het BYE request) en gedraagt de caller zich als UAS, deze zal het request ontvangen en een response terugsturen.
Hoofdstuk 2. Gebruikte technologiën
Stateful Proxy
Caller
UAC
7
INVITE
UAS
Callee
UAC
INVITE
BYE
UAS
UAS
UAC
Figuur 2.1: Het UAC-UAS systeem van SIP.
User agents kunnen berichten sturen naar (en via) een proxy server. Proxy servers zijn zeer belangrijke componenten in een SIP infrastructuur. Zij staan in voor de routering van de berichten a.d.h.v. de locatie van de bestemmeling (d.i. de contact-URI). Eventueel staan ze ook in voor authenticatie en presence informatie. De belangrijkste taak van een proxy server is om de berichten dichter bij de bestemmeling te brengen. De berichten zullen over het algemeen enkele proxies passeren totdat ze in een proxy aankomen die de locatie van de bestemmeling kent.
Deze laatste proxy zal het bericht direct
naar de bestemmeling doorsturen, en die kan dan gepast reageren op het bericht.
alice @ thesis.test
INVITE
kent locatie van bob niet Proxy A
kent locatie van bob wel INVITE
...
INVITE
Proxy B
bob@ thesis.test
INVITE
Figuur 2.2: Een proxy stuurt de berichten door tot ze bij de bestemmeling aankomen.
In guur 2.2 wil de user agent van de entiteit
[email protected] een communicatiesessie opzetten met
[email protected]. Alice stuurt een INVITE request naar haar gekende proxy. Deze kent de
Hoofdstuk 2. Gebruikte technologiën
8
locatie van Bob niet, dus forwardt hij het INVITE request naar een volgende proxy. Dit proces herhaalt zich tot het bericht naar B wordt gestuurd.
Deze ontvangt het bericht, en kent de
contact-URI van
[email protected] wel, en kan het request dus rechtstreeks naar Bob sturen.
Opdat een proxy de contact-URI, en dus de locatie, van een bepaalde entiteit zou kennen, dient deze entiteit zich eerst met zijn UA te registreren bij een zgn. registrar. Dit gebeurt a.d.h.v. een REGISTER request.
De registrar is de locatiedienst in het domein waar de proxy ver-
antwoordelijk voor is, die REGISTER requests ontvangt, en de SIP-URI van de entiteit mapt op de ontvangen contact URI. Deze mapping noemt men een binding, aangezien de naam van de entiteit gebonden wordt aan zijn adres. dan niet tegelijkertijd.
Een entiteit kan meerdere bindingen hebben, al
Een voorbeeld van een binding zou kunnen zijn:
- sip:
[email protected]:5060.
sip:
[email protected]
Al deze bindingen samen vormen de locatie database van de
registrar. Die locatie database kan dan gebruikt worden door proxy servers. Als een proxy een request ontvangt met als bestemmeling
[email protected], zal de proxy de locatie database van zijn domein bevragen en kijken of hij een binding vindt voor
[email protected]. Is dit het geval, dan kan het request doorgestuurd worden naar het contactadres van Alice. Aangezien proxy en registrar zeer nauw dienen samen te werken, zijn ze meestal gecoloceerd. Dit is echter niet vereist.
Communicatie opzetten via SIP gebeurt a.d.h.v. berichten. Voor het aeveren van de berichten wordt over het algemeen TCP gebruikt, UDP is echter ook een mogelijkheid. Een bericht bestaat typisch uit een rst line, bericht headers en de body. De rst line geeft aan over welk type bericht het gaat. Er zijn twee types : requests en responses. Requests worden gebruikt om een actie te starten (vb. een registratie a.d.h.v. het REGISTER request). Responses daarentegen worden gebruikt om te antwoorden op een request. De bericht headers bieden de mogelijkheid extra informatie mee te geven aan het bericht (sommige headers zijn echter verplicht, welke dat zijn varieert van bericht tot bericht). De bericht body laat toe extra inhoud aan het bericht toe te voegen, zo zal tijdens het opzetten van een RTP sessie a.d.h.v. een INVITE request een SDP bericht in de content van het INVITE bericht gestoken worden. De belangrijkste berichten zullen verder in 2.2 uitgebreider aan bod komen.
Voor de ondersteuning van presence informatie zijn vooral de SUBSCRIBE-, NOTIFY- en
Hoofdstuk 2. Gebruikte technologiën
PUBLISH-requests belangrijk.
9
Het basisidee is het volgende:
een gebruiker maakt zijn sta-
tus kenbaar via een presence agent (PA), die instaat voor het beheer ervan. Dit gebeurt aan de hand van een PUBLISH bericht. Andere gebruikers die van deze presence op de hoogte willen blijven, moeten zich hiervoor inschrijven bij de PA van de gebruiker. Dit gebeurt met een SUBSCRIBE bericht. De PA zal de de ingeschreven gebruikers dan NOTIFY berichten sturen om hen te updaten. Dit laatste kan zowel via een push-, als via een pullgebaseerd model gebeuren (zie ook 3.2.1). In de context van presence noemen we de gebruiker die zijn presence kenbaar maakt de presentity (of ook notier, hoewel strikt gezien de PA de notier is); de gebruikers die zich inschrijven voor de status van de presentity noemen we watchers of subscribers.
Subscriber A
SUB
SCR
IBE
PA SUBSCRIBE Subscriber B
Alice
IBE
SCR
SUB
Subscriber C
Figuur 2.3: Subscribers A, B en C schrijven zich in voor de presence informatie van Alice.
Op guur 2.3 is te zien hoe subscribers A, B en C zich inschrijven voor de presence informatie van Alice. Op guur 2.4 is te zien wat er gebeurt als Alice haar presence informatie publiceert. De PA van Alice zal de 3 subscribers via het pushgebaseerde model op de hoogte brengen van de presence informatie van Alice door middel van een NOTIFY bericht.
Hoofdstuk 2. Gebruikte technologiën
Subscriber A
NOT
10
IFY
PA NOTIFY
PUBLISH
Subscriber B
Alice
IFY
NOT
Subscriber C
Figuur 2.4: Alice publiceert haar presence informatie, en de PA brengt de subscribers daarvan op de
hoogte.
2.2 SIP-berichten Hier zal nog even dieper ingegaan worden op de betekenis van enkele SIP-berichten die een vitale rol zullen spelen in het systeem. We denken hierbij in de eerste plaats aan :
•
REGISTER
•
INVITE en bijbehorende berichten
•
SUBSCRIBE
•
PUBLISH
•
NOTIFY
Speciale aandacht zal uitgaan naar berichten waarbij een extra inhoud zal worden toegevoegd. Bij sommige berichten zal dit in de vorm van XML-berichten zijn, deze zullen echter pas in sectie 3.4 uitgebreid aan bod komen, hier volstaat het enkel te weten waar en waarom ze gebruikt worden. Voor voorbeelden van enkele typische SIP ows verwijzen we graag naar appendix B.
2.2.1 Headers Vooraleer de meestgebruikte SIP-berichten toegelicht zullen worden, zal er eerst een kort overzicht gegeven worden van de voornaamste headers waarvan SIP gebruik maakt, zonder hierbij ex-
Hoofdstuk 2. Gebruikte technologiën
11
haustief te willen zijn. Dit om het begrip van de volgende secties te vergemakkelijken. De basisheaders die in elk SIP-bericht voorkomen zijn de volgende :
•
To-header : geeft de logische entiteit van de gewenste ontvanger van het request aan. Ook bij een response op dat request geeft de To-header de gewenste ontvanger aan van het request waarop de response verstuurd werd (d.i. dus de zender van de response).
•
From-header : geeft de logische entiteit van degene die het request initieert aan. Ook bij responses blijft dit degene die het request initieerde.
•
CSeq-header : deze header bevat een nummer en de methode van het request. De CSeqheader wordt onder andere gebruikt om het verschil aan te geven tussen nieuwe requests, en retransmissies van een request. De CSeq-header van een response is altijd dezelfde als deze van het request waarop de response gestuurd werd. De methode geeft aan om welk soort bericht het gaat.
•
CallID-header :
deze header identiceert een bepaalde call of alle registraties van een
bepaalde gebruiker op een unieke manier.
•
MaxForwards-header : deze header ziet erop toe dat er maar een beperkt aantal proxies doorlopen kan worden wanneer een request of response gerouteerd wordt. Elke keer een request of response downstream een hop passeert, zal deze hop (in dit systeem altijd een proxy) de waarde in de MaxForwards-header met één decrementeren.
•
Via-header : deze header duidt het transportprotocol aan dat zal gebruikt worden en identiceert ook de locatie naar waar de response moet gezonden worden. Elke keer een request een hop passeert, zal deze hop een extra Via-header aan de lijst van Via-headers toevoegen. Elke keer een response diezelfde hop opnieuw passeert op de terugweg, verwijdert deze hop zijn Via-header uit de lijst.
Het is hier geenszins de bedoeling elke header van elk SIP-bericht van naaldje tot draadje uit te leggen. Hiervoor kan men altijd bij de RFCs over SIP en de diverse extenties terecht, zie [3], [4], [5] en [6]. Hierin kan men uiteraard ook gedetailleerdere beschrijvingen vinden van onderstaande SIP-berichten en hun structuur en gebruik.
Hoofdstuk 2. Gebruikte technologiën
12
2.2.2 REGISTER Het REGISTER bericht wordt, zoals eerder al gezegd, gebruikt om een gebruiker te registreren bij een registrar. In de registrar wordt dan een mapping (of binding) gemaakt van de SIP-URI op de contactURI van de gebruiker. Als een gebruiker zich registreert bij een registrar zal die een OK response terugkrijgen met als inhoud zijn UserXML.
REGISTER sip:@213.118.63.145:4000 SIP/2.0 Call-ID:
[email protected] CSeq: 0 REGISTER From: "alice" <sip:
[email protected]>;tag=1347 To: "alice" <sip:
[email protected]>;tag=1347 Via: SIP/2.0/UDP 213.118.63.145:6060;branch=z9hG4bK6f2943d278cb4894037dd44d689a37d3 Max-Forwards: 70 Contact: <sip:
[email protected]:6060> Expires: 3600 Allow: INVITE, ACK, BYE, NOTIFY, SUBSCRIBE, PUBLISH Content-Length: 0
Figuur 2.5: Een REGISTER bericht.
Op guur 2.5 is een voorbeeld REGISTER bericht te zien. Sommige headers bij een REGISTER bericht zullen anders gebruikt worden dan normaal het geval is en er zijn ook een paar verplichte headers die bij andere berichten niet dienen voor te komen. Zo zullen de From- en To-header dezelfde waarde hebben, nl. de gewenste SIP-URI van de gebruiker en eventueel een gebruiksvriendelijkere naam. Ook zal de RequestURI (d.i. de URI die op de methode van het SIP-bericht volgt) afwijken van zijn normale vorm.
De RequestURI zal geen gebruikersnaam
hebben, en zal als domein het adres van de proxy bevatten. Verder dient er bij een REGISTER bericht altijd een Contact-header aanwezig te zijn, die gebruikt zal worden om de SIP-URI te binden aan de contactURI in de registrar.
De Expires-header tenslotte geeft aan hoelang de
registratie door de registrar levend moet gehouden worden, m.a.w. eens de tijd aangegeven in de Expires-header afgelopen is, en de registrar nog geen nieuw REGISTER bericht ontvangen heeft voor die gebruiker, zal de binding verwijderd worden.
Een REGISTER bericht kan ook gebruikt worden om een gebruiker te unregistreren, d.w.z. een binding in de registrar voor een bepaalde gebruiker verwijderen. Om een zgn. unregister bericht te construeren, dient men de Expires header een waarde 0 mee te geven. Het is ook mogelijk
Hoofdstuk 2. Gebruikte technologiën
13
met één unregister alle bindingen van een bepaalde gebruiker te verwijderen. Hiervoor wordt een wildcard gebruikt in de contactURI.
2.2.3 INVITE en bijbehorende berichten Om een andere gebruiker uit te nodigen tot een multimediasessie wordt het INVITE bericht gebruikt. Op een INVITE bericht volgen andere berichten die ook nodig zijn om tot een multimediasessie te komen.
Deze zijn :
de (optionele) Trying response, de (eveneens optionele)
Ringing response, de (verplichte) OK response en het (eveneens verplichte) ACK request. Dit is te vergelijken met een 2-way handshake, aangezien de caller de sessie als gestart zal beschouwen eens het ACK request verstuurd werd.
INVITE sip:
[email protected] SIP/2.0 Call-ID: 6de3fb060e71bb654c6eea64414b633e @213.118.61.50 CSeq: 6 INVITE From: "alice" <sip:
[email protected] >;tag=3809 To: "erica" <sip:
[email protected] > Via: SIP/2.0/ UDP 213.118.61.50:6060;branch=z9hG4bK381bfcfd2bbaf41fba632553cd35da98 Max-Forwards: 70 Route: <sip:213.118.61.50:4000> Allow: INVITE, ACK, BYE, NOTIFY, SUBSCRIBE, PUBLISH Content-Type: application/ sdp Content-Length: 137 v=0 o=- 3357744591 3357744591 IN IP4 213.118.61.50 s=c=IN IP4 213.118.61.50 t=0 0 a=RTPMAP :0 PCMU/8000 m=audio 33334/2 RTP/AVP
Figuur 2.6: Een INVITE bericht en bijbehorende SDP inhoud.
Op de guur is een voorbeeld INVITE bericht te zien. Een INVITE bericht zal een SDP bericht als inhoud krijgen, dit wordt gebruikt om eventueel de parameters voor de multimediasessie in af te spreken.
Hoofdstuk 2. Gebruikte technologiën
14
Proxy
Alice
Bob
INVITE TRYING INVITE RINGING RINGING
OK OK ACK
RTP
BYE OK
Figuur 2.7: Een voorbeeld van een typische INVITE messageow, alsook een BYE bericht gestuurd
door de callee om de sessie af te sluiten.
Om een multimediasessie af te breken zal ofwel de caller, ofwel de callee een BYE bericht versturen naar de andere partij (en dit point-to-point). De partij die het BYE request stuurt, zal de sessie als afgelopen beschouwen eens het request verzonden is. De andere partij zal niettemin toch nog een OK response terugsturen, en dan ook de sessie als afgesloten beschouwen.
2.2.4 SUBSCRIBE Het SUBSCRIBE bericht kan gebruikt worden op twee manieren (die eigenlijk niet zo heel verschillend van elkaar zijn). Zoals eerder al gezegd, wordt een SUBSCRIBE bericht gebruikt om zich in te schrijven bij een andere gebruiker, om diens presence informatie te ontvangen. Een belangrijke parameter hierbij is de zgn. Expires-header. Een SUBSCRIBE met een Expires-header met waarde verschillend van 0, is een echte inschrijving om presence te ontvangen (en deze duurt zolang als de Expires-header aangeeft, in seconden). Heeft de Expires-header echter een waarde gelijk aan 0, dan betreft het een zgn. fetcher (indien er geen inschrijving aanwezig is van de subscriber op de notier) ofwel een zgn. unsubscribe (indien de subscriber al ingeschreven is op de notier). Het verschil tussen een normale SUBSCRIBE en een fetcher is dus eigenlijk
Hoofdstuk 2. Gebruikte technologiën
15
de lengte van de inschrijving. Voor een fetcher bedraagt die 0 seconden. De subscriber zal in het laatste geval evenwel toch een NOTIFY bericht ontvangen voor dat SUBSCRIBE bericht.
SUBSCRIBE sip:
[email protected] SIP/2.0 Call-ID:
[email protected] CSeq: 1 SUBSCRIBE From: "alice" <sip:
[email protected]>;tag=2368 To: "erica" <sip:
[email protected]> Via: SIP/2.0/UDP 213.118.63.145:6060;branch=z9hG4bK1c2106c8ab69980d9de30d7bad6b24ff Max-Forwards: 70 Expires: 3600 Route: <sip:213.118.63.145:4000> Allow: INVITE, ACK, BYE, NOTIFY, SUBSCRIBE, PUBLISH Accept: application/pidf+xml Contact: <sip:
[email protected]:6060> Event: presence Content-Length: 0
Figuur 2.8: Een SUBSCRIBE bericht.
Op guur 2.8 is een SUBSCRIBE bericht te zien waarbij Alice zich inschrijft bij Erica om haar presence informatie te ontvangen. Een verplichte header voor een SUBSCRIBE bericht is de Event-header. Deze header zal in het huidige systeem altijd de waarde presence bevatten, maar kan ook gebruikt worden om andere informatie buiten presence op te vragen. Verder is er een Contact-header aanwezig om de PA van de notier op de hoogte te brengen van de contactURI van de subscriber, aangezien de PA van de notier niet noodzakelijk gecoloceerd is met de registrar waarbij de subscriber geregistreerd is.
SUBSCRIBE berichten worden ook gebruikt om de SuperNode op de hoogte te brengen wanneer er een contactpersoon toegevoegd of verwijderd wordt uit de Buddy List. Hiervoor wordt een zgn.
BuddyXML als inhoud meegegeven aan het SUBSCRIBE bericht zie hiervoor ook deel
3.4.3.
2.2.5 PUBLISH Een PUBLISH bericht wordt gebruikt om de eigen presence informatie te publiceren bij de eigen PA. Hiervoor wordt een PIDF document als inhoud aan het PUBLISH bericht gehangen. Naargelang de gekozen strategie van een subscriber zal er dan door de PA gepast gereageerd worden als deze het PUBLISH bericht ontvangt (zie 3.2.1).
Hoofdstuk 2. Gebruikte technologiën
16
PUBLISH berichten worden hier ook gebruikt om veranderingen in de Preferences aan de SuperNode te melden.
Hiervoor wordt een PreferencesXML als inhoud aan het PUBLISH bericht
gehangen.
PUBLISH sip:
[email protected] SIP/2.0 Call-ID:
[email protected] CSeq: 2 PUBLISH From: "alice" <sip:
[email protected]>;tag=3616 To: "alice" <sip:
[email protected]> Via: SIP/2.0/UDP 213.118.63.145:6060;branch=z9hG4bKb4dbda02c02144ff449128fed8769283 Max-Forwards: 70 Route: <sip:213.118.63.145:4000> Allow: INVITE, ACK, BYE, NOTIFY, SUBSCRIBE, PUBLISH Expires: 3600 Contact: <sip:
[email protected]:6060> Content-Type: application/xml+pidf Event: presence Content-Length: 297 <presence xmlns="urn:ietf:params :xml:ns:pidf" entity="sip:
[email protected]">
<status> closed offline 2006-05-23T21:19: 46Z
Figuur 2.9: Een voorbeeld PUBLISH bericht met een PIDF document als inhoud
Op guur 2.9 is een PUBLISH bericht te zien, waarbij Alice haar nieuwe status (Oine) publiceert naar haar PA. PUBLISH berichten voor veranderingen in Preferences zijn volledig analoog, er wordt enkel een ander type inhoud aan toegevoegd (met als ContentType: application/xml+preferences).
Voor het PUBLISH bericht zijn er enkele verplichte headers gedenieerd. Net als bij het SUBSCRIBE bericht is er een Event-header, die volledig analoog is. Er is ook hier een Expires header terug te vinden, waarvan de waarde aangeeft hoelang de presence aangegeven door de inhoud van dit bericht geldig is. Deze header wordt echter genegeerd in dit systeem, m.a.w. de presence van een gebruiker blijft geldig tot hij ze zelf aanpast.
Hoofdstuk 2. Gebruikte technologiën
17
2.2.6 NOTIFY Een NOTIFY bericht wordt gebruikt om de presence informatie van notiers door te sturen naar hun subscribers. Een NOTIFY bericht zal dan ook een PIDF document als inhoud meekrijgen met daarin de huidige presence informatie van de notier. Op guur 2.10 is een voorbeeld NOTIFY bericht te zien waarbij Alice op de hoogte gebracht wordt van Erica's laatste presence informatie.
NOTIFY sip:
[email protected]:6060 SIP/2.0 Call-ID:
[email protected] CSeq: 2 NOTIFY From: "erica" <sip:
[email protected]>;tag=5211 To: "alice" <sip:
[email protected]>;tag=2368 Via: SIP/2.0/UDP 213.118.63.145:4000;branch=z9hg4bkdf35dbbd234212d8d2a8ce158651ff7f Max-Forwards: 70 Event: presence Content-Type: application/pidf+xml Subscription-State: Active;expires=3599 Content-Length: 128 <presence xmlns="urn:ietf:params:xml:ns:pidf" entity="sip:
[email protected]">
<status> open away 2006-05-23T20:15:24Z
Figuur 2.10: Een voorbeeld NOTIFY bericht met PIDF document als inhoud
Een NOTIFY bericht zal altijd voorzien zijn van een Event-header, zoals bij een SUBSCRIBE bericht.
Verder wordt er aan een NOTIFY bericht ook altijd een SubscriptionState-header
toegevoegd. Deze header zal de status van de inschrijving bevatten, en bij een actieve inschrijving, eventueel ook een expires parameter die aangeeft hoelang de inschrijving nog zal bestaan.
2.3 Session Description Protocol (SDP) Het Session Description Protocol (SDP) wordt gebruikt om de parameters voor multimediale sessies af te spreken. Het doel van SDP is om informatie over een multimediasessie beschikbaar
Hoofdstuk 2. Gebruikte technologiën
18
te maken aan geïnteresseerden, en erover te onderhandelen. De parameters omvatten de naam van de sessie, een beschrijving van de sessie, de tijd waarin de sessie actief is, de media die gebruikt worden (audio, video,...), en informatie over de gebruikte media (adressen, poortnummers, formaten (vb. video codecs, audio codecs, . . . )).
v=0 o=- 3357744591 3357744591 IN IP4 213.118.61.50 s=c=IN IP4 213.118.61.50 t=0 0 a=RTPMAP:0 PCMU/8000 m=audio 33334/2 RTP/AVP
Figuur 2.11: Een voorbeeld van een SDP bericht.
Een SDP bericht kan als inhoud toegevoegd worden aan een SIP bericht (dit zal typisch INVITE zijn) om op die manier met de verschillende partijen een gepast formaat af te spreken voor een multimediasessie (vb. een RTP sessie). In deze context wordt SDP hier ook gebruikt. SDP kan echter ook gebruikt worden in samenwerking met het Real Time Streaming Protocol (RTSP) of op een alleenstaande manier. Meer informatie over SDP kan gevonden worden in de RFC die SDP beschrijft, nl. [7].
2.4 Real-time Transport Protocol (RTP) Om een live media broadcast te zenden of te ontvangen, of om een video conferentie op te zetten over Internet of Intranet, is het van belang dat men in staat is media streams in real-time te zenden en te ontvangen. Hiervoor kan men het Real-time Transport Protocol gebruiken (RTP). Bij een RTP-sessie verzenden en ontvangen beide partijen data naar en van elkaar. In de volgende paragrafen zullen we de ontvangende partij de client noemen, de verzendende kant de server.
Real-time media kan door de client direct afgespeeld worden zonder dat de client moet wachten totdat de hele stream gedownload is van de server. In vele gevallen heeft de stream zelfs geen voorafgedenieerde duur, zodat het eerst downloaden van die stream onmogelijk is (vb. bij een telefoon- of audiogesprek of bij live streams van sportevenementen).
Hoofdstuk 2. Gebruikte technologiën
19
Media over het internet verspreiden in real-time vraagt een hoge network throughput.
Het is
makkelijker met verloren data om te gaan (een beetje kwaliteitsverlies van de mediastream is aanvaardbaar), dan met het veel te laat aankomen van data (het veel te laat aankomen van stukken van de media-stream is niet aanvaardbaar).
Om die reden zal RTP als onderliggend
protocol gebruik maken van UDP. UDP is een niet-betrouwbaar protocol.
Er is m.a.w.
geen
garantie dat alle verzonden pakketten ook gaan aankomen bij de ontvanger, en er is ook geen garantie dat indien ze aankomen dat ook in de juiste volgorde gebeurt.
RTP is het standaard Internet protocol voor het transport van real-time data, audio en video incluis. RTP bestaat uit een data- en controlegedeelte. Het controle gedeelte is het Real-Time Control Protocol (RTCP). Het datagedeelte van RTP biedt ondersteuning voor applicaties met real-time eigenschappen zoals continue media (vb. audio en video), inclusief tijdsreconstructie, controle op dataverlies, beveiliging en inhoudsidenticatie. RTCP daarentegen biedt ondersteuning voor real-time conferencing voor groepen van eender welke grootte binnen een IP-gebaseerd netwerk.
Het voorziet Quality-Of-Service (QOS) feed-
back van de clients naar de multicast groep. Ook wordt de synchronisatie tussen de verschillende streams door RTCP afgehandeld.
Voor verdere informatie over RTP verwijzen we graag naar [8].
2.5 Presence Information Data Format (PIDF) Het Presence Information Data Format (PIDF) is een standaard XML-gebaseerd formaat om presence informatie in voor te stellen. Onder presence informatie verstaat men onder andere de status van een bepaalde gebruiker (vb.
Online,Oine, Busy, Away,...), zoals veelvuldig
gebruikt in onder meer chatprogramma's. Deze presence data geeft een indicatie over de beschikbaarheid van de gebruiker voor anderen (voor een bepaalde vorm van communicatie). Ook de contactgegevens van de gebruiker kunnen hierin vervat zitten.
Hoofdstuk 2. Gebruikte technologiën
20
<presence xmlns="urn:ietf:params:xml:ns:pidf" entity="sip:
[email protected] ">
<status> closed 2006-05- 23T21:19:46Z
Figuur 2.12: Een voorbeeld van een PIDF document.
In de beschreven standaard van PIDF is er enkel standaard ondersteuning om als status ofwel open (d.i. Online) ofwel closed (d.i. Oine) mee te geven. PIDF biedt echter wel de mogelijkheid om extra informatie mee te geven die afwijkt van één van deze twee statussen (vb. de status Away) door een extra element toe te voegen. Dit wordt verder in meer detail beschreven (zie 3.4.2). Ook over PIDF bestaat er een RFC die meer informatie kan verschaen, nl. [9].
Als uitbreiding op PIDF kan ook het Rich Presence Information Data Format (RPID) gebruikt worden.
RPID wordt beschreven in een Internet-draft beheerd door de IETF ([10]).
RPID
voegt elementen toe aan het PIDF die extra informatie verschaen over de presentity en zijn contactpersonen.
2.6 Distributed Hashtable (DHT) Een Distributed Hashtable (DHT) of gedistribueerde hashtabel is in staat om data te distribueren over een groot peer-to-peer (p2p) netwerk en snel gegevens op te zoeken aan de hand van een gegeven sleutel. Het p2p netwerk wordt gevormd door een aantal nodes die elk een deel van de DHT opslaan.
Een DHT bestaat over het algemeen uit twee lagen: een routeringslaag die zorgt dat elke node binnen het p2p netwerk steeds toegankelijk is vanaf elke andere node in het netwerk, en een opslaglaag die de eigenlijke data van de DHT gedistribueerd zal opslaan, gebruikmakend van de routeringslaag. De opslaglaag is in feite naar buiten toe een Map-datastructuur.
Hoofdstuk 2. Gebruikte technologiën
21
2.6.1 Routeringslaag (routing layer) Een node wordt intern voorgesteld door een
k -bit
identier (ID). Dit ID wordt meestal bekomen
door consistent hashing: men neemt de hash van een vast gegeven van die node, vb. het IP-adres en de poort van het DHT-proces. De IDs worden gerangschikt in een ring, en elke node neemt dus een plaats in op die ring. Er zijn
2k
mogelijke IDs in de ruimte opgespannen door de IDs
(ook wel de identier space genoemd).
Voor de routering in een DHT-ring met n nodes zijn er twee mogelijkheden. We kunnen een naïef algoritme gebruiken waarbij elke node zijn buren kent, en dus het bericht gewoon zal doorsturen naar zijn buur. De performantie van dit algoritme is
O(n),
hetgeen weinig performant is in een
groot netwerk. Een betere optie is het gebruik van de zgn.
nger table.
een lijst bij van de adressen van enkele andere nodes.
a, a + 2, a + 4, a + 8, a + 16, ..., a + 2n−1 ,
waarbij
a
Elke node houdt in deze tabel
Dit zijn typisch de nodes met IDs
de opvolger in de ring (of successor) van
de huidige node voorstelt. Als een node nu een bericht dient te versturen, stuurt hij het bericht door naar de node uit zijn ngertabel die het dichtst bij de doelnode ligt (het ID van de gekozen node moet wel kleiner of gelijk zijn aan het ID van de doelnode). Met dit algoritme wordt een opzoekperformantie van
O(log(n))
bekomen. Om de ngertabellen van alle nodes over verschil-
lende joins (een nieuwe node komt in de ring) en leaves (een node verlaat de ring) van nodes consistent te houden moet wel wat extra onderhoud voorzien worden.
Hoofdstuk 2. Gebruikte technologiën
22
b+4 Node A a+8
Fingertable A: a, a + 2, a + 4, a + 8
Node C : b + 2
g
Ms
M
sg
a
b
b+8
Node B : a + 4
a+2
Fingertable B: b, b + 2, b + 4, b + 8
Figuur 2.13: Routering in een DHT-ring.
Figuur 2.13 laat een voorbeeld van het laatste algoritme zien. Node A wil een bericht sturen naar node C, en zal dus zijn ngertabel raadplegen om te weten te komen welke node waarvan hij het adres kent, het dichtst bij maar niet voorbij node C ligt. In het voorbeeld is dat node B, dus node A stuurt het bericht door naar node B. Node B zal nu op zijn beurt zijn ngertabel raadplegen, en zal tot de conclusie komen dat node C opgenomen is in zijn ngertabel, waarna het bericht naar node C gestuurd wordt.
2.6.2 Opslaglaag (storage layer) Op de nodes worden sleutel/waarde (key/value) paren opgeslagen, en aan de hand van de sleutel kan men dus de waarde opvragen die bij die sleutel hoort. De twee basisoperaties die een DHT moet voorzien zijn het opslaan van een sleutel/waarde paar, en het ophalen van een bepaalde waarde a.d.h.v. een gegeven sleutel.
Elke sleutel is ook een k-bit ID. Het is belangrijk dat de sleutels en de nodeIDs dezelfde ruimte beslaan, dit vormt namelijk de link tussen de routeringslaag en de opslaglaag. ruimte is dus gelijk aan de sleutelruimte (of key space).
De identier
Elke node dient die sleutels op te
Hoofdstuk 2. Gebruikte technologiën
23
slaan, waarvoor hij de verantwoordelijkheid krijgt. Hoe die verantwoordelijkheid bepaald wordt is afhankelijk van de gekozen implementatie. Een mogelijkheid is dat een node verantwoordelijk wordt gesteld voor alle sleutels die het dichtst bij zijn nodeID liggen (zoals in Pastry, zie [11]). Een andere mogelijkheid is een node verantwoordelijk stellen voor alle sleutels die tussen het eigen nodeID en dat van de predecessor liggen (zoals in Chord, zie [12]). Dit is de voorganger van de huidige node in de ring. Deze verantwoordelijke node noemen we dan de primaire node voor die sleutels. Er wordt meestal ook geopteerd om het sleutel/waarde paar ook redundant bij te houden op een paar successors van de primaire node. Dit heet men ook replicatie.
2.6.3 Voorbeeld In het onderstaande voorbeeld nemen we aan dat nodes verantwoordelijk zijn voor sleutel/waarde paren waarvan de sleutels numeriek het dichtst bij het nodeID liggen. Verder veronderstellen we dat bij joins en leaves in de ring steeds beide onmiddellijke buren van de node waar de verandering zich voordoet respectievelijk (verantwoordelijkheid over) sleutels kwijtraken en bijkrijgen.
2 8 -1 = 127
0
Intervallen voor nodes : ID = 15
ID = 78
Node 15 : ]110, 127] U [0, 21] Node 28 : ]21, 40] Node 53 : ]40, 65] Node 78 : ]65, 110]
ID = 28
ID = 53
Figuur 2.14: Een DHT-ring met 4 nodes.
Op guur 2.14 is een DHT-ring te zien met 4 nodes. Elke node heeft zijn eigen nodeID (resp. 15, 28, 53 en 78) en is verantwoordelijk voor de sleutels die het dichtst bij zijn eigen nodeID liggen. Voor node 28, bijvoorbeeld, zullen dit alle sleutels zijn die in het interval ]21,40] liggen.
Hoofdstuk 2. Gebruikte technologiën
24
Op de guur 2.15 zijn de sleutel/waarde paren aangeduid van nodes 15 en 28. Aangezien er een replicatiefactor van 1 gebruikt wordt, zal de successor van een node ook de sleutel/waarde paren (als replica) van die node bevatten.
Primair Key Value 2 8 -1 = 127
0
126
151
18
152
Replica's (78) ID = 15
Key
Value
82
781
ID = 78 Primair
ID = 28 ID = 53
Key 18
Value 152
Replica's (15) Key Value 216
151
18
152
Figuur 2.15: Dezelfde DHT-ring met verdeling van de gedistribueerde inhoud.
Als een nieuwe node de ring joint, dan worden de intervallen van sleutels waarvoor zijn nieuwe buren verantwoordelijk zijn, aangepast. Stel vb. dat een node met nodeID 20 de ring binnenkomt. Het interval van node 15 wordt dan verkleind tot
]110, 127] ∪ [0, 17],
het interval van node 28 tot
]24,40], terwijl node 20 verantwoordelijkheid krijgt over het interval ]17, 24]. Als gevolg van deze verandering in verantwoordelijkheid zal ook het sleutel/waarde paar 18/152 verplaatst worden naar node 20. De replica's van node 15, die opgeslagen waren op node 28 worden ook naar node 20 overgebracht. Concreet betekent dit dat node 20 volgende sleutel/waarde paren zal bevatten : 18/152 (node 20 is de primaire node voor sleutel 18) en 126/151 (als replica voor node 15). Merk op dat de replica voor 18/152 nog steeds op node 28 dient te staan, daar dit nu de opvolger is van de node die verantwoordelijk is voor 18/152. Het resultaat van de join van node 20 is te zien op guur 2.16.
Hoofdstuk 2. Gebruikte technologiën
2 8-1 = 127
25
Primair Key Value
0
126
151
ID = 15 Replica's (78) Key Value ID = 78
82
781
ID = 20 ID = 28 Primair
ID = 53
Primair
Key
Value
18
152
Replica's (15)
Key
Value
Key
Value
39
281
126
151
Replica's (20) Key Value 18
152
Figuur 2.16: DHT-ring nadat Node 20 de ring gejoined heeft.
Als een node de ring verlaat, zal een analoge operatie gebeuren.
De intervallen van de oude
buren zullen weer groter worden, en de data zal a.d.h.v. de replica's weer gedistribueerd worden naar de nodes die verantwoordelijk zijn (dit zullen m.a.w.
de oude buren van de weggevallen
node zijn). In DHT systemen zal men doorgaans wel kiezen voor een grotere replicatiefactor, omdat dit net hetgeen is dat het p2p netwerk beschermt van dataverlies. Hoe groter de replicatiefactor, hoe hoger de betrouwbaarheid (maar ook hoe groter de benodigde opslagruimte en het aantal berichten dat verstuurd moet worden om de replica's consistent te houden).
Hoofdstuk 3
High-Level Architectuur van het systeem In dit hoofdstuk wordt een beeld geschetst van alle ontwerpsbeslissingen op een vrij hoog abstractieniveau, en wordt de architectuur van het systeem gedeniëerd. Er zal een opsplitsing gemaakt worden tussen de Node-kant enerzijds, die de gebruiker- of client-kant van het programma is, en de SuperNode-kant anderzijds, die de server-kant van het programma is. Hoe het geheel als een gedistribueerd peer-to-peer (p2p) systeem tot stand gekomen is, en hoe de diverse componenten op SIP niveau met elkaar interageren, zal ook aan bod komen. Verder zal ook dieper ingegaan worden de diverse XML-formaten die gebruikt werden.
3.1 Inleiding Het gehele systeem moet in staat zijn om de gebruiker volgende features aan te bieden in een p2p netwerk :
•
Een gebruiker dient in staat te zijn om andere gebruikers uit te nodigen tot een multimediasessie.
•
Men moet de presence informatie van andere gebruikers kunnen opvragen en de eigen presence informatie kunnen aanbieden aan andere gebruikers.
26
Hoofdstuk 3. High-Level Architectuur van het systeem
•
27
De gebruikersvoorkeuren die aangeven wanneer en door welke (groepen van) gebruiker(s) men al dan niet wil kunnen bereikt worden, moeten instelbaar zijn en moeten persistent bijgehouden worden. Deze voorkeuren dienen uiteraard ook afgedwongen te worden.
•
De gebruikers moeten een persistente lijst van contactpersonen bij kunnen houden
•
Het systeem dient dit alles op een betrouwbare manier aan te bieden, en dus bestand te zijn tegen veranderingen in het p2p netwerk.
Om dit alles te voorzien werd besloten een opslitsing te maken tussen een zgn.
Node en een
SuperNode. Een Node is te beschouwen als een client-applicatie, een SuperNode als een serverapplicatie.
Het is echter wel mogelijk dat een gebruiker zowel een Node als een SuperNode
draaiende heeft.
Over de SuperNode heeft de gebruiker echter geen zeggenschap, hij kan de
SuperNode enkel starten en stoppen. Figuur 3.1 geeft een klein p2p netwerk weer met drie SuperNodes en drie Nodes. Op de guur is niet te merken of een bepaalde gebruiker zowel een Node als een SuperNode draait, aangezien deze twee entiteiten eigenlijk in de context van de architectuur los van elkaar te beschouwen zijn.
Node A SIPClient GUI
SuperNode 1
SuperNode 2
VoIP Manager
SIP-Proxy
SIP-Proxy Registrar
Presence Server
DHT
DHT
Presence Registrar Server
Node B
GUI
GUI VoIP Manager
SIP-Proxy
SIPClient
SuperNode 3
Node C
Presence Registrar Server
VoIP Manager
DHT
SIPClient
Figuur 3.1: Een voorbeeldopstelling met 3 SuperNodes en 3 Nodes.
Hoofdstuk 3. High-Level Architectuur van het systeem
28
In de volgende paragrafen zal dieper ingegaan worden op zowel de Node, als op de SuperNode. Waarvoor beide componenten instaan zal aan bod komen, alsook de diverse ontwerpsbeslissingen die hierover genomen zijn.
3.2 Node De Node component is de kant van het gehele systeem waar de eindgebruiker mee zal werken. De gehele Node kan opgesplitst worden in drie delen. Deze zijn: de SIP-Client, die instaat voor alle SIP-communicatie van en naar de gebruiker, de VoIP-Manager, die de eigenlijke spraaksessie zal behandelen nadat deze is opgezet door de SIP-Client, en de GUI, die de gebruiker een interface biedt om alles te kunnen bedienen. Voor verdere informatie over de werking van SIP bekijkt men best volgende secties in het vorige hoofdstuk: 2.1 en 2.2.
Node
VoIP Manager
SIP-Client
GUI
Figuur 3.2: De interne opsplitsing van de Node in deelcomponenten.
3.2.1 SIP-Client De SIP-Client laat de gebruiker toe zich te registreren bij een registrar, gecoloceerd met een SIPproxy (zie verder) zodat deze bereikbaar wordt voor andere gebruikers. Hij zal de gebruiker ook in staat stellen multimediasessies op te zetten (en af te sluiten) met andere gebruikers, presence informatie van andere gebruikers op te vragen en zelf zijn presence kenbaar te maken.
Hoofdstuk 3. High-Level Architectuur van het systeem
29
GebruikerA
GUI
SIP Client
Gebruiker B
Gebruiker C
VoIP Manager
Gebruiker D
Figuur 3.3: De SIP-Client doet dienst als portaal langs waar gebruikers met andere gebruikers in contact
kunnen komen.
De SIP-Client is in feite het portaal langs waar de gebruiker via SIP in contact kan treden met de andere gebruikers van het systeem (in tegenstelling tot de VoIPManager, die de eigenlijke mediasessie via RTP beheert). Deze verschillende aspecten zullen nu verder belicht worden.
Registratie Een gebruiker kan zich registreren bij een registrar d.m.v. een REGISTER bericht (de opbouw en de verdere uitleg over de eigenlijke SIP-berichten komen later aan bod). Een REGISTER bericht heeft als doel om in de registrar een binding te maken tussen de SIP-URI van de gebruiker en de contactURI van de gebruiker.
Eens een gebruiker geregistreerd is krijgt deze zijn zgn.
UserXML terug.
Er zal later dieper
ingegaan worden op deze UserXML. Nu volstaat het te weten dat een UserXML instaat voor het persistent bijhouden van de gegevens van een gebruiker, meer bepaald zijn Buddy List en zijn Preferences. De gebruikers wiens presence informatie men wil blijven ontvangen, zitten in de zgn. Buddy List (dit is te vergelijken met de lijst van contactpersonen in een chatprogramma).
Hoofdstuk 3. High-Level Architectuur van het systeem
30
De Preferences zijn een set van regels die de gebruiker kan instellen om al dan niet bereikbaar te zijn op een bepaald moment voor een bepaalde persoon, of voor een groep van personen. Deze preferences omvatten dus onder meer de mogelijkheid sommige gebruikers (eventueel gedeeltelijk) te blokkeren, zoals in andere systemen courant geïmplementeerd wordt door een blocklist.
Van zodra de gebruiker zijn UserXML teruggekregen heeft, zit hij volledig in het systeem. Het is nu mogelijk om een multimediasessie te beginnen en te stoppen met een andere gebruiker, presence informatie van andere gebruikers op te vragen, en zelf de eigen presence en preferences aan te passen.
Multimediasessies opzetten Om een multimediasessie met een andere gebruiker op te zetten wordt een INVITE SIP-request naar de proxy gestuurd met als bestemming de gebruiker die men wenst uit te nodigen tot een multimediasessie (d.i. genoemd).
de zgn.
callee; de gebruiker die de sessie initieert wordt de caller
De proxy zorgt ervoor dat het INVITE bericht gerouteerd wordt tot bij de callee
(eventueel via meer dan één proxy).
Deze laatste zal dan de keuze krijgen al dan niet in te
gaan op de uitnodiging tot het opzetten van een multimediasessie.
Een gepast SIP-response
bericht zal via dezelfde weg in omgekeerde zin teruggestuurd worden naar de proxy, die deze response zal doorsturen naar de caller. Indien de callee de uitnodiging aanvaardde, antwoordt de caller opnieuw met een ACK bericht om de uitnodiging af te ronden.
Dit is eigenlijk een
2-way handshake, zoals ook veel gebruikt in authenticatieprotocols. Met behulp van een SDP bericht dat aan het INVITE bericht (en de daaropvolgende response en ACK) toegevoegd wordt, kan er eventueel onderhandeld worden over het formaat waarin de multimediasessie zal gevoerd worden. Aangezien de focus van het gehele systeem niet op het gebruikte mediaformaat ligt, is ervoor geopteerd om slechts met één mediaformaat te werken. De caller stuurt een SDP bericht als inhoud van zijn INVITE bericht, en de callee stuurt in zijn OK-response altijd hetzelfde SDP bericht terug. In dat opzicht wordt er niet echt onderhandeld over een mediaformaat. Een multimediasessie zal afgesloten worden van zodra ofwel de caller ofwel de callee een BYE SIP-bericht stuurt naar de andere partij. Dit gebeurt point-to-point en niet hop-by-hop zoals de andere berichten. Van zodra het BYE bericht gestuurd is, wordt de sessie door de sturende partij als afgesloten beschouwd. De partij die het BYE bericht ontvangt, zal evenwel toch nog een OK response terugsturen en dan ook de sessie als gesloten beschouwen.
Hoofdstuk 3. High-Level Architectuur van het systeem
31
Eigen presence informatie aanpassen Indien een gebruiker iets aanpast aan zijn presence informatie (vb. hij verandert zijn status van Oine naar Away), dan zal hij zijn verantwoordelijke proxy, die in dit systeem ook als PA dient, daarvan op de hoogte brengen d.m.v. een PUBLISH SIP-bericht met als inhoud een PIDF document met zijn nieuwe presence informatie.
De proxy zal dan de presence informatie van
die gebruiker, die hij in het geheugen opgeslagen heeft, aanpassen aan de ontvangen presence informatie. Figuur 3.4 toont gebruiker Alice die haar status verandert van Busy naar Online.
STAP 2 : PUBLISH <"Online">
Alice
Proxy
STAP 3
STAP 1 : ''Busy'' => ''Online''
Presence Info Alice
''Busy'' ''Online''
Bob
''Offline''
Figuur 3.4: Alice verandert haar status van Busy naar Online.
Presence informatie van andere gebruikers ontvangen Om als gebruiker op de hoogte gebracht te worden van de presence van een andere gebruiker zijn er twee mogelijkheden: ofwel kan men een polling-systeem gebruiken, ofwel kan men zich inschrijven bij (de PA van) een bepaalde gebruiker om diens presence informatie te ontvangen telkens deze zijn presence aanpast. Beide manieren worden door de SIP-client ondersteund, en kunnen dus in het programma gebruikt worden. Welk van de twee gebruikt zal worden hangt af van welke parameters ingevuld zijn in de conguratiele van de client. In de volgende sectie zal de gebruiker die de presence informatie wenst te ontvangen, de subscriber genoemd worden. De gebruiker wiens presence informatie men wenst te ontvangen wordt de notier genoemd.
Hoofdstuk 3. High-Level Architectuur van het systeem
32
Zowel het polling-systeem als het systeem van het inschrijven zullen nu meer in detail beschreven worden.
Het polling-systeem (fetching): Bij het polling-systeem zal telkens na een bepaalde tijd door de subscriber een SUBSCRIBE SIP-bericht gestuurd worden met als speciale eigenschap dat de zgn. Expires-header een waarde gelijk aan 0 heeft. Dit wordt een fetcher genoemd. Als zo'n fetch bericht aankomt in de PA van de notier, dan zal deze een OK response terugsturen, en daarna een NOTIFY SIP-bericht met als inhoud een PIDF document dat de huidige presence informatie van de notier bevat. De subscriber zal op zijn beurt dit NOTIFY bericht beantwoorden met een OK response. De fetch berichten worden door de SIP-client op regelmatige basis gestuurd voor elke gebruiker in de Buddy List van de subscriber. Er zijn twee nadelen verbonden aan het polling systeem. Ten eerste is het mogelijk dat er meer netwerkverkeer gegenereerd wordt indien subscribers een kort fetching-interval hanteren. inconsistent is, m.a.w.
Ten tweede is er een interval waarin de presence van een notier
dat deze zijn presence ondertussen al opnieuw heeft aangepast, en de
subscriber zich hier niet van bewust is.
In guur 3.5 stuurt Charles om de 10 minuten een SUBSCRIBE met Expires = 0 om de presence van Alice te weten te komen.
De proxy van Charles kent Alice niet, dus dient hij het
SUBSCRIBE bericht door te zenden naar een proxy die Alice wel kent, in dit geval Proxy 2. Deze proxy zal, als PA van Alice, de huidige presence informatie van Alice terugsturen a.d.h.v. een NOTIFY bericht met als inhoud een PIDF document met de huidige presence van Alice. Charles zal dus, onafhankelijk van het feit of Alice al dan niet haar presence aangepast heeft, op geregelde tijdstippen de presence informatie van Alice fetchen. Merk op dat op de guur de OK responses weggelaten zijn, dit om de duidelijkheid te bevorderen.
Hoofdstuk 3. High-Level Architectuur van het systeem
STAP 2 : SUBSCRIBE Expires = 0
STAP 1 : SUBSCRIBE Expires = 0
S Charles
33
Proxy 1 STAP 4 : NOTIFY <"Online">
Proxy 2 STAP 3 : NOTIFY <"Online">
N Alice
Presence Info Alice
''Online''
Bob
''Offline''
Figuur 3.5: Charles gebruikt het polling systeem om de presence info van Alice te weten te komen.
Het systeem van het inschrijven: Indien gebruik gemaakt wordt van het andere systeem, dient de subscriber eerst een SUBSCRIBE SIP-bericht te sturen om aan te geven dat hij zich (voor een bepaalde tijd, aangegeven door de waarde van de Expires-header) wenst in te schrijven voor de presence informatie van de notier. Na een OK response ontvangen te hebben op dit SUBSCRIBE bericht zal deze meteen ook een NOTIFY bericht ontvangen met als inhoud de huidige presence info van de notier. De subscriber zal als antwoord hierop ook een Ok response terugsturen. Telkens de notier iets verandert aan zijn presence informatie zal deze, zoals eerder vermeld, een PUBLISH SIP-bericht (met als inhoud een PIDF document) naar zijn verantwoordelijke proxy sturen. De PA van deze proxy zal de in het geheugen opgeslagen presence informatie voor de notier aanpassen aan de zopas ontvangen informatie. De PA zal ook voor elke subscriber op deze notier een NOTIFY SIP-bericht sturen met daarin de nieuwe presence informatie. Het voordeel van dit systeem is dat de subscribers enkel op de hoogte gebracht worden van de presence van de notier indien deze notier eectief iets aan zijn presence informatie veranderd heeft. Merk op dat het fetching-systeem eigenlijk een speciaal geval is van het inschrijf-systeem, namelijk een inschrijving die maar 0 seconden duurt. In guur 3.6 zullen Donna en Erica enkel een NOTIFY bericht ontvangen indien Alice eerst haar nieuwe status publiceert. Er wordt wel verondersteld dat Donna en Erica beiden ingeschreven zijn om de presence van Alice te ontvangen. Opnieuw zijn de OK responses weggelaten om de duidelijkheid te bevorderen.
Hoofdstuk 3. High-Level Architectuur van het systeem
Donna S
STAP 5 NOTIF : <"Onl Y ine">
STAP 4 : NOTIFY <"Online"> Proxy 1
Erica
: STAP 5 Y NOTIF > ine" <"Onl
STAP 2 : PUBLISH <"Online">
Proxy 2
STAP 4 : NOTIFY <"Online">
Alice N
STAP 1 : ''Busy'' => ''Online'' STAP 3
S
34
Presence Info Alice
''Busy'' ''Online''
Bob
''Offline''
Figuur 3.6: Donna en Erica ontvangen enkel een update van de presence van Alice als deze haar presence
verandert.
De Buddy List en preferences Een gebruiker heeft de mogelijkheid om de contactpersonen in zijn Buddy List te verdelen in groepen. Een bepaalde contactpersoon kan maar tot één groep behoren, en er dient altijd minimum één groep te zijn. Gebruikers die niet in de Buddy List van de desbetreende gebruiker aanwezig zijn, behoren per denitie tot de groep Unknown.
Onder de preferences of voorkeuren van een gebruiker verstaan we de verzameling van regels die een gebruiker kan deniëren om andere gebruikers al dan niet toe te laten hem te contacteren en zijn presence informatie op te vragen. Regels kunnen zowel voor een groep als voor een aparte contactpersoon gedeniëerd worden. Elke regel die voor de groep geldt, geldt automatisch voor alle contactpersonen in die groep. Een regel heeft typisch de vorm ACTIE - VAN - TOT. De ACTIE is ofwel een ALLOW ofwel een DENY commando.
Indien er onderling tegenstrijdige
regels aanwezig zijn, heeft de regel voor de contactpersoon voorrang op de regels voor de groep. Een DENY commando heeft voorrang op een ALLOW commando als deze conicteren (enkel binnen dezelfde orde van regels, m.a.w. binnen een groep, of bij een contactpersoon).
Hoofdstuk 3. High-Level Architectuur van het systeem
35
Indien er geen regels aanwezig zijn voor een bepaalde contactpersoon (er gelden dus geen regels voor de persoon zelf, en ook niet voor de groep waartoe de contactpersoon behoort), dan wordt dat als een ALLOW_ALL commando aanzien. Het volledige principe is eigenlijk te vergelijken met dat van een rewall.
De SuperNode, verantwoordelijk voor de gebruiker, die onder meer de proxy en PA omvat, wordt altijd op de hoogte gebracht van veranderingen aan de preferences.
Dit gebeurt d.m.v.
een
PUBLISH SIP-bericht met een speciale inhoud (een Preferences-XML, zie 3.4.4). De proxy dient op de hoogte gehouden te worden om twee redenen: de preferences moeten persistent gemaakt worden indien de gebruiker het systeem verlaat en later terugkomt, en de proxy heeft de preferences nodig om na te kunnen gaan of hij een andere gebruiker toelating mag geven tot het initiëren van een multimediasessie met deze gebruiker, en of hij de presence informatie van deze gebruiker vrij mag geven aan een andere gebruiker.
Een voorbeeld: Alice heeft twee personen in haar Buddy List, nl. Bob en Erica. Zowel Bob en Erica zitten in de groep Friends, waarvoor de volgende regel bestaat: ALLOW - Van: 13u30 Tot: 15u30. Voor Bob heeft Alice nog de regel DENY - Van: 14u30 - Tot : 14u45 toegevoegd. Voor de Unknown groep (die standaard aanwezig is in elke UserXML), heeft Alice ook een regel voorzien, nl. DENY - Van: 00u00 - Tot: 23u59. Stel nu dat het op dit moment 14u00 is en Erica komt binnen in het systeem. Erica heeft ook Alice in haar Buddy List zitten, en zal dus de presence informatie van Alice proberen bemachtigen. De proxy van Alice zal nu kijken of Erica toestemming heeft om de presence info van Alice te krijgen. Erica behoort tot de groep Friends, waarvoor een regel bestaat. Deze regel zal Erica de toestemming geven de presence info van Alice te bemachtigen.
Als Bob echter om 14u35 een multimediasessie met Alice wil
initiëren zal de proxy verantwoordelijk voor Alice echter geen toestemming geven, aangezien de regel voor Bob (DENY - Van: 14u30 - Tot: 14u45) voorrang heeft op de regel van de groep Friends (omdat het een regel voor een contactpersoon betreft). Moest nu iemand die niet in de Buddy List van Alice zit proberen Alice te bellen, dan zou dit ook niet toegelaten zijn, aangezien die gebruiker zal getoetst worden aan de regels voor de Unknown groep, en deze laten niet toe Alice te contacteren van 00u00 tot 23u59.
Hoofdstuk 3. High-Level Architectuur van het systeem
36
3.2.2 VoIP-Manager De VoIP-Manager staat in voor het verzorgen van de RTP multimediasessie tussen de caller en de callee eens een uitnodiging aanvaard is. Hij bestaat uit twee onderdelen: de Processor en de Player. De Processor is het gedeelte dat de media opneemt, dit in RTP-pakketten verpakt, en deze verzendt naar de andere partij. De Player is het gedeelte dat de RTP-pakketten ontvangt, en deze terug afspeelt. Zowel de caller en de callee hebben dus een Processor en een Player nodig. De Processor is dus de kant vanwaar de RTP vertrekt op guur 3.7, terwijl de Player de kant is die de RTP ontvangt, en dit voor de beide richtingen.
Gebruiker A
Gebruiker B
GUI
GUI RTP
SIP Client
VoIP Manager
VoIP Manager
SIP Client
RTP
Figuur 3.7: Gebruiker A en gebruiker B bellen met elkaar door hun VoIPManager-componenten.
In dit ontwerp is voor de eenvoud gekozen voor enkel spraak/audiosessies, vandaar ook de naam van de component. Er zijn echter veel opties die hier ingeplugd zouden kunnen worden, zoals videochat, audio- en videoconferencing, of eenvoudigweg een tekstgebaseerde chatsessie.
3.2.3 GUI De Grasche User Interface (GUI) biedt de gebruiker een beeld op zijn deel van het systeem en de mogelijkheid interactief met het systeem te werken. De eigenlijke GUI van het programma wordt voorafgegaan door een zgn.
Initiële GUI, die
de gebruiker toelaat om een SuperNode op te starten, of om in te loggen met een ingegeven
Hoofdstuk 3. High-Level Architectuur van het systeem
37
gebruikersnaam. Als er ingelogd wordt, zal de eigenlijke GUI verschijnen. Deze GUI is opgebouwd uit verschillende panelen die elk voor een ander aspect van het programma instaan.
Er is een gedeelte waar men kan registreren bij een registrar (en ook een
bestaande registratie ongedaan kan maken), een gedeelte om andere gebruikers uit te nodigen voor een multimediasessie, een stuk om de eigen presence aan te passen, een gedeelte voor (het beheer van) de Buddy List en nog een gedeelte om een SuperNode op te starten of af te sluiten.
Bij het gedeelte voor de Buddy List zijn verschillende opties mogelijk : men kan een contactpersoon toevoegen, een contactpersoon verwijderen, een contactpersoon uitnodigen tot een multimediasessie, of regels instellen of aanpassen voor een bepaalde contactpersoon. Dit laatste roept een nieuw scherm op. Regels voor groepen kan men instellen of aanpassen in een apart scherm dat opgeroepen kan worden via het menu.
3.3 Supernode De SuperNode component representeert de serverzijde van de applicatie. Deze component bestaat uit twee grote delen. Ten eerste de SIP-proxy, die instaat voor het afhandelen van alle SIP communicatie en ten tweede de DHT, die instaat voor het consistent gedistribueerd opslaan van de persistente data, meerbepaald de UserXMLs. Verder zal de SuperNode ook instaan voor het beheer van de UserXMLs zelf, en vormt dus als het ware de lijm tussen de SIP-proxy en de DHT.
SuperNode SIP-Proxy Registrar
DHT
PresenceServer
Figuur 3.8: De interne opsplitsing van de SuperNode in deelcomponenten.
Hoofdstuk 3. High-Level Architectuur van het systeem
38
3.3.1 SIP-proxy Zoals hierboven vermeld staat de SIP-proxy in voor het afhandelen van alle SIP communicatie. Dit omvat onder meer de locatiedienst, meerbepaald de registrar, die REGISTER requests zal afhandelen. Ook de presenceserver zit vervat in de SIP-proxy. Naast deze twee interne componenten zal de SIP-proxy uiteraard ook andere verantwoordelijkheden hebben, zoals het valideren en doorsturen van requests en responses die op de SIP-proxy toekomen.
Een SIP-proxy luistert op minstens één poort naar binnenkomende berichten.
Dit kan over
UDP of TCP gebeuren, met de verplichting dat voor elke open UDP poort de proxy ook TCP connecties aanvaardt op diezelfde poort. Dit is noodzakelijk omdat via TCP berichten kunnen verstuurd worden die de maximum message size (MMS) van UDP overschrijden indien dit zou voorvallen.
Een SIP-proxy heeft ook een lijst van domeinen waarvoor hij verantwoordelijk is, zoals nist.gov, ugent.be of thesis.test. Een algemene proxy kan verantwoordelijk zijn voor meerdere domeinen en berichten routeren die uit deze domeinen komen en/of ernaartoe gaan. Door de aard van deze applicatie zal hier slechts één domein gebruikt worden, nl. thesis.test. Indien men toch meerdere domeinen wil gebruiken, zal elke proxy in het systeem verantwoordelijk moeten zijn voor elk van deze domeinen.
De oorzaak hiervan is dat het verdelen van de verantwoordelijkheid over
de gebruikers (van een bepaald domein) via de DHT niet vastgelegd kan worden, maar hiermee lopen we wat vooruit op de zaak.
Registrar De registrar implementeert een locatiedienst, zoals reeds beschreven in hoofdstuk 2.
Deze lo-
catiedienst is een soort van databank of telefoonboek dat de SIP-URI van een gebruiker (vb. sip:
[email protected]) mapt op zijn huidige contactURI(s) (vb.
sip:
[email protected]:6060).
Dit noemt men een binding. Voor één gebruiker kunnen meerdere bindingen tegelijkertijd aanwezig zijn (als de gebruiker zich vanaf meerdere locaties en/of toestellen registreert). Typisch zullen vele gebruikers geregistreerd zijn bij één registrar.
Hoofdstuk 3. High-Level Architectuur van het systeem
39
Gebruikers registreren zich bij de registrar door het sturen van REGISTER requests naar de proxy waarmee de registrar gecoloceerd is. Wanneer een gebruiker zich registreert en de SuperNode waarop de proxy (en dus ook de registrar) loopt verantwoordelijk is voor die gebruiker, dan zal in het antwoord op het REGISTER request de UserXML van die gebruiker meegestuurd worden als inhoud van de OK response. Zo krijgt de nu geregistreerde gebruiker zijn Buddy List en Preferences terug, en kan hij verdergaan met de data die op het einde van zijn laatste sessie aanwezig was.
Registraties hebben een beperkte duur, aangegeven door de waarde van de Expires header in het REGISTER bericht. Dit zal typisch in de orde van een of meerdere uren zijn. Dit impliceert ook dat een gebruiker regelmatig zijn registratie moet verversen, aangezien de registrar verlopen registraties zal schrappen uit zijn databank.
Gebruikers kunnen ook hun registratie ongedaan maken door een REGISTER bericht te sturen met een waarde 0 voor de Expires header.
Dit verwijdert de binding voor de contactURI
aangegeven in de Contact header van het bericht.
Indien een gebruiker al zijn bindingen in-
eens wil verwijderen, moet die naast de waarde 0 voor Expires ook een waarde * voor de Contact header opgeven.
De registrar heeft ten behoeve van de proxy component ook voorzieningen voor het opvragen of een gebruiker al dan niet hier geregistreerd is, en indien dit zo is, van die gebruiker de (meest recente) contactURI op te vragen.
SIP-URI sip: alice @ thesis.test sip: bob@ thesis.test sip: claire @ thesis.test sip: erica @ thesis.test
ContactURI sip: alice @157.193.215.21:6060 sip: alice @157.193.215.23:5560 sip:
[email protected]:5060 sip: claire @213.118.60.224:6060 sip: erica @213.118.60.12:5060 sip: erica @157.193.215.24:5060
Figuur 3.9: Enkele bindings in de registrar.
Hoofdstuk 3. High-Level Architectuur van het systeem
40
Presenceserver De presenceserver behandelt alle requests en responses op SIP-berichten die iets met presence te maken hebben, d.i. PUBLISH, SUBSCRIBE en NOTIFY.
Deze component treedt op als Presence Agent (PA) voor alle gebruikers (in deze context ook presentities of notiers genoemd) die op de registrar geregistreerd zijn, en zal dus in hun naam NOTIFY berichten sturen naar hun subscribers. Dit uiteraard enkel indien de subscribers toelating hebben om de presence van de notier te ontvangen, waarover later meer. Dit impliceert dat de presentities hun presence informatie kenbaar maken aan de PA. Dit gebeurt zoals reeds vermeld door middel van PUBLISH berichten. De PA zal dan alle verdere nodige communicatie met eventuele subscribers afhandelen (door hen NOTIFY berichten te sturen met daarin de nieuwe presence info van de notier). Het voordeel van dit systeem is dat de presentity zelf eigenlijk niks af hoeft te weten van zijn subscribers, en ook geen enkel bericht naar hen hoeft te sturen. De communicatie van de presence informatie tussen presentity en PA is de enige vereiste.
Een belangrijke opmerking hierbij is dat bij het binnenkomen van een REGISTER request ook de presenceserver hiervan op de hoogte moet gebracht worden, aangezien hiermee de contactURI van de presentity wordt geüpdatet. Ook is het mogelijk dat er reeds subscribers ingeschreven zijn op deze notier, en deze moeten dan gelijk op de hoogte gebracht worden van zijn presence informatie. Dit is duidelijk ook het geval bij het wissen van een registratie, aangezien de presence status dan zeker op Oine komt te staan.
Alle SUBSCRIBE berichten die toekomen in de SIP-proxy en bestemd zijn voor een gebruiker waarvoor deze SuperNode verantwoordelijk is, zullen afgeleid worden naar de presenceserver, die deze SUBSCRIBEs dan verder afhandelt. Gebruikers kunnen zoals reeds vermeld de presence informatie van andere gebruikers opvragen door het sturen van SUBSCRIBE berichten, die een inschrijving aanmaken voor een bepaalde tijd (aangegeven door de waarde van de Expires header). In dit opzicht zijn inschrijvingen t.a.v. de presenceserver zeer gelijkaardig aan registraties t.a.v. de registrar. De presenceserver beheert ook deze inschrijvingen en verwijdert ze indien ze verlopen zijn.
Hoofdstuk 3. High-Level Architectuur van het systeem
41
Een subscriber kan ook zijn inschrijving opzeggen door een SUBSCRIBE te sturen met waarde 0 voor Expires. Hierna krijgt deze subscriber nog één NOTIFY bericht van de presenceserver (na de OK response op zijn SUBSCRIBE). Op dat moment is de inschrijving echter al vernietigd.
De presenceserver vangt zoals gezegd alle presencegerelateerde SIP-berichten op. Hierbij zijn ook twee speciale gevallen te onderscheiden waarbij de presenceserver interageert met de omvattende SuperNode, nl. die berichten waaraan een inhoud is toegevoegd in de vorm van een BuddyXML of een PreferencesXML. Dit zijn respectievelijk SUBSCRIBE en PUBLISH. Indien zo'n bericht toekomt in de presenceserver zal deze via zijn SuperNode de XML-inhoud parsen en afhankelijk van welk soort XML het is (en de inhoud ervan) de gepaste actie uitvoeren op de betreende UserXML, en deze aangepaste UserXML opnieuw opslaan via de SuperNode. Over de exacte opbouw van de XML inhoud en verdere uitleg over de werking van het bovenstaande verwijzen we graag naar secties 3.2.1, 3.4.3 en 3.4.4
Validatie van inkomende requests De SIP-proxy krijgt logischerwijze een hele hoop requests te verwerken. Om te vermijden dat de verwerking van deze berichten vastloopt bij een foute berichtstructuur of ontbrekende headers, moet elk request eerst gecontroleerd worden op zijn geldigheid. Dit garandeert dan ook onmiddellijk dat geen verkeerde berichten worden doorgestuurd over het netwerk, en andere componenten zich dus geen zorgen hoeven te maken over het controleren van de geldigheid van de inkomende requests. De uitgevoerde controles omvatten onder meer:
•
de syntax van het bericht
•
URI schema ondersteuning (niet alle applicaties ondersteunen alle mogelijke URI schema's)
•
lus detectie (als een proxy zichzelf twee keer passeert op het pad naar de bestemming, zit er een lus in het systeem)
•
max forwards (als het maximum aantal hops dat een bericht mag passeren bereikt is, mag de proxy dit niet meer doorsturen)
Indien één of meerdere van de controles een fout bericht detecteert, zal de proxy een gepast response bericht terugzenden naar de afzender, waarin aangegeven wordt wat er fout was aan
Hoofdstuk 3. High-Level Architectuur van het systeem
42
het verstuurde request. Dit garandeert onmiddellijk ook dat er geen nodeloze netwerktraek zal gegenereerd worden door andere componenten in de vorm van responses die aangeven dat het inkomende request fout was, aangezien een request altijd eerst een proxy moet passeren vooraleer naar zijn bestemming gerouteerd te worden.
Doorsturen van requests en responses Als een proxy een bericht (request of response) ontvangt voor een gebruiker waarvoor deze SuperNode verantwoordelijk is, dan zal deze dat bericht doorsturen naar die gebruiker. Hiertoe vervangt de proxy de request URI van het bericht door de contact URI van de bestemmeling, die van de registrar verkregen wordt. Indien deze SuperNode niet verantwoordelijk is voor de bestemmeling, dan zal de proxy het bericht (quasi) ongewijzigd proberen doorsturen naar de locatie aangegeven in de request URI. Indien de locatie onbekend blijkt, zal de proxy proberen via DNS de hostnaam te resolveren tot een IP adres. De enige wijzigingen die aangebracht zullen worden in het bericht zijn voorzieningen die nodig zijn om eventuele antwoorden op het bericht langs hetzelfde pad terug te kunnen sturen, en om te voorkomen dat een bericht eeuwig zou blijven rondzwerven op het netwerk. Meer speciek zullen, afhankelijk van het bericht, Via headers worden toegevoegd of verwijderd, Record-Route headers worden toegevoegd, en Route headers worden verwijderd. Ook zal bij elke hop die het bericht passeert, de waarde van de Max Forwards header met 1 worden verminderd. Voor meer informatie omtrent deze voorzieningen en de noodzaak hieraan verwijzen we graag naar [3]. Dit is eigenlijk één van de voornaamste taken van een (SIP-)proxy.
3.3.2 Gedistribueerde hashtabel (DHT) Deze component heeft twee grote functies: het consistent gedistribueerd opslaan van de UserXMLs en het opzoeken van de verantwoordelijke SuperNode (en dus ook proxy) voor een bepaalde gebruiker (via zijn SIP-URI, vb.
[email protected]). Elk van deze componenten vormt een deel van het p2p netwerk dat de DHT ondersteunt. In de onderstaande secties zal met het begrip node een component van dit DHT overlay-netwerk aangeduid worden. Deze node stemt dus overeen met de DHT component van de SuperNode uit het systeem.
Hoofdstuk 3. High-Level Architectuur van het systeem
43
Opslagfunctie De DHT-component zal verantwoordelijk zijn voor het opslaan van de UserXMLs van alle gebruikers in het systeem. Deze opslag moet gelijkmatig gedistribueerd gebeuren over alle nodes van het p2p netwerk (en dus over alle SuperNodes aanwezig in het systeem). Hiermee wordt bedoeld dat elke node een ongeveer even groot deel van alle UserXMLs moet opslaan. De opslag moet ook consistent zijn, wat betekent dat er nooit twee verschillende UserXMLs voor dezelfde gebruiker in het systeem bewaard worden, en dat op elk gegeven tijdstip alle nodes tesamen alle UserXMLs bevatten.
Deze twee voorwaarden moeten steeds voldaan zijn, en specieker moeten ze ook voldaan blijven wanneer het onderliggende p2p-netwerk verandert door het binnenkomen van nieuwe nodes in het systeem (joins) en het verlaten van het netwerk door bepaalde nodes (leaves), zonder dat op voorhand geweten is wanneer deze veranderingen zich zullen voordoen.
Het probleem van steeds alle data te blijven opslaan, ook al vallen er nodes weg uit het netwerk, wordt opgevangen door replicatie. Hiertoe zal alle data niet alleen op een primaire node bewaard worden, maar zal ook op (minstens) één andere node een kopie van de betreende data redundant bewaard worden. Deze redundante kopie wordt een replica genoemd. Door het instellen van een replicatiefactor die aangeeft hoeveel replica's er bewaard worden voor elk dataobject is het systeem verzekerd tegen leaves van nodes. Indien de replicatiefactor 1 is, dan is het systeem bestand tegen het uitvallen of leaven van 1 node per keer.
Stellen we de
replicatiefactor in op een waarde n, dan zal het systeem bestand zijn tegen het gelijktijdig uitvallen van n nodes. Uiteraard geldt hierbij: hoe hoger de replicatiefactor, hoe meer opslagruimte vereist zal worden, aangezien elke replica evenveel plaats inneemt als het primaire object.
Het gelijkmatig verdelen van alle data over alle aanwezige nodes in het netwerk zal worden opgevangen door telkens een node het netwerk vervoegt, de data opnieuw te distribueren indien nodig. Hiertoe wordt een mechanisme toegepast van consistent hashing op de SIP-URI van de gebruikers van wie het systeem de UserXMLs opslaat.
Hoofdstuk 3. High-Level Architectuur van het systeem
44
Consistent hashing is een hashingtechniek voor hashtabellen die ervoor zorgt dat het toevoegen of verwijderen van een bucket in de hashtabel de verdeling van de sleutels over de verschillende buckets van de tabel niet zwaar verstoort.
Dit verkleint de nood aan herverdeling van sleu-
tel/waarde paren, wat dit systeem uiteraard ten goede komt. De hash van de SIP-URI geeft dan de sleutel waarop de UserXML zal gemapt worden, en de node verantwoordelijk voor deze sleutel zal dan het corresponderende sleutel/waarde paar opslaan, hier dus SIP-URI/UserXML. Zie in dit verband ook sectie 2.6 en meerbepaald 2.6.2.
Opzoekfunctie Het voorgestelde systeem steunt voor locatiebepaling van gebruikers op de registrar-component van de SIP-proxy.
Aangezien nu elke node in het netwerk (die dus deel van een SuperNode
uitmaakt) een deel van alle UserXMLs opslaat, zal de gebruikerslocatiedata gefragmenteerd zijn over de verschillende registrar-componenten behorend bij de nodes. Om dus steeds alle gebruikers te kunnen bereiken, zal er een manier moeten voorzien worden om vanaf één bepaalde node het adres op te vragen van de proxy-component waarvan de omvattende SuperNode verantwoordelijk is voor de data van te bereiken gebruiker. Met het adres wordt hier de combinatie van ip-adres, poortnummer en netwerkprotocol bedoeld. De standaard zoekfunctie van een DHT laat over het algemeen enkel toe de waarde behorend bij een bepaalde sleutel op te vragen, en laat niet toe het adres van de node waarop dit sleutel/waarde paar is opgeslagen op te vragen. Een bijkomende moeilijkheid is dat niet het adres van de node teruggegeven moet worden, maar wel dat van de proxy-component gecoloceerd met de node.
Hoofdstuk 3. High-Level Architectuur van het systeem
SuperNode A
Proxy
verantw . SN voor de callee ?
DHT
INVITE
SuperNode B verantw . SN voor de callee?
next hop?
45
DHT
next hop ProxyLP B in inhoud
DHT
Proxy
INVITE
Callee
ProxyLP B in inhoud
INVITE
Figuur 3.10: De opzoekfunctie nodig om de verantwoordelijke SuperNode te vinden (zoals nodig voor
routering van SIP berichten).
Samenwerking van de DHT met de andere componenten De opzoekfunctie van de DHT vormt samen met de registrar het mechanisme voor locatiebepaling en routering in het volledige systeem. Telkens een proxy-component een request ontvangt voor een gebruiker die niet gekend is (waarvoor m.a.w. geen registratie bestaat in zijn registrar, of nog: waarvoor zijn omvattende SuperNode niet verantwoordelijk is), zal deze via zijn SuperNode een opzoekoperatie uitvoeren om het adres te bekomen van de proxy waarvan de omvattende SuperNode wel verantwoordelijk is voor die gebruiker. Eens dit adres verkregen is, zal de proxy het request doorsturen naar het bekomen adres.
Het voorgestelde systeem zal dus een maximum van 2 tussenliggende SIP-hops (proxies) hebben, aangezien steeds onmiddellijk de verantwoordelijke proxy voor een gebruiker wordt opgezocht via de DHT indien diens UserXML niet gevonden werd in de eigen SuperNode. Het DHT-systeem impliceert ook dat UserXMLs kunnen verhuizen van de ene SuperNode naar de andere. Als er namelijk een SuperNode opgestart of afgesloten wordt, zal dit uiteraard ook de DHT beïnvloeden, die indien nodig sleutels/waarde paren zal herverdelen over de nodes van het p2p netwerk. Hierdoor kan de verantwoordelijkheid voor een bepaalde gebruiker veranderen van SuperNode. Om dit op te vangen en ervoor te zorgen dat een op dat moment geregistreerde gebruiker naar zijn nieuw verantwoordelijke SuperNode wordt afgeleid, zal ook speciale onder-
Hoofdstuk 3. High-Level Architectuur van het systeem
46
steuning moeten voorzien worden. Ook voor de eventuele inschrijvingen van andere gebruikers moet een oplossing gevonden worden. Bij dit laatste is er een voor de hand liggende keuze: ofwel wordt elke inschrijving vanuit de (oude) presenceserver zelf getermineerd en wordt aan de subscribers overgelaten zich na een bepaalde tijd opnieuw in te schrijven (waarbij door het opzoekmechanisme de nieuwe inschrijving automatisch bij de nieuwe SuperNode zal toekomen); ofwel moeten de subscribers ingeschreven voor een bepaalde gebruiker ook persistent bijgehouden worden, en dus ook mee verhuizen met de UserXML van die gebruiker, waarna de (nieuwe) presenceserver deze subscribers op de hoogte zal brengen van veranderingen in de presence van de notier.
3.3.3 Verdere functies In de voorgaande paragrafen werd de werking van de verschillende componenten van de SuperNode uitgelegd. Het mag duidelijk zijn dat de SuperNode zelf al deze componenten integreert tot een samenhangend geheel.
Het gehele systeem werkt in op de UserXML objecten, en de
SuperNode is verantwoordelijk voor het updaten van deze data, evenals voor het coördineren van de acties van de SIP-proxy en de DHT.
Bij het beheer van de UserXMLs hoort ook de autorisatie van inschrijvingen en uitnodigingen tot opzetten van multimediasessies naar gebruikers waarover deze SuperNode de verantwoordelijkheid heeft.
Zoals reeds vermeld, is deze autorisatie afhankelijk van de Preferences die een
gebruiker al dan niet heeft ingesteld, en die ook persistent bewaard worden in de UserXML (zie ook 3.2.1 en 3.4.4).
Speciek naar de DHT toe zal de SuperNode ook moeten coördineren voor welke gebruikers hij verantwoordelijk is, aangezien dit een dynamisch gegeven is in een veranderend p2p netwerk. Ook zal de SuperNode bij het opstarten van het p2p netwerk alle data (UserXMLs) moeten inladen in de eerste DHT node (deze node wordt ook wel de bootstrap node genoemd). Wanneer een nieuwe node het netwerk vervoegt, zal zijn SuperNode ook de data verkregen uit de DHT moeten inladen in de registrar en presenceserver. Op regelmatige tijdstippen zal de SuperNode ook moeten controleren of de set van gebruikers die hij beheert, niet veranderd is. Indien dit zo is, zal de SuperNode die gebruikers (en eventueel hun subscribers) indien nodig moeten redirecten naar hun nieuw verantwoordelijk SuperNode (zie ook 4.2.4 en 4.3.4).
Hoofdstuk 3. High-Level Architectuur van het systeem
47
Tot slot wensen we erop te wijzen dat de registrar van een SuperNode en die SuperNode zelf complementaire functies hebben. De registrar staat in voor de bereikbaarheid van een gebruiker, d.i.
als een gebruiker voor anderen bereikbaar wil zijn of zelf anderen wil bereiken, zal deze
geregistreerd moeten zijn bij de registrar van zijn verantwoordelijke SuperNode en dus minstens één binding tussen zijn SIP-URI en zijn contactURI gemaakt moeten hebben. Deze registratie denieert dus eigenlijk de duur van SIP-sessie waarin de gebruiker van het systeem gebruik maakt. De SuperNode zelf denieert het bestaan van een gebruiker, d.i. als een gebruiker in het netwerk bestaat (maar daarom niet noodzakelijk bereikbaar is), dan zal zijn verantwoordelijke SuperNode altijd zijn corresponderende UserXML bevatten, die de persistente data van de gebruiker bijhoudt. Deze data is cruciaal voor het ondersteunen van de extra functies die het systeem aan de gebruikers aanbiedt. Een gebruiker kan enkel van het volledige systeem gebruikmaken indien zijn SuperNode ook eectief zijn UserXML bevat. Het is echter ook mogelijk om met gebruikers te registreren die strikt genomen niet bestaan voor het SuperNode-netwerk, en waarvoor dus geen UserXML bestaat. Deze user agents kunnen wel enkel lokaal (door andere gebruikers op hun SuperNode) bereikt worden, en zullen ook geen voorkeuren noch contactlijsten kunnen bijhouden. Zo wordt ook enige vorm van compatibiliteit voorzien voor vb. interne netwerken voor een gebouw waarin verschillende bureaus elkaar steeds moeten kunnen bereiken op vaste nummers, maar buitenstaanders enkel de centrale receptie kunnen bereiken. De centrale receptie zou dan de SuperNode draaien die het hele gebouw bedient, en bureaus registreren zich dan bij deze SuperNode. Om dergelijke user agents te ondersteunen moet echter wel een aangepaste clientapplicatie ontwikkeld worden, als alternatieve Node-implementatie.
Hoofdstuk 3. High-Level Architectuur van het systeem
48
3.4 Extensible Markup Language (XML) formaten Aangezien er verschillende XML-formaten gebruikt worden in de gehele applicatie, zullen deze nu van naderbij bekeken worden.
3.4.1 De UserXML De UserXML is één van de hoekstenen van het gehele systeem. Het stelt een gebruiker en zijn preferences en contactpersonen persistent voor. Zonder een UserXML zouden gebruikers elke keer ze registreren met een lege Buddy List starten, en zouden al hun preferences verloren gegaan zijn.
Een UserXML is opgebouwd uit 2 delen, die beiden vervat zitten in een user element, dat de nodige informatie over de gebruiker zelf bevat (zoals de gebruikersnaam, het domein waartoe de gebruiker behoort en eventueel een e-mailadres). Er is een deel voorzien om alle contactpersonen van een gebruiker in op te slaan, het zgn. Buddies gedeelte. Elke contactpersoon bevindt zich in dit gedeelte als een kind van het buddies element. Elke entry voor een contactpersoon bevat de gebruikersnaam, het domain, de groep waartoe de contactpersoon behoort, en eventueel het e-mailadres van de contactpersoon. Per contactpersoon kunnen er nog verschillende preferences gedenieerd zijn, dit zijn de zgn. pref elementen. Een tweede gedeelte is het deel voor de groepen.
In dit gedeelte is er steeds een element te
vinden voor de Unknown groep. Zoals eerder al gezegd is dit de groep waartoe alle gebruikers impliciet behoren die niet in een andere groep zitten. Per groep kunnen er opnieuw verschillende preferences gedenieerd zijn, de zgn. pref elementen.
Op guur 3.11 is de UserXML van
[email protected] te zien. Alice heeft twee contactpersonen in haar Buddy List, nl.
[email protected] en
[email protected], en drie groepen, nl. Work, Friends, en Unknown. Voor Bob heeft Alice een regel voorzien, alsook voor de groepen Friends en Unknown.
Hoofdstuk 3. High-Level Architectuur van het systeem
49
<user name="alice" domain="thesis.test" email="
[email protected]">
<pref rule="Deny" start="1430" end="1445" /> <pref rule="Allow" start="1530" end="1730" /> <pref rule="Deny" start="0000" end="2359" />
Figuur 3.11: De UserXML van Alice.
Een gebruiker zal veranderingen doen aan de inhoud van zijn UserXML d.m.v. ofwel een SUBSCRIBE SIP-bericht met als inhoud een BuddyXML (om contactpersonen toe te voegen of te verwijderen), ofwel d.m.v. een PUBLISH SIP-bericht met als inhoud een PreferencesXML (om preferences toe te voegen of te verwijderen voor een contactpersoon of voor een groep). Beide XML-formaten komen hieronder nog aan bod.
3.4.2 Het Presence Information Data Format (PIDF) Het PIDF is een standaard XML-gebaseerd formaat om presence informatie in voor te stellen. PIDF wordt beschreven in RFC 3863 (zie [9]). Het standaard PIDF formaat was in dit geval te beperkt om alle presence informatie in voor te stellen, dus werd het uitgebreid.
Een standaard PIDF document laat toe om ofwel een status Open, ofwel een status Closed mee te geven als presence informatie (via de basic tag). In een systeem waarin men gebruikers de mogelijkheid wil geven om ook andere statussen te publiceren (zoals vb. Away en Busy) zijn deze twee mogelijkheden ontoereikend.
Hoofdstuk 3. High-Level Architectuur van het systeem
50
De RFC voor PIDF laat echter wel toe om uitbreidingen te deniëren. Er werd voor geopteerd om van deze mogelijkheid gebruik te maken, nl. door een extra element contact_status toe te voegen aan het status element in de XML-boom. Dit extra element bevat dan de meer gedetailleerde status van de gebruiker. Elke contact_status verschillend van Oine zal in het basic element een status open tot gevolg hebben. Op die manier wordt er toch nog een compabiliteit voorzien met systemen die enkel met de standaard PIDF werken.
Figuur 3.12 toont een voorbeeld PIDF document voor de gebruiker Alice. In dit geval is Alice maar op één plaats aanwezig, en ten gevolge daarvan zal er maar één tuple element in de PIDF aanwezig zijn. Mocht Alice vb. tegelijkertijd ook haar presence informatie via een PDA willen publiceren, dan zou dit tot gevolg hebben dat er nog een extra tuple element zou toegevoegd worden aan het PIDF document.
Als alternatief kan ook het RPID ([10]) gebruikt worden. RPID voegt elementen toe aan het PIDF die extra informatie voorzien over de presentity en zijn contactpersonen.
<presence xmlns="urn:ietf:params:xml:ns:pidf" entity="sip:
[email protected] ">
<status> open away 2006-05- 23T21:19:46Z
Figuur 3.12: Een PIDF document van Alice met als status Away.
3.4.3 De BuddyXML De BuddyXML is een klein XML document dat zal toegevoegd worden aan de inhoud van een SUBSCRIBE SIP-bericht, indien men een nieuwe contactpersoon wenst toe te voegen aan zijn Buddy List, of indien men een bestaande contactpersoon wil verwijderen uit zijn Buddy List.
Hoofdstuk 3. High-Level Architectuur van het systeem
51
Figuur 3.13: Een voorbeeld BuddyXML om een contactpersoon toe te voegen aan de Buddy List.
Op guur 3.13 is een voorbeeld BuddyXML te zien om een contactpersoon toe te voegen aan de Buddy List. Er wordt gespecieerd dat het om een toevoegactie gaat d.m.v. het attribuut action=addBuddy, verder worden ook de gebruikersnaam, het domein, eventueel het e-mailadres, en de groep van de nieuwe contactpersoon opgegeven.
Figuur 3.14: Een BuddyXML om een contactpersoon te verwijderen.
Op guur 3.14 is een analoog bericht te zien om een contactpersoon te verwijderen uit een Buddy List. Het enige verschil met voorgaande XML is dat het nu een verwijderactie betreft, te zien aan het attribuut action=deleteBuddy.
3.4.4 De PreferencesXML De PreferencesXML wordt gebruikt bij drie operaties :
•
Bij het toevoegen of verwijderen van groepen.
•
Bij het toevoegen of verwijderen van preferences voor groepen.
•
Bij het toevoegen of verwijderen van preferences voor contactpersonen.
Hoofdstuk 3. High-Level Architectuur van het systeem
52
De PreferencesXML kan dus gebruikt worden om een operatie op groepen aan te geven. Het idee is dat men een volledig nieuw groups element voor de bestaande UserXML zal construeren, en dit zal versturen a.d.h.v. een PUBLISH SIP-bericht. Het oude groups element uit de UserXML zal dan vervangen worden door het ontvangen nieuwe groups element. Op deze manier is er op een eenvoudige manier voor gezorgd dat er geen ingewikkelde vergelijkingen moeten gebeuren tussen het huidige groups element uit de UserXML en het nieuwe groups element indien men vb. een groep zou verwijderen. Aangezien een gebruiker typisch slechts een beperkt aantal groepen zal voorzien, zou de overhead hier zeker binnen de perken moeten blijven. Op guur 3.15 is een typische PreferencesXML te zien die het groepsaspect behandelt.
< pref rule="Deny" start="1400" end="1700" /> < pref rule="Deny" start="1200" end="2359" />
Figuur 3.15: Een PreferencesXML om groep regels toe te voegen en/of te verwijderen.
Voor het publiceren van preferences voor een contactpersoon is een gelijkaardige aanpak gekozen. Er werd nu echter niet geopteerd om het volledige buddies element te versturen (aangezien een gebruiker met vb. een 100-tal contactpersonen niet zo uitzonderlijk is, zou dit veel overhead met zich meebrengen). Nu wordt enkel het element uit de XML-boom dat op de contactpersoon zelf slaat, in de PreferencesXML opgeslagen. Het volstaat dus om in de persistente UserXML op de SuperNode het huidige element voor de contactpersoon te vervangen door het ontvangen buddy element. Op guur 3.16 is zo'n PreferencesXML te zien.
Hoofdstuk 3. High-Level Architectuur van het systeem
53
<pref rule="Allow" start="0800" end="1500" />
Figuur 3.16: Een PreferencesXML om preferences bij een contactpersoon toe te voegen en/of te ver-
wijderen.
Hoofdstuk 4
Software Architectuur De voorgestelde architectuur uit hoofdstuk 3 werd zoveel mogelijk geïmplementeerd aan de hand van open-source componenten. Hiertoe werden voor sommige componenten verschillende implementaties uitgeprobeerd, en werden de meest bruikbare gehouden. In de volgende secties zal de implementatie verder uitgelegd worden. Hierbij zal uiteraard niet elk implementatiedetail aan bod komen, maar zal eerder vanuit functioneel oogpunt de hoofdfunctionaliteit van elk van de componenten beschreven worden. Eerst zal echter een overzicht gegeven worden van de gebruikte softwarebibliotheken die in het systeem gebruikt worden. De gebruikte programmeertaal voor de implementatie is Java, aangezien er reeds een aantal zeer bruikbare Java implementaties bestonden die een deel van de beoogde functionaliteit boden, of hiertoe alleszins goede ondersteuning boden.
4.1 Overzicht van gebruikte softwarebibliotheken 4.1.1 SIP en SDP Voor SIP en SDP werd de Java APIs for Integrated Networks (JAIN) specicatie gebruikt, meerbepaald versie 1.1. Deze API deniëert een architectuur die SIP communicatie ondersteunt door middel van het Java event-listener paradigma: SIP-berichten die in een component toekomen, worden in een event gewikkeld en naar de applicatie toe gepropageerd. De applicatie moet dan de SipListener interface implementeren om deze events op te vangen. Elke component die SIP-berichten wil versturen of ontvangen, moet hiervoor een SipStack draaien. Op deze SipStack worden dan één of meerdere SipProviders gehecht, die elk abstrac-
54
Hoofdstuk 4. Software Architectuur
55
tie maken van 1 poort-protocol combinatie (in de implementatie ListeningPoints genoemd) en methoden voorzien om berichten te versturen (zowel statefull als stateless). Om berichten op te vangen moet de applicatie dus bij deze SipProvider(s) een implementatie van SipListener registreren. De open-source referentie-implementatie van deze specicatie, ontwikkeld door het National Institute for Standards and Technology (NIST), werd in dit systeem gebruikt. Deze implementatie voorziet voor zowel SIP als SDP een groot aantal klassen die het werken met beide protocols fel vergemakkelijken. Voor beide protocollen werd de 1.2 versie gebruikt, die de meest recente is op het moment van schrijven. Zie hieromtrent ook [13]. Korte tijd geleden is de nieuwe versie van de JAIN-SIP API uitgekomen, nl. versie 1.2. Aangezien op dat moment de implementatie al vergevorderd was, en er enkele problemen zijn met betrekking tot achterwaartse compatibiliteit, werd ervoor gekozen om toch bij versie 1.1 te blijven, ook al omdat de nieuwste release nog niet stabiel is.
4.1.2 Mediastreaming Aangezien RTP gebruikt wordt om de VoIP call te voeren, zal hiervoor ook Java ondersteuning nodig zijn.
Hiervoor bestaat sinds enige tijd het Java Media Framework (JMF, zie [14]), dat
onder meer het afspelen en opnemen van streaming media via Java aanbiedt. Deze API maakt het vrij gemakkelijk RTP streams op te zetten en af te spelen.
4.1.3 DHT Er zijn vrij veel open-source implementaties die een p2p netwerk tot stand kunnen brengen en onderhouden.
Aangezien een p2p netwerk op zichzelf echter geen DHT implementeert, werd
speciek gezocht naar software die dit wel deed.
Enkele onderzochte bibliotheken zijn JDHT
([15]), BambooDHT ([16]), PAST (de DHT van (Free)Pastry, zie [17]) en Bunshin DHT ([18]). Er werd uiteindelijk gekozen voor Bunshin DHT, omdat de andere opties niet voldeden aan de eisen van dit systeem. Zo was er niet voldoende ondersteuning voor replica's of het beheer van sleutels bij veranderingen in het onderliggende netwerk (JDHT, PAST), of waren ze niet (meer) volledig op Java gebaseerd (Bamboo).
Hoofdstuk 4. Software Architectuur
56
Bunshin DHT (ook FreePastry-gebaseerd) daarentegen werd juist ontwikkeld om betere performantie te bekomen dan PAST bij veranderingen aan het onderliggende p2p netwerk, gebruikmakend van een actief replicatieschema. Deze DHT implementatie voldeed quasi volledig aan de eisen die het hier voorgestelde systeem stelde. De versie van Bunshin DHT die we hier gebruiken, is versie 2.1.2.
4.1.4 JDOM Voor het gemakkelijk manipuleren van XML bestanden werd gekozen voor het gebruik van JDOM, een bibliotheek die ondersteuning biedt voor het eciënt inlezen, aanpassen en uitschrijven van XML bestanden vanuit Java. Zie hieromtrent ook [19].
4.1.5 Remote Method Invocation (RMI) Dit is geen alleenstaande bibliotheek, maar een manier om methoden op objecten op afstand aan te roepen die standaard in Java ingebakken zit.
Andere technologieën die hetzelfde bereiken,
maar hier minder geschikt geacht werden, zijn bijvoorbeeld Common Request Broker Architecture (CORBA) en Simple Object Access Protocol (SOAP). De Java RMI werkt ruwweg als volgt: voor elk op afstand aanroepbaar object wordt een interface gedeniëerd die het gewenste gedrag van het object abstraheert. Deze interface moet de klasse java.rmi.Remote uitbreiden, enkel de methoden die in deze interface aanwezig zijn zullen vanop afstand aanroepbaar zijn op het object in kwestie. De klasse die het object voorstelt moet dan deze interface die van Remote overerft implementeren. Een bijkomende verplichting is dat die klasse ook de klasse UnicastRemoteObject uitbreidt, dit is een standaard klasse die een aantal zaken afhandelt waar de programmeur zich dan niet meer hoeft bezig te houden zoals (un)marshallen van argumenten, resultaten en dergelijke. Er bestaan ook andere mogelijkheden dan het uitbreiden van UnicastRemoteObject, maar aangezien niet geopteerd werd deze te gebruiken, verwijzen we de geïnteresseerde lezer graag naar [20] en [21].
Hoofdstuk 4. Software Architectuur
57
4.2 Beschrijving van de geïmplementeerde klassen In deze sectie zullen de voornaamste eectief geïmplementeerde klassen en interfaces per package wat verder uitgelegd worden.
4.2.1 Node package Het Node package implementeert de client kant van het systeem, zoals uitgelegd in hoofdstuk 3. Dit package is verder onderverdeeld in drie andere packages, die elk een deel van de functionaliteit implementeren. Deze drie packages zijn node.sip, verantwoordelijk voor alle SIP communicatie langs clientzijde, node.media dat de mediacommunicatie d.m.v. RTP afhandelt en node.gui, dat de grasche user interface voor de gebruiker implementeert. In elk package komt een interface voor, die telkens als portaal naar een van de drie componenten fungeert. Elk package zal nu verder uitgelegd worden. Nadat elk package afzonderlijk aan bod gekomen is, zullen er nog enkele klassen uit het node package zelf besproken worden.
Het is
echter niet de bedoeling van hier elke klasse die gebruikt werd tot in detail te beschrijven, het is eerder de bedoeling de lezer een blik te gunnen op hoe de onderlinge delen samenwerken.
Figuur 4.1 toont hoe de belangrijkste interfaces en klassen van de Node samenhangen.
Hoofdstuk 4. Software Architectuur
58
<<SuperNodeManager >> startSuperNode(): void stopSuperNode( ): void
<
> diverse getters en setters die van belang zijn voor de interactie van de GUImet de rest van de Node
<> createNewClient ( ): void setNewProxyParams (List proxyLps) : void setUsername(String username) : void stopClient(): void
Client 1
<> redirect(ProxyLPAnswernewProxy): boolean
<<SipClient>>
<<java.rmi.Remote >>
register (userName, domain): void unregister (userName, domain):void invite (calleeName, domain):void subscribe (userName, domain, group,email, refresh):void publish(newStatus, preferencesXML):void bye (userName, domain):void cancel(userName, domain):void fetch(userName, domain):void
UnicastRemoteObject SipManager
<>
<<SipListener >>
startVoIPSession ( InetSocketAddress): void stopVoIPSession ( ): void
RTPPlayer
RTPProcessor
Figuur 4.1: UML-schema voor de belangrijkste interfaces en klassen van de Node.
SIP package Zoals gezegd zal het SIP package instaan voor alle SIP communicatie langs clientzijde. SipManager is de klasse die hiervoor zal gebruikt worden.
De
De SipManager implementeert de
Hoofdstuk 4. Software Architectuur
59
SipClient (die op zijn beurt de SipListener interface uitbreidt). De Siplistener interface voorziet methoden om om te gaan met binnenkomende events die door de SipStack gegenereerd worden wanneer een SIP-bericht arriveert.
De SipClient interface daarentegen biedt de methoden die
nodig zijn om met de andere gebruikers in contact te kunnen treden (vb.
om te registreren,
publiceren, ...), m.a.w. om zelf te berichten te versturen.
Er zijn in het SIP package ook verschillende TimerTasks voorzien, dit om het verversen van een registratie of van een inschrijving te vergemakkelijken en te automatiseren. Een TimerTask is een taak die kan gepland worden d.m.v.
een Timer object.
Als de Timer aoopt zal de run
methode van de TimerTask uitgevoerd worden. Het is met TimerTasks op een vrij eenvoudige manier mogelijk om bepaalde gebeurtenissen periodiek of een enkele keer te laten gebeuren.
Verder is er nog een klein subpackage pidf voorzien, dat alles omtrent het aanmaken en het aanpassen van PIDF documenten regelt. Dit package zal ook worden gebruikt in diverse stukken van de SuperNode.
De SipManager maakt ook gebruik van de VoIPManager nadat een mediasessie is opgezet door middel van een INVITE bericht. Deze interface zit in het media package, welke in de volgende paragraaf aan bod komt.
Media package Het media package bevat alle klassen om een RTP sessie op te zetten en af te sluiten. Centraal is de interface VoIPManager dewelke methoden voorziet om een RTP sessie te starten en te stoppen. Er zijn twee klassen die de VoIPManager implementeren, nl. RTPPlayer en RTPProcessor. RTPPlayer is de klasse die de binnenkomende RTP-pakketten zal decoderen en afspelen. RTPProcessor is de klasse die het geluid zal opnemen, het coderen en dan de zo bekomen RTPpakketten zal versturen.
RTPPlayer gebruikt (net als RTPProcessor) een klasse die beschikbaar gesteld werd op de site van Sun, om het RTP gedeelte op te lossen. Deze klassen zijn AVReceive2 voor de RTPPlayer en AVTransmit2 voor de RTPProcessor. Meer informatie is te vinden op [22] en [23].
Hoofdstuk 4. Software Architectuur
60
GUI package Het GUI package voorziet alle klassen die samen de GUI tot stand brengen. Om communicatie naar de andere delen van de Node toe te laten is er de GuiModel interface voorzien. Deze interface voorziet enkele getters en setters die nodig zijn opdat de GUI een visuele voorstelling zou kunnen geven van het geheel.
Intern in het GUI package wordt de klasse Model gebruikt als
implementerende klasse voor deze interface.
Er is ook een klasse PreferencesXMLParser voorzien die PreferencesXML documenten zal aanmaken aan de hand van de genomen keuzes in het BuddyRulesFrame of in het GroupRulesFrame. Deze laatste twee klassen stellen elk een venster voor dat tevoorschijn komt als de gebruiker ofwel de preferences van een groep of van een contactpersoon wil wijzigen.
Verdere klassen in het Node package In het node package zelf zijn er ook nog enkele klassen die het verdienen om even onder de loep genomen te worden. Allereerst zijn er de drie interfaces: Node, NodeCallBack en SuperNodeManager. De Node interface is de interface die de eigenlijke Node abstraheert. De NodeCallBack interface breidt het Remote object uit, en laat een SuperNode toe een RMI-call te doen als de client op deze Node moet geredirect worden doordat zijn verantwoordelijke SuperNode veranderd is. De SuperNodeManager tenslotte, voorziet methoden om een SuperNode op te starten en af te sluiten. Dit zal ook via RMI gebeuren, maar dan lokaal. De klasse Client implementeert deze drie interfaces en breidt het UnicastRemoteObject uit. Dit is de standaard Java manier om een op afstand aanroepbaar RMI-object te implementeren. De Client klasse is ook de klasse die zal gebruikt worden om het geheel op te starten, ze maakt ook een nieuwe GUI aan, en een nieuwe SIPClient. Telkens een client geredirect wordt zal zijn proxy veranderen, en daardoor zal ook steeds een nieuwe SipClient moeten aangemaakt worden. Om met RMI te kunnen werken is het echter nodig dat er een rmiregistry process aanwezig is. Dit rmiregistry process zal gestart worden als het programma opgestart wordt, en zal gestopt worden als het programma afsluit.
Hoofdstuk 4. Software Architectuur
61
4.2.2 SuperNode package Het SuperNode package implementeert de server kant van het systeem, zoals uitgelegd in hoofdstuk 3. Dit package is verder onderverdeeld in twee andere packages supernode.proxy en supernode.dht, die respectievelijk de proxy en de DHT implementeren. Deze packages zullen eerst afzonderlijk besproken worden, en daarna zullen de overblijvende klassen uit het SuperNode package aan bod komen.
Figuur 4.2 toont hoe de belangrijkste interfaces en klassen van de SuperNode samenhangen. Om de guur niet te overladen werd de verdere onderverdeling van de proxy component weggelaten.
Hoofdstuk 4. Software Architectuur
62
<<SuperNode >> getProxy ( ) : SipProxy getDHT() : DHT initialize(userXmlSet) : void getBootstrapUsers() : Set getUserXML( user, domain):String setUserXML(user, domain,newUserXml) : boolean getBuddyList(user, domain) : List<Buddy> addBuddy(user,udomain, buddy,bdomain) :void deleteBuddy (user,udomain, buddy,bdomain) :void isBuddy(user,udomain, buddy,bdomain) : boolean authorize(user, udomain, caller, cdomain) : boolean managesUser(user, domain) : boolean addUser(userXml) : void deleteUsers(userXmls) : void
<<SuperNodeRMIController >>
<<java.rmi.Remote >>
startSuperNode() : void stopSuperNode() : void
BunshinDHT
UnicastRemoteObject SuperNodeImpl <>
1
<<SuperNodeRMIAccess>>
start(): void stop(): void lookupProxyLP (key):ProxyLPAnswer store (user, domain, userXml): void getOwnedUsers(): Set<String>
1
lookupProxy (user): ProxyLPAnswer
1 <<SipProxy>> getSuperNode() : SuperNode setInitialRegistrations (users) : void removeRegistrations(users): void getContactUriList(user): Vector getListeningPoints(): Iterator getIPAddress() : String start() : void stop() : void
Proxy
<<SipListener >>
Figuur 4.2: UML-schema voor de belangrijkste interfaces en klassen van de SuperNode.
Hoofdstuk 4. Software Architectuur
63
Proxy package Dit package implementeert de proxyfunctionaliteit van het systeem.
Hierin zijn zoals eerder
gezegd twee aparte componenten te onderscheiden, nl. de Registrar en de PresenceServer. Voor deze twee componenten zijn nog eens twee subpackages aangemaakt die de nodige klassen voor die componenten bevatten.
Dit zijn respectievelijk de packages supernode.proxy.registrar en
supernode.proxy.presenceserver. We zullen eerst deze packages bespreken vooraleer de overblijvende klassen in het proxy package uit de doeken te doen. De code uit dit package steunt sterk op de open-source code van NIST voor hun jain-sip-presenceproxy server. Zie in dit verband [13]. Vanzelfsprekend wordt in deze implementatie overal gebruikgemaakt van de NIST SIP en SDP implementaties van de JAIN SIP API.
Registrar package
Zoals vermeld in hoofdstuk 3 is deze component verantwoordelijk voor het
bewaren van bindingen van de SIP-URIs van gebruikers op hun contact-URIs. De hoofdklasse in dit package is de klasse Registrar, die methoden voorziet voor het opvangen van REGISTER berichten, die door de proxy naar deze klasse worden doorgestuurd. Afhankelijk van de inhoud van deze berichten zal dit leiden tot het aanmaken, aanpassen of verwijderen van een registratie. Een registratie wordt voorgesteld door de klasse Registration. De Registrar klasse bevat ook methoden die door andere klassen gebruikt kunnen worden om op te vragen of de Registrar een registratie heeft voor een bepaalde gebruiker (via zijn SIP-URI, of zelfs rechtreeks via een Request gestuurd door die gebruiker), en van geregistreerde gebruikers de (meest recente) contactURI op te vragen. Voornamelijk de proxy zal hiervan veelvuldig gebruik maken.
Er is in de Registrar ook een methode voorzien om initiële registraties in te stellen (de zgn. dummy registraties, zie ook 3.3.2).
Om ervoor te zorgen dat voor een gebruiker die niet
geregistreerd is (en dus niet online is voor het systeem) onnodige opzoekoperaties gebeuren op de DHT omdat de verantwoordelijke SuperNode geen registratie bevat voor de gebruiker in kwestie (zie 4.2.3), zal een speciale voorziening getroen worden. Voor elke gebruiker waarvoor een SuperNode verantwoordelijk is op een gegeven ogenblik, zal voor die gebruiker een dummy registratie aangemaakt worden in de registrar van die SuperNode. Een dummy registratie bestaat uit een lege binding, d.i. een mapping van de SIP-URI op een
Hoofdstuk 4. Software Architectuur
64
lege contact-URI. Wanneer de gebruiker zich dan registreert, zal de binding ingevuld worden. Op deze manier wordt gegarandeerd dat de verantwoordelijke proxy voor een gebruiker steeds kan bepaald worden, onafhankelijk van het feit of deze gebruiker al dan niet geregistreerd is. Door een gelijkaardig systeem toe te passen op de presenceserver (zie volgende paragraaf ) zullen gebruikers ook in staat zijn zich in te schrijven voor het ontvangen van de presence informatie van een gebruiker die op dat moment niet geregistreerd is. Er is ook een klasse ExpiresTask aanwezig die ervoor zal zorgen dat verlopen registraties uit de Registrar verwijderd worden.
Presenceserver package
De presenceserver behandelt alle presencegerelateerde berichten (de
proxy leidt deze af naar de presenceserver), REGISTER berichten voor het aanpassen van notiers, evenals de berichten die de UserXML kunnen aanpassen. Dit laatste was een logische keuze aangezien deze berichten SUBSCRIBE en PUBLISH zijn met een extra XML inhoud, en deze berichten sowieso door deze component worden opgevangen.
De hoofdklasse in dit package is PresenceServer. Deze klasse voorziet methoden om REGISTER, SUBSCRIBE en PUBLISH berichten op te vangen, en NOTIFY berichten te sturen. Deze klasse voorziet ook een methode om initiële notiers in te stellen, zodat gebruikers zich eventueel al kunnen inschrijven voor het ontvangen van hun presence vooraleer de notiers zich geregistreerd hebben.
Het eigenlijke beheer van notiers en subscribers gebeurt echter in de klasse PresentityManager. Hiertoe zijn ook de klassen Notier en Subscriber voorzien.
Als een Notier nu zijn presence
aanpast, dan zal de PresentityManager bij elk van zijn Subscribers met een lopende inschrijving een vlag instellen die aangeeft dat deze Subscriber een NOTIFY bericht moet krijgen. De PresentityManager loopt in een aparte thread en zal in een lus over alle Subscribers itereren, en diegenen een NOTIFY sturen waar hun vlag aanstaat. De uitzondering hierop zijn fetchers (en unsubscribes). Aangezien zij slechts één NOTIFY moeten ontvangen zullen deze Subscribers in een wachtlijn worden bijgehouden, en nadat ze op de hoogte gebracht zijn van de presence van de notier, zullen zij verwijderd worden. We wensen hier ook op te merken dat het al dan niet geautoriseerd zijn van een Subscriber
Hoofdstuk 4. Software Architectuur
65
voor het ontvangen van presence van een bepaalde notier ook steeds afhankelijk is van diens Preferences, zoals eerder vermeld. De PresentityManager en PresenceServer zullen dit dan ook nagaan vooraleer een NOTIFY te sturen. Of een Subscriber al dan niet toelating heeft om deze presence te ontvangen, zal ook met een vlag worden bijgehouden in het Subscriber object. Deze vlag wordt eerst gezet bij de constructie van de Subscriber, en telkens de notier een PUBLISH stuurt of de subscriber zijn inschrijving ververst, wordt deze vlag geherevalueerd.
Elk Notier-object houdt ook steeds intern zijn meest recente PIDF document bij, terwijl een Subscriber-object steeds de status van zijn inschrijving bijhoudt, evenals het laatste SUBSCRIBE request dat de subscriber verstuurd heeft. Dit laatste is nodig om de NOTIFY steeds naar het juiste adres te sturen. Uiteraard zal de PresentityManager ook verlopen inschrijvingen verwijderen, hiervoor is in tegenstelling tot het registrar package geen speciale klasse voorzien aangezien de PresentityManager toch al regelmatig alle Subscribers overloopt en op dat moment kan controleren of de inschrijving verlopen is.
Voor het verwerken van de UserXML-gerelateerde berichten wordt gebruikgemaakt van methoden uit de omvattende SuperNode en diens UserXMLManager, waarover later meer.
Hoofdstuk 4. Software Architectuur
Verdere klassen en interfaces in het Proxy package
66
De samenwerking van de proxy met
de andere componenten van het systeem wordt door de interface SipProxy gedenieerd, die op zijn beurt de SipListener interface uitbreidt. Zoals reeds vermeld biedt de SipListener interface mogelijkheid tot het opvangen van SIP berichten, evenals het omgaan met timeouts en dergelijke. De belangrijkste extra methoden die SipProxy hieraan toevoegt zijn methoden om de SuperNode van deze proxy op te vragen, initiële registraties in te stellen, registraties te verwijderen, de contactURIs van gebruikers op te vragen, het adres (IP+poort+protocol) van de proxy op te vragen, en uiteraard methoden om de proxy te starten en te stoppen. Deze SipProxy interface vormt de deur tussen de proxy-component en de SuperNode.
De implementerende klasse van deze interface is de Proxy klasse. Deze klasse is dus degene die alle inkomende berichten zal opvangen en ze zal verwerken of naar andere klassen delegeren, al naargelang het soort bericht en de inhoud ervan. De parameters voor de proxy, zoals de poortnummers en protocols waarop geluisterd wordt, kunnen ingesteld worden aan de hand van een XML-conguratiebestand.
Verder zijn er in het proxy package nog enkele grote hulpklassen aanwezig die elk een deel van de taken van de proxy op zich nemen. Zo is er de RequestValidation klasse die inkomende requests valideert (en eventueel een gepaste response terugstuurt indien het request niet in orde was), zoals aangegeven in 3.3.1.
Ook zijn er de Request- en ResponseForwarding klassen die
zoals hun naam aangeeft requests en responses doorsturen naar hun bestemming (eventueel na behandeling door de proxy en afhankelijk van het bericht, zie ook 3.3.1).
Dit doorsturen kan
statefull of stateless gebeuren, wederom afhankelijk van het bericht en de door de betrokken partijen gebruikte transportprotocollen.
Figuur 4.3 toont nog eens de belangrijkste klassen die de proxy intern gebruikt.
Hoofdstuk 4. Software Architectuur
67
ResponseForwarding
RequestForwarding Proxy
RequestValidation
PresenceServer Registrar PresentityManager Registration
Notifier
Subscriber
Figuur 4.3: UML-schema van de belangrijkste klassen gebruikt in de proxy.
4.2.3 DHT package Het DHT package bevat de klassen die de DHT-component implementeren, gebruikmakend van de Bunshin bibliotheek. Hieruit werden enkele klassen aangepast om de gewenste functionaliteit te verkrijgen. Deze aanpassingen zullen verder uitgebreider aan bod komen.
De DHT interface denieert de benodigde functionaliteit van deze component. Hiertoe werden methoden voorzien voor het opvragen voor welke gebruikers deze DHT-component (en dus de omvattende SuperNode) verantwoordelijk is, om het adres van de proxy op te zoeken die verantwoordelijk is voor een bepaalde gebruiker, om een UserXML op te slaan in de DHT en uiteraard ook om de component te starten of te stoppen. Deze interface wordt geïmplementeerd door de klasse BunshinDHT. Deze klasse maakt gebruik van de Bunshin implementatie om zowel de routeringslaag als de opslaglaag te beheren en consistent te houden.
Hoofdstuk 4. Software Architectuur
68
De operatie om het adres van de proxy verantwoordelijk voor een bepaalde gebruiker op te zoeken, is speciek voor dit systeem.
Om die te ondersteunen, zijn de klassen GetProxyLP-
Client, GetProxyLPMessage en ProxyLPAnswer voorzien, die volgens dezelfde manier als voor andere BunshinDHT berichten ondersteuning bieden voor een bericht dat de benodigde informatie opvraagt. Om dit nieuwe bericht te kunnen versturen, ontvangen en het juiste resultaat terug te geven werden de klassen BunshinConnection en BunshinImpl ook (lichtjes) aangepast. Deze klassen zullen een oproep om het proxy adres te weten te komen door het p2p-netwerk routeren naar de verantwoordelijke dht-node (en dus SuperNode en SIP-proxy) voor de opgegeven gebruiker. Dezelfde klassen zullen op de bestemming interageren met de SuperNode d.m.v. de getProxy methode om zo het adres te weten te komen, en dit terugsturen.
De operatie om de eigen gebruikers op te vragen wordt door de klasse BunshinDHT zelf geïmplementeerd, evenals de operatie om een UserXML op te slaan. Ook zijn enkele keuzes gemaakt qua opslag: Bunshin heeft standaard ondersteuning voor opslag in het geheugen of op schijf (via de StorageManager klasse). Hier is er voor gekozen om primaire kopieën op schijf te bewaren en replica's in het geheugen op te slaan. Andere conguratieparameters zoals poortnummer voor de DHT, replicatiefactor, bootstrapadres en refreshtime kan men instellen door middel van een conguratiebestand.
De refresh time geeft aan om de hoeveel tijd de DHT zal nagaan of het
netwerk nog dezelfde status heeft als tevoren en of de verantwoordelijkheid voor sleutels (en dus ook waarden) of replica's niet veranderd is, en gepast zal reageren op deze mogelijke veranderingen.
4.2.4 Verdere klassen en interfaces in het SuperNode package Het SuperNode package zelf tenslotte bevat de klassen en interfaces die nodig zijn om de communicatie tussen de DHT en SIP-proxy componenten in goede banen te leiden, alsook klassen voor het beheren van de UserXMLs. Ook zijn er enkele RMI interfaces voorzien die de toegang tot de SuperNode van buitenuit modelleren. Al deze klassen en interfaces zullen in de volgende paragrafen belicht worden.
Hoofdstuk 4. Software Architectuur
69
De interface die abstractie maakt van de SuperNode component zelf is de gelijknamige interface.
Deze interface voorziet methoden om de DHT- en SIP-proxy component op te vragen
(noodzakelijk voor de interactie van beide componenten met elkaar), methoden om UserXMLs te manipuleren en te beheren, na te gaan of een gebruiker toelating heeft een gebruiker beheerd door deze SuperNode te contacteren of zijn presence op te vragen, en na te gaan of een bepaalde gebruiker beheerd wordt door deze SuperNode. Verder bevat deze interface ook methoden om gebruikers via hun UserXML in te laden in de SuperNode (hetzij initieel als deze SuperNode ook de bootstrap DHT-node omvat, hetzij dynamisch wanneer door veranderingen in het p2p netwerk gebruikers verhuizen naar een andere SuperNode). Ook methoden om gebruikers te verwijderen horen hierbij.
Deze interface wordt geïmplementeerd door de klasse SuperNodeImpl. Deze klasse brengt dus de DHT- en SIP-proxy-componenten samen, en gebruikt intern hun respectievelijke implementaties BunshinDHT en Proxy. Voor het beheren van UserXMLs wordt veelvuldig gebruik gemaakt van de klasse UserXMLManager, die conversies tussen het XML formaat en de geheugenrepresentatie ervan afhandelt, en ook methoden voorziet voor het manipuleren van deze UserXMLs. De klassen die de geheugenrepresentatie van de UserXML implementeren, zijn User, SuperNodeUser, Buddy, Group, Rule, die respectievelijk een gebruiker, een gebruiker die andere gebruikers kan autoriseren, een contactpersoon, een groep waarin contactpersonen kunnen worden ingedeeld, en een regel voorstellen. Zo'n regel is de bouwsteen van de Preferences, zoals eerder besproken.
Elke UserXML die in de DHT-component op schijf wordt opgeslagen (en dus een primaire kopie is, wat betekent dat deze SuperNode verantwoordelijk is voor die gebruiker), wordt ook in het geheugen bijgehouden door de SuperNode d.m.v.
een SuperNodeUser object.
Hiervoor werd
geopteerd om de performantie te vergroten, aangezien het systeem veelvuldig de UserXML moet bevragen en aanpassen, en dit een serieuze performantiekost met zich zou meebrengen indien elke keer het eectieve UserXML bestand van schijf zou worden ingelezen.
Zoals gezegd zijn er ook methoden voorzien om de geheugenrepresentaties van de UserXMLs (en ook hun overeenkomstige objecten in de Registrar en PresenceServer) consistent te houden met de DHT. Hiermee wordt bedoeld dat wanneer de verantwoordelijkheid over sleutels (en dus ook UserXMLs) in de DHT verandert, de overeenkomstige SuperNodes gebruikers moeten verwijde-
Hoofdstuk 4. Software Architectuur
70
ren of toevoegen. De klasse OwnedUsersTask controleert met dezelfde regelmaat als de DHT of deze verantwoordelijkheid niet veranderd is, en past het gebruikersbestand van de SuperNode overeenkomstig aan. Bij dit proces moeten geregistreerde gebruikers waarvoor deze SuperNode niet meer verantwoordelijk is, geredirect worden naar hun nieuw verantwoordelijke SuperNode.
Ook hiervoor
heeft de SuperNodeImpl klasse ondersteunende methoden, die dan via RMI de methode redirect van de NodeCallback interface zullen oproepen op de betreende Nodes, met daarin het adres van hun nieuwe proxy. Dit adres zal bekomen worden van de eigen DHT component door de lookupProxyLP operatie. Dit is echter enkel mogelijk als de verandering in verantwoordelijkheid afkomstig is van een nieuwe SuperNode die het systeem binnekomt. Indien echter de verandering afkomstig is van het stoppen van deze SuperNode zelf, zal de SuperNode noodgedwongen het adres van zijn eigen proxy als nieuwe proxy meegeven (aangezien deze SuperNode nog altijd de verantwoordelijkheid heeft over de desbetreende Nodes).
In de Node wordt telkens gekeken
of het ontvangen nieuwe adres gelijk is aan het adres van de huidige proxy.
Indien dit zo is,
zal de Node een delayed redirect doen, dit wil zeggen dat de Node een periode (gelijk aan de refresh rate van de DHT) zal wachten en dan bij de bootstrap SuperNode het adres van zijn nieuwe proxy zal opvragen, en dit via een RMI call op de SuperNodeRMIAccess interface, zoals hieronder uitgelegd. Met het nieuwe adres zal dan een nieuwe SipClient gestart worden, en zal de Node terug registreren bij de juiste proxy. Zie in dit verband ook het sequentiediagram 4.3.4 dat dit geval grasch weergeeft. Ook subscribers op gebruikers die van SuperNode verhuizen, moeten geredirect worden. Er is hier gekozen in dit geval de lopende inschrijvingen te beëindigen, en door middel van een RetryAfter header aan de betreende Nodes aan te geven dat ze over een tijd aangegeven door de waarde van deze header zich opnieuw moeten inschrijven voor de geredirecte gebruiker. Door deze tijd gelijk te kiezen aan het interval waarin de DHT de verantwoordelijkheden controleert en zonodig herverdeelt, zal de nieuw verstuurde inschrijving gegarandeerd bij de juiste (nieuw verantwoordelijke) proxy toekomen.
Verder zijn in dit package zoals gezegd ook twee RMI-interfaces te vinden, SuperNodeRMIController en SuperNodeRMIAccess. De eerste interface voorziet enkel de methoden startSuperNode en stopSuperNode die zoals de naam aangeeft de SuperNode starten en stoppen. Deze methoden zullen aangeroepen worden vanuit de Client klasse uit het Node package wanneer de gebruiker
Hoofdstuk 4. Software Architectuur
71
een SuperNode wenst te starten of te stoppen. De reden waarom dit met RMI gebeurt is omdat door een eigenaardigheid in de NIST-SIP implementatie slechts één SipStack per Java Virtual Machine (JVM) kan aangemaakt worden. Aangezien de Node-component zelf een SipStack gebruikt was het dus onmogelijk om in dezelfde JVM ook de SuperNode te draaien, en moest hiervoor een Process gebruikt worden om de SuperNode in een aparte JVM te draaien. Om de gebruiker te voorzien van de mogelijkheid deze SuperNode te starten en te stoppen naar believen, moest dus een manier gevonden worden om de twee JVMs met elkaar te laten communiceren (ook al gaat het enkel om het starten en stoppen van de SuperNode). In die zin is het gebruik van RMI hier eerder een hack om het bovengenoemde probleem te omzeilen dan een echte oproep op afstand, aangezien deze RMI call steeds lokaal zal gebeuren.
De tweede RMI interface, SuperNodeRMIAccess, abstraheert de functionaliteit van het opzoeken van de verantwoordelijke proxy voor een gebruiker.
Deze operatie zal intern via de DHT de
lookupProxyLP operatie uitvoeren. Deze interface werd in eerste instantie voorzien voor de bootstrap node van de DHT, zodat Node-objecten daarop via RMI het adres hun verantwoordelijke proxy kunnen te weten komen wanneer zij inloggen in het systeem. Dit is dus een echte oproep op afstand, aangezien de Nodes die de oproep doen over het algemeen niet gecoloceerd zullen zijn met de bootstrap SuperNode. Deze functionaliteit is echter voorzien in alle SuperNodes, en kan dus eventueel gebruikt worden in een caching mechanisme om de bootstrap SuperNode te ontlasten van deze oproepen. Hierover meer in hoofdstuk 6. De klasse SuperNodeImpl implementeert dus de drie interfaces SuperNode, SuperNodeRMIController en SuperNodeRMIAccess. Ook wordt de UnicastRemoteObject klasse uitgebreid, dit voor de ondersteuning van de RMI interfaces. Aangezien de SuperNode in een apart Process wordt opgestart (zie boven), zal dit via een main methode moeten gebeuren. Er is ervoor gekozen deze main methode in de SuperNodeImpl klasse zelf onder te brengen, aangezien deze klasse ook eectief wordt opgestart. In deze main wordt de SuperNodeImpl ook gebonden in het RMIRegistry, één keer als SuperNodeRMIController op localhost, en één keer als SuperNodeRMIAccess op het publieke IPadres. Het SuperNodeImpl object wordt echter niet direct aangemaakt, maar via de SuperNodeFactory klasse, die garandeert dat er op elk moment slechts één SuperNode per JVM aanwezig is.
Hoofdstuk 4. Software Architectuur
72
Er is ook voorzien dat meerdere SuperNodes op hetzelfde IPadres kunnen lopen (weliswaar in aparte JVMs), door de bindstring waarmee de RMI interfaces gebonden zijn in het RMI-Registry een nummer mee te geven. Dit is vooral handig voor testdoeleinden.
4.3 Sequentie-diagrammen In deze sectie zullen aan de hand van sequentiediagrammen de belangrijkste scenario's die zich kunnen voordoen in het systeem achtereenvolgens besproken worden. In de sequentiediagrammen zullen ook SIP-berichten voorkomen, die zullen telkens d.m.v. het
Courier
lettertype onderscheiden kunnen worden van de andere pijlen.
4.3.1 Login Een gebruiker kan inloggen in het systeem door in de initiële GUI zijn SIP-URI in te geven en op Login te klikken. Er zal nu een RMI call gebeuren naar de bootstrap SuperNode van het p2p netwerk (d.i. de eerste SuperNode van het p2p netwerk). Deze bootstrap SuperNode zal dan het adres teruggeven van de verantwoordelijke proxy voor de ingegeven SIP-URI.
Hoofdstuk 4. Software Architectuur
bootstrap : SuperNode
73
nsc : SipClient
n : Node
rsp : SipProxy
rsn : Supernode
lookupProxyLP(SIP-URI) ProxyLPAnswer proxy register (SNadress, Username)
setUserXML (UserXML)
REGISTER (userName)
OK (met content : UserXML)
getUserXML (userName) return UserXML
getPresenceForBuddies publish (status) PUBLISH(status) OK
Figuur 4.4: Sequentiediagram voor het inloggen van een gebruiker.
Eens een gebruiker zijn verantwoordelijke proxy kent, kan deze een REGISTER bericht sturen naar zijn proxy.
De proxy zal het bericht ontvangen, aan de SuperNode de desbetreende
UserXML opvragen en deze naar de SipClient terugsturen als de inhoud van een OK response. Wanneer de SipClient die OK response ontvangt zal deze de bijgeleverde UserXML doorspelen naar de UserXMLManager, en deze zal een User object aanmaken (dit wordt in het sequentiediagram vereenvoudigd voorgesteld door een setUserXML pijl naar Node). Eens de UserXML goed en wel ontvangen is, wordt er voor elke contactpersoon in de lijst van contactpersonen een SUBSCRIBE gestuurd. Dit wordt in guur 4.4 verkort weergegeven als getPresenceForBuddies. Er is een apart sequentiediagram voorzien voor getPresenceForBuddies, nl. guur 4.5. Het gehele procédé dat geschetst wordt in guur 4.5 is eigenlijk het standaard subscribe paradigma zoals ook besproken in 3.2.1.
Hoofdstuk 4. Software Architectuur
74
responsible for node node : Node
nodeSC : SipClient
responsible for node X
respProxyNode : SipProxy
respProxyX : SipProxy
respPSX : PresenceServer
while (moreBuddies) SUBSCRIBE (SIPnameX, expires)
SUBSCRIBE (SIPNameX, expires)
processSubscription (Request req)
OK OK NOTIFY + pidf NOTIFY + pidf stateChanged OK
OK
Figuur 4.5: Sequentiediagram voor het getPresenceForBuddies onderdeel van de loginprocedure.
Eens er voor alle contactpersonen een SUBSCRIBE bericht verzonden is, zal nog de huidige status van de gebruiker gemeld worden aan de verantwoordelijke PA (dit zal over het algemeen Oine zijn). Hiermee is de loginprocedure afgerond en is de gebruiker volledig toegetreden tot het systeem.
4.3.2 Het toevoegen van een contactpersoon aan de lijst met contactpersonen Om een andere gebruiker toe te voegen aan de lijst met contactpersonen dient men zich in te schrijven bij de PA van die gebruiker. Hiertoe wordt een SUBSCRIBE bericht met als inhoud een BuddyXML gestuurd naar de eigen verantwoordelijke proxy, die het bericht indien nodig verder zal routeren naar de verantwoordelijke proxy van de notier. Zoals wordt aangegeven op guur 4.6 dient ook de UserXML die de contactlijst van de gebruiker bevat op de hoogte gebracht te worden van het feit dat er een nieuwe contactpersoon aan de lijst met contactpersonen is toegevoegd. Dit vereist dus ook een oproep van de eigen proxy naar de eigen SuperNode bij het binnenkomen van dergelijk bericht.
Hoofdstuk 4. Software Architectuur
75
Eens het SUBSCRIBE bericht aangekomen is bij de PA van de notier zal deze een OK response terugsturen met daarop volgend een NOTIFY voorzien van een PIDF document als inhoud met de laatste presence informatie van de notier.
n : Node
eigenProxy : SipProxy
nsc : SipClient
subscribe (username, domain)
SUBSCRIBE + buddyXML
eigenSN : Supernode
andereProxy : SipProxy + PA
SUBSCRIBE + buddyXML
setUserXML(userName, domain, buddyXML) OK OK
if (OK) addBuddy
NOTIFY + PIDF
NOTIFY + PIDF
showStatusNewBuddy OK OK
Figuur 4.6: Sequentiediagram voor het toevoegen van een contactpersoon
Het verwijderen van een contactpersoon uit de lijst met contactpersonen wordt op volledig analoge mainer gedaan.
4.3.3 Het starten van een SuperNode Een SuperNode starten zal gebeuren aan de hand van de methode startSuperNode() van de interface SuperNodeManager. Deze zal lokaal over RMI de SuperNode opstarten (aangezien een SuperNode een apart process is). Als de SuperNode opgestart is, dient deze zelf nog een aantal handelingen te verichten vooraleer hij volledig operationeel is.
Zo zal eerst de DHT component opgestart worden, en zullen de
gebruikers waarover deze SuperNode de verantwoordelijkheid krijgt opgevraagd worden.
De
SuperNode zal nu voor elke ontvangen gebruiker (en dus voor elke UserXML die hij van de DHT
Hoofdstuk 4. Software Architectuur
76
ontvangen heeft) een User object aanmaken dat gemapt wordt op deze UserXML (en in een ConcurrentHashMap opgeslagen). Eens dit gebeurd is, zal de proxy component opgestart worden. Er wordt ook een TimerTask aangemaakt die telkens een bepaalde periode (gelijk aan de refresh rate van de DHT component) verlopen is, zal nagaan of de SuperNode geen verantwoordelijkheid over gebruikers heeft bijgekregen of verloren. Indien er verantwoordelijkheden zijn bijgekomen, dan zal de SuperNode voor deze gebruikers ook een User object aanmaken, dit mappen op de UserXML en in de map steken. Als er verantwoordelijkheden verdwijnen dienen de overeenkomstige entries in de map verwijderd te worden en dienen de gebruikers op de hoogte gebracht te worden van het feit dat ze geredirect moeten worden. In de PA moeten de subscribers voor de notiers die geredirect worden, ook verwittigd worden dat hun notier een andere proxy krijgt. Mocht dit niet gebeuren dan zouden de subscribers niet meer ingeschreven zijn bij die notier, aangezien deze bij zijn nieuwe PA zonder subscribers zal geïnitialiseerd worden. Om subscribers op de hoogte te brengen dat ze moeten herinschrijven voor die notier werd geopteerd om een SERVICE_UNAVAILABLE response met een Retry-After header op het laatste SUBSCRIBE request voor die notier terug te sturen.
Hoofdstuk 4. Software Architectuur
snMngrA : SNMngr
supernodeA : Supernode
77
task : OwnedUsersTask
proxyA : SipProxy
dhtA : DHT
deletedUser : NodeCallBack
startSN ( ) start( ) getOwnedUsers( ) initialize(ownedUsers)
start( ) timer.schedule( )
Every ''refreshRate'' seconds getOwnedUsers( )
if (newOwnedUsers) addUsers( ) if (usersNoLongerOwned) deleteUsers ( )
getClientIP (deletedUser) redirectSubscribers(deletedUser) ProxyLPAnswer newProxy = lookupProxyLP(deletedUser) redirect(newProxy)
Figuur 4.7: Sequentiediagram voor het starten van een SuperNode.
4.3.4 Het afsluiten van een SuperNode Als een SuperNode gestopt wordt zullen de gebruikers waarvoor de SuperNode op dat moment verantwoordelijk is, moeten geredirect worden naar een nieuwe verantwoordelijke proxy. Opnieuw zullen hierbij ook de subscribers van de geredirecte gebruikers moeten verwittigd worden. Dit gebeurt op dezelfde manier als hierboven beschreven in sectie 4.3.3. Als aan een client gemeld wordt dat hij moet geredirect worden zal telkens het adres van zijn nieuwe proxy meegegeven worden. Hierbij zit echter een addertje onder het gras. Op het moment
Hoofdstuk 4. Software Architectuur
78
dat de SuperNode die wil afsluiten aan een client zal melden dat hij geredirect moet worden, zal de DHT component van de SuperNode nog draaien en heeft de SuperNode nog steeds de verantwoordelijkheid over die gebruiker. Dit wil zeggen dat als de client de opdracht krijgt te redirecten, deze als nieuwe proxy zijn huidige proxy zal terugkrijgen.
En aangezien deze elk
moment kan afsluiten, vormt dit een probleem. Dit werd echter opgelost op volgende manier : als de client merkt dat zijn nieuwe proxy dezelfde proxy is als zijn huidige proxy, zal deze een zgn. delayed redirect doen. Hierbij wordt enkele ogenblikken gewacht, en de client zal dan een aanvraag doen naar de bootstrap SuperNode van het systeem om zo zijn nieuwe proxy te weten te komen. De wachttijd dient echter lang genoeg te zijn, zodat men met vrij grote zekerheid kan zeggen dat de afsluitende SuperNode eectief weg zal zijn (en de sleutels/waarden herverdeeld zijn). Hier wordt dezelfde tijd als de refresh rate van de DHT genomen.
snMngrA : SNMngr
superNodeA : SuperNode
proxyA : SipProxy
dhtA : DHT
redirectedUser : NodeCallBack
stopSupernode( )
while (more users to be redirected) ProxyLPAnswer newProxy = lookupProxyLP(userToRedirect)
redirectSubscribers (userToRedirect) redirect(newProxy)
stop( )
stop( )
Figuur 4.8: Sequentiediagram voor het stoppen van een SuperNode.
Eens voor alle gebruikers waarvoor de SuperNode verantwoordelijk is het commando tot redirecten gegeven is, zal de SuperNode zijn Proxy en DHT componenten afsluiten, waarna deze zelf ook afsluit.
Hoofdstuk 4. Software Architectuur
79
4.3.5 Het uitnodigen van een andere gebruiker tot het opzetten van een mediasessie Om een andere gebruiker tot het opzetten van een mediasessie uit te nodigen, zal een INVITE bericht gebruikt worden. De gehele ow hierbij volgt eigenlijk zo goed als volledig de standaard manier, zie hiervoor ook 3.2.1 en 2.2.3. Bij het routeren van een bericht naar de verantwoordelijke proxy van de callee (indien nodig), wordt beroep gedaan op de DHT. Indien de proxy merkt dat hij niet verantwoordelijk is voor de callee, zal hij via de SuperNode aan de DHT component vragen wat het adres van de verantwoordelijke proxy voor de callee is. Aan de hand van het verkregen adres kan het INVITE bericht dan gerouteerd worden tot bij de callee.
mediaCaller : VoIPMngr
caller : Node
scCaller : SipClient
spCaller : SipProxy
DHTCaller : DHT
spCallee : SipProxy
scCallee : mediaCallee: SipClient VoIPMngr
invite (calleeName) INVITE lookupProxyLP (calleeName)
ProxyLPAnswer INVITE
INVITE processRequest
Other SIP traffic following initial INVITE message [rcvMsg == OK] setupRTP ( ... )
[rcvMsg == OK] setupRTP ( ... )
Figuur 4.9: Sequentiediagram voor het uitnodigen van een andere gebruiker tot het opzetten van een
mediasessie.
Hoofdstuk 4. Software Architectuur
80
4.3.6 Het afsluiten van een Node Als een Node stopt dient hij zich voor elke contactpersoon in zijn lijst uit te schrijven bij de betreende PA. Dit gebeurt door naar de eigen proxy een zgn. unsubscribe te sturen, dit is een SUBSCRIBE bericht met Expires-header gelijk aan 0 (zie hiervoor ook 2.2.4). Eens men is uitgeschreven voor elke contactpersoon, dient men nog te unregisteren bij de eigen registrar. Dit gebeurt door middel van een REGISTER bericht met Expires header gelijk aan 0 (zie ook 2.2.2).
n : Node
nsc : SipClient
userRegistarr : Registrar
rsp : SipProxy
notifierPS : PresenceServer
while (more buddies)
unsubscribe (buddyName)
SUBSCRIBE (expires = 0, userName)
processSubscribe(...) OK NOTIFY OK
unregister (userName) REGISTER (expires = 0, userName) OK
deleteRegistration(userName)
Figuur 4.10: Sequentiediagram voor het afsluiten van een Node.
Hoofdstuk 5
Evaluatie In dit hoofdstuk zullen de resultaten besproken worden van de testen die uitgevoerd zijn op het geïmplementeerde systeem. Deze testen gingen na wat de throughput is van het systeem, d.i. wat de maximaal haalbare call rate (in CAlls Per Second of CAPS) is zonder een te groot percentage aan gefaalde calls. Verder werd ook nagegaan wat de responstijd van het systeem is. Ook op het processorgebruik is gelet, aangezien deze de belasting van de testcomputers weergeeft. Vanzelfsprekend handelen deze testen over de SuperNode componenten, en niet over de Node componenten, aangezien enkel de SuperNodes calls routeren en eigenlijk de basisblokken van het hele systeem zijn. Deze verzorgen de aangeboden diensten naar de Nodes toe.
Voor de tests werd het programma SIPp gebruikt, een gratis open-source traekgenerator voor SIP-gebaseerde systemen met vele ingebouwde mogelijkheden (zie [24]). Versie 1.0 werd gebruikt, aangezien dit de laatste stabiele versie van het programma is op het moment van schrijven. Verder werden alle tests uitgevoerd op AMD Athlon 64 3000+ machines met 1 GB RAM, op een linux kubuntu besturingssysteem met kernelversie 2.6.10. Het netwerk waarmee ze onderling verbonden zijn, is een gigabit LAN.
In de secties hieronder zullen de uitgevoerde tests elk apart besproken worden. Alle tests zijn uitgevoerd over UDP (met en zonder retransmissies van berichten), aangezien het testen over TCP door meerdere praktische problemen in verband met de testopstelling onmogelijk bleek binnen het beschikbare tijdsbestek. Vooraleer de tests besproken worden, zullen we eerst nog enkele globale parameters bespreken die van groot belang zijn op de performantie van de applicatie.
81
Hoofdstuk 5. Evaluatie
82
5.1 Globale parameters De parameters die een grote invloed hebben op de throughput van de SuperNodes, en meerbepaald van hun proxy-component, zijn het maximaal aantal connecties die mogen worden aangegaan, het maximale aantal servertransacties (een (JAIN-)SIP-specieke parameter: voor elk inkomend bericht wordt een servertransactie aangemaakt), en de grootte van de threadpool (de proxy zal zoveel mogelijk calls en transacties simultaan proberen afhandelen in aparte draden).
Het bleek dat de parameters voor het maximale aantal connecties en servertransacties vrij hoog moesten gekozen worden om een aanvaardbare call rate te bekomen.
In onze testopstellingen
werd gekozen voor 2000, wat ruimschoots voldoende is voor de testen die we vooropstelden. Het is vooral van belang dat deze parameter niet te laag wordt gezet, omdat de proxy anders in een deadlock zou kunnen komen te zitten. Dit kan bijvoorbeeld wanneer het maximale aantal servertransacties bereikt is, en de antwoorden binnenkomen op de berichten die tot de creatie van deze lopende transacties aanleiding gaven. Op dat moment zijn niet genoeg resources meer vrij om de antwoorden te verwerken, en zullen dus ook de transacties aangemaakt voor de berichten waarop deze antwoorden binnenkomen niet meer afgesloten kunnen worden. Wat dus aanleiding geeft tot minstens vertraging, doordat de transacties eerst een time-out moeten genereren voor de resources vrijgegeven worden, en in het ergste geval deadlock.
De waarde voor de grootte van de threadpool moet groot genoeg gekozen worden om een goede throughput te bekomen, maar mag ook niet te groot gekozen worden omdat de overhead in processorbelasting door de contextwisselingen die nodig zijn om van thread naar thread te springen anders te groot zou worden, en een negatieve invloed zou hebben op de responstijd (en indirect dus ook op de call rate, aangezien nieuwe calls pas zullen opgestart worden als er voldoende voorgaande calls afgesloten zijn).
Door experimenteel onderzoek hebben we gevonden
dat de optimale parameter 256 bedraagt voor deze testconguraties. Naar alle waarschijnlijkheid zal deze parameter op meer high-end processoren (zoals in recente dual-core en hypertreadingmachines) veel hoger kunnen ingesteld worden zonder negatieve impact op de performantie. De optimale waarde zal over het algemeen ook verschillend zijn van conguratie tot conguratie.
Hoofdstuk 5. Evaluatie
83
Uiteraard werd voor elke test ook de logging van de applicatie afgezet, aangezien het continu schrijven naar schijf of scherm enorm veel verschil uitmaakt qua performantie. Nog een aandachtspunt waar we op wensen te wijzen, is dat voor alle tests geen enkele testcomponent gecoloceerd was met een andere, m.a.w.
alle testcomponenten draaiden op een verschillend IP-adres.
Dit om
onnauwkeurige metingen en extra belasting te vermijden.
Bij het testen werd ook opgemerkt dat er een geheugenlek in de applicatie zit (zie 6.1.5), waardoor na elke test de SuperNode component moest afgesloten en opnieuw gestart worden, en er geen (zeer) hoge waarden voor het aantal calls kon genomen worden : er konden maximum 500 tot 700 calls opgezet worden voor het geheugen volliep. Dit verhinderde ook het laten warmlopen van de proxy, wat gebruikelijk is bij dergelijke metingen. De waarde voor het aantal opgezette calls is bij onderstaande testen dan ook steeds 500. De hoeveelheid geheugen ingenomen door de voorzieningen voor deze 500 calls, is steeds ongeveer dezelfde, en bedraagt plus minus 150MB.
Het testscenario is steeds hetzelfde: 1 callee wordt gebeld door 4 verschillende callers, en nadat de calls zijn opgezet (d.i.
na het sturen van een ACK door de caller) worden ze onmiddellijk
afgesloten door de callerkant (door het sturen van een BYE). De responstijden worden steeds gemeten vanaf het versturen van de INVITE tot het toekomen van de OK op de INVITE. Er werd voor 4 verschillende callers gekozen om wat variatie te krijgen in de berichtheaders (voor debugdoeleinden), maar dit heeft geen impact op de performantie van de proxy aangezien SIPp sowieso traek genereert vanop een andere UDP poort voor elke call. Zo wordt immers een groot aantal UACs geëmuleerd. Per call wordt willekeurig 1 van de 4 callers gekozen. Op zich maakt het dus niet uit wie een caller is, of hoeveel ervan een verschillende naam of SIP-URI hebben. Dit heeft ook geen invloed op de call rate: er worden steeds evenveel calls per seconde opgezet, enkel de afzender van de berichten verandert (van poort en misschien van naam). wordt schematisch getoond in guur 5.1.
Dit testscenario
Hoofdstuk 5. Evaluatie
84
UAC
Proxy A INVITE
NG
TRYI
UAS
INVITE
Responstijd
G GIN RIN G GIN RIN
OK
OK ACK
ACK
BYE
ACK BYE
OK OK
Figuur 5.1: Schematische voorstelling van de SIP-ow
Het sturen van een extra ACK naar de proxy is nodig opdat deze anders automatisch de OK responses van de UAS zou blijven hersturen. Dit ligt aan de ingebouwde retransmissielter van de NIST-SIP implementatie.
Nog een eigenaardigheid is de noodzaak om de ACKs en BYEs
langs de proxy te routeren, zie in verband hiermee 6.1.3. Er werd voor geopteerd om in de resultaten slechts graeken te tonen wanneer er voldoende schommeling zat op de bekomen testwaarden. Indien m.a.w. de waarden voor vb. de call rate voor een bepaalde test over de gehele test gelijk bleef, wordt dit niet in graekvorm weergegeven. Ook belangrijk is dat de waarden voor de responstijden uitgemiddeld zijn over verschillende testruns, terwijl de graeken voor de call rate momentopnames voorstellen bij 1 testrun (die het gemiddelde geval het dichtst benadert).
Dit om beter de relatie tussen pieken in call rate en
hoge gemiddelde responstijden te visualiseren. Verder zal het vermelde percentage gefaalde calls ook steeds de gemiddelde waarde over verschillende testruns heen zijn. Wanneer we in de volgende secties spreken over de call rate bedoelen we de eectief gemeten aangenomen call rate van de proxy, d.i.
een waarde in CAPS die aangeeft hoeveel calls de
Hoofdstuk 5. Evaluatie
proxy op een bepaald moment kan verwerken.
85
Indien we echter het aantal calls bedoelen dat
aangeboden wordt door de testapplicatie, d.i. het aantal calls dat SIPp per seconden zal proberen opzetten, zullen we van de ingestelde call rate spreken. Deze laatste waarde is immers één van de parameters die aan SIPp meegegeven wordt. Verder zullen we ook bij elke test vermelden welke hoeveelheid calls procentueel verloren ging, d.i. niet (correct) opgezet, als gevolg van pakketverlies. Dit pakketverlies zal vooral voorkomen door de onbetrouwbaarheid van het onderliggende UDP protocol, maar kan ook veroorzaakt worden door het vollopen van de proxy-queue. Dan kunnen soms berichten uit de queue vallen omdat die vol zit. Dit laatste komt heel weinig voor, maar wordt wel iets erger bij hogere (ingestelde) call rates.
5.2 Test zonder retransmissies noch optimalisaties met één SuperNode De eerste test is de meest eenvoudige: de caller kant wordt gesimuleerd door een SIPp UAC scenario dat de 4 verschillende callers bevat; de callee kant wordt gesimuleerd door een SIPp UAS scenario dat alle ontvangen berichten zal beantwoorden; de routing tussen de twee kanten wordt verzorgd door één SuperNode (waar de UAS uiteraard geregistreerd is). Er werden opeenvolgende testen uitgevoerd met oplopende call rates, beginnend bij 5 CAPS. Deze call rates zijn uiteraard de ingestelde call rates voor de test en kunnen dus verschillen van de gemeten waarden voor de call rate. Dit zal ook besproken worden waar nodig.
5.2.1 5 CAPS Call Rate
De call rate bleef over de gehele test gelijk aan de ingestelde call rate, nl. 5.
Er gingen geen calls verloren.
Responstijd
Bij guur 5.2 valt op dat er een piek van 95ms is na 10 seconden, maar de gemid-
delde responstijd daarna zal stabiliseren rond de 38 ms. We merken hierbij op dat 80% van de berichten een antwoord krijgt binnen de 20ms, en dat de gemiddelde responstijd omhooggestuwd wordt door de berichten in de piek, die gevormd wordt door 10% van de berichten die een responstijd hoger dan 100ms hebben.
Hoofdstuk 5. Evaluatie
86
100 90 80 70 60 50 40 30 20 10 0
0 01
:4
0 0:
01 0:
:2 01 0:
:3
0
0 :1
0 01 0:
:0
0
01 0:
00
:5
0 0:
00
:4
0 0:
:3 00 0:
:2
:1
00 0:
00 0:
0
ResponseTime(avg in ms)
0
Average Response Time (ms)
ResponseTime(average in ms) per Elapsed Test Time (in s)
Elapsed Test Time (s)
Figuur 5.2: Graek van de gemiddelde responstijd t.o.v. de verstreken testtijd
De piek is te wijten aan het feit dat het CPU gebruik op dat moment vrij hoog ligt, nl. 99%, terwijl eens deze burst gedaan is (na 50 calls), het CPU gebruik terug een vrij normale waarde aanneemt (tussen de 10 en 40%), met als gevolg een betere responstijd.
5.2.2 10 CAPS Call Rate
De call rate is over het algemeen gelijk aan de ingestelde call rate, nl. 10 CAPS.
In de eerste 10 seconden is de call rate een weinig lager, aangezien de proxy dan een burst van berichten binnenkrijgt. Men kan verwachten dat dit zich ook zal vertalen in een hogere waarde voor de responstijd bij 10 seconden. Er gingen gemiddeld 0,5% calls verloren door berichtverlies.
Responstijd
De responstijd vertoont een piek na 10 seconden, te wijten aan de burst van
berichten die de proxy op dat moment ontvangt (zie ook de lagere call rate op dat moment). Nadien zal de responstijd zich stabiliseren rond de 200 ms. We merken op dat de gemiddelde responstijd hier al veel hoger is dan bij 5 CAPS het geval was. 30% van de berichten had een
Hoofdstuk 5. Evaluatie
87
responstijd hoger dan 100ms, en 60% van de berichten had een responstijd lager dan 30ms. Aangezien de gemiddelde responstijd echter getoond wordt, zal de minderheid van berichten met een relatief hoge responstijd de gemiddelde responstijd zwaar naar boven trekken.
ResponseTime(average in ms) per Elapsed test Time (in s) 900 ResponseTime (avg ms) 800
Average Response Time (ms)
700 600 500 400 300 200 100 0 0:00:10
0:00:20
0:00:30
0:00:40
0:00:50
Elapsed Test Time (s)
Figuur 5.3: Graek van de gemiddelde responstijd t.o.v. de verstreken testtijd
De piek in de responstijd is opnieuw te wijten aan het hoge CPU gebruik (99%) de eerste 10 seconden. Nadien daalt het CPU gebruik tot 30 à 60%, en ook de responstijd daalt dan weer.
5.2.3 15 CAPS Call Rate
Zoals guur 5.4 aangeeft komt de callrate na 20 seconden in de buurt van de
ingestelde call rate. De vooropgestelde waarde van 15 CAPS wordt echter niet gehaald. De waarden voor de call rate zijn momentopnamen, en hier zien we dus duidelijk dat op sommige momenten de hoeveelheid calls die opgestart wordt groter is dan op andere momenten. Dit hangt uiteraard af van de belasting van de proxy: als er veel calls ineens worden afgesloten, zal de UACkant besluiten meer nieuwe calls op te zetten met als gevolg een hogere call rate.
Hoofdstuk 5. Evaluatie
88
Is dit niet zo en komen er m.a.w.
weinig BYEs terug, dan zal de UAC minder nieuwe calls
opzetten, met als gevolg een lagere call rate.
CallRate(sample in caps) per Elapsed Test Time (in s) 16 CallRate(sample in caps)
Sample Call Rate (CAPS)
14 12 10 8 6 4 2 0 0:00:10
0:00:20
0:00:30
0:00:40
Elapsed Test Time (s)
Figuur 5.4: Graek van enkele sample call rates t.o.v. de verstreken testtijd
Er werden 0,8% calls niet opgezet door verlies van berichten.
Responstijd
Opnieuw is er een piek te zien in het begin van de meting (opnieuw te wijten
aan de burst). Daarna zal echter de responstijd dalen tot een waarde van ongeveer 1450 ms, een waarde die meer dan het drievoudige is als bij 10 CAPS. Hierbij merken we ook op dat quasi alle berichten een responstijd hoger dan 200ms hadden.
Hoofdstuk 5. Evaluatie
89
ResponseTime(average in ms) per Elapsed Test Time (in s) 2000 ResponseTime(avg ms)
1800 Average Response Time (ms)
1600 1400 1200 1000 800 600 400 200 0 0:00:10
0:00:20
0:00:30
0:00:40
Elapsed Test Time (s)
Figuur 5.5: Graek van de gemiddelde responstijd t.o.v. de verstreken testtijd
Het processor gebruik lag tijdens deze test continu op 99%, wat ook de hoge responstijden verklaart. Enkel na ongeveer 400 calls te hebben opgezet zakt dit naar een waarde tussen de 40 en de 80%.
5.2.4 20 CAPS Call Rate
Er wordt na 20 seconden een waarde van bijna 17 CAPS bereikt, maar nadien gaat
het onherroepelijk bergaf met de call rate. Dit is voor een groot stuk te wijten aan het feit dat de proxy in het begin een burst van berichten binnenkrijgt, en deze niet allemaal tegelijk kan behandelen.
Berichten komen op die manier in de queue terecht, en deze zal voller en voller
raken, waardoor de call rate zal dalen aangezien niet genoeg opgezette calls afgesloten worden, en het aantal concurrente calls dus op zijn maximum blijft zitten. Het dalen van de call rate zal de proxy de tijd geven de overgebleven berichten uit de queue ook te verwerken. Hierna zal de call rate opnieuw een beetje oplopen, aangezien door de lagere belasting ook meer calls worden afgesloten (dit door BYE berichten die nog in de queue aanwezig waren).
Hoofdstuk 5. Evaluatie
90
CallRate(sample in caps) per Elapsed Test Time (in s) 18 CallRate(sample caps)
16
Sample Call Rate (CAPS)
14 12 10 8 6 4 2 0 0:00:10
0:00:20
0:00:30
0:00:40
Elapsed Test Time (s)
Figuur 5.6: Graek van enkele sample call rates t.o.v. de verstreken testtijd
Er gingen gemiddeld 1,4% calls verloren.
Responstijd
De responstijd toont deze keer niet echt een piek, maar blijft op een hoog niveau
hangen (rond de 2500 ms, zie 5.7). De processor is bij 20 CAPS ook zo goed als de gehele tijd volledig belast. Slechts 10% van alle verstuurde berichten krijgt een antwoord in minder dan 1 seconde, en 60% van de berichten in meer dan 2 seconden! Deze responstijden zijn onaanvaardbaar met slechts 1 hop tussen de UAC en UAS.
Hoofdstuk 5. Evaluatie
91
ResponseTime(avg in ms) per Elapsed Test Time (in s)
Average Response Time (ms)
3000
2500 2000
1500 1000 ResponseTime(avg ms)
500
0 0:00:10
0:00:20
0:00:30
0:00:40
Elapsed Test Time (s)
Figuur 5.7: Graek van de gemiddelde responstijd t.o.v. de verstreken testtijd
5.2.5 Conclusie We observeren dat een ingestelde call rate hoger dan 15 aanleiding geeft tot enorm hoge responstijden, en dat de ingestelde call rate ook niet gehaald wordt. Call rates kleiner dan of gelijk aan 15 geven vrij goede resultaten, maar de responstijd laat bij een call rate van 15 toch ook al te wensen over. De beginpieken geven overal aanleiding tot hoge responstijden.
Dit is niet enkel te verklaren
door de plotse burst van berichten die toekomen, maar ook door het niet warmgelopen zijn van de proxy. Indien men in een regime-toestand dezelfde testen zou kunnen uitvoeren, zouden waarschijnlijk betere responstijden gemeten worden. De belasting van de CPU zou daar dan ook algemeen lager liggen, zonder pieken van 99%. Een ingestelde call rate van 20 zal echter nog steeds niet haalbaar zijn zonder een performantere machine. De CPU belasting is daar dan ook continu 99%. Een belasting van meer dan 80% is over het algemeen al te veel, en introduceert sowieso pieken in de responstijd.
De maximale tijd om een call op te zetten is voor deze test ongeveer 2 seconden, indien de call rate van 15 niet overschreden wordt. Dit is een aanvaardbaar maximum voor dit soort applicatie.
Hoofdstuk 5. Evaluatie
92
Er zijn ook nog tests uitgevoerd met hogere ingestelde call rates dan 20 CAPS, maar daarvan vielen de resultaten qua responstijd nog hoger uit, terwijl de eectieve call rate niet veel hoger geraakte dan 15-16 CAPS. Ook het aantal gefaalde calls lag daarbij beduidend hoger. Daarom laten we deze resultaten achterwege.
5.3 Test zonder retransmissies met optimalisaties met één SuperNode Deze test is analoog aan de eerste test, met één verschilpunt.
In een paper in verband met
performantietuning voor SIP-applicaties (zie [25]), werden enkele optimalisaties voorgesteld voor het verbeteren van de responstijd d.m.v. parametriseren van de Java garbage collection. In het kort komt het erop neer dat de garbage collector geoptimaliseerd wordt om sommige objecten met korte levensduur (zoals SIP-berichten) vlugger uit het geheugen te verwijderen en deze niet te cachen, terwijl objecten met langere levensduur (zoals transacties en dialogs) wel gecachet worden. Verder worden ook plafondwaarden meegegeven voor het geheugengebruik.
De gebruikte parameters voor deze test, meegegeven aan de JVM, zijn:
•
-Xmx512m : zet de maximum heap size op 512MB
•
-XX:+UseParNewGC : stelt de parallelle garbage collector in die samen met de concurrente garbage collector kan lopen
•
-XX:+UseConcMarkSweepGC : stelt de concurrente garbage collector in
•
-XX:+UseTLAB : laat de JVM threads toe objecten lokaal te alloceren, wat leidt tot meer concurrentie zonder grote locking overheadkost
•
-XX:MaxTenuringThreshold=0 : laat toe objecten met een lange levensduur vlug in het niet vrijgegeven geheugen te plaatsen zonder deze objecten veelvuldig te onderzoeken
•
-XX:SurvivorRatio=128 : limiteert de hoeveelheid geheugen die gebruikt wordt om objecten die de garbage collection overleven in op te slaan vooraleer ze denitief in het niet vrijgegeven geheugen worden geplaatst
Hoofdstuk 5. Evaluatie
93
5.3.1 5 CAPS Call Rate
De gemeten call rate bleef over de gehele duur van de test consequent 5, de waarde
van de ingestelde call rate. Er gingen geen calls verloren.
Responstijd
De responstijd vertoonde wat meer schommelingen: op guur 5.8 zien we duidelijk
dat de responstijd tijdens de eerste 15 seconden van de test relatief hoog is t.o.v. de responstijd erna.
ResponseTime(avg in ms) per Elapsed Test Time (in s) 50 ResponseTime(avg ms)
Average Response Time (ms)
45 40 35 30 25 20 15 10 5
0 :4 0: 01
0
0
:4 0: 01
0
:3 0: 01
0
:2 0: 01
0
:1 0: 01
:0 0: 01
0
0
:5 0: 00
0
:4 0: 00
0
:3 0: 00
:2 0: 00
0: 00
:1
0
0
Elapsed Test Time (s)
Figuur 5.8: Graek van de gemiddelde responsetijd t.o.v. de verstreken testtijd
Dit komt overeen met de gemeten CPU-belasting die rond de 99% schommelde tot aan ongeveer het 50e verzonden bericht (d.i. de eerste 10 seconden). Daarna zakte de CPU-belasting tot een waarde tussen de 10% en 40%.
Hoofdstuk 5. Evaluatie
94
5.3.2 10 CAPS Call Rate
De gemeten call rate bleef over de gehele duur van de test 10, met een iets tragere
start van 9,4 CAPS tijdens de eerste 10 seconden van de test. Er gingen geen calls verloren.
Responstijd
De responstijd vertoonde hier grote schommelingen: op guur 5.9 zien we duidelijk
dat de responstijd tijdens de eerste 10 seconden van de test enorm hoog is ten opzichte van de responstijden erna.
De hoeveelheid berichten die tegelijk toekomen op de proxy triggert even
een piek in de responstijd die een minimum een factor 4 en maximum een factor 40 hoger ligt dan de andere gemeten responstijden (ongeveer 800 ms t.o.v. respectievelijk 200 ms en 20 ms). Nochtans merken we ook op dat het overgrote deel van de berichten een lage responstijd had: iets minder dan 85% van de berichten had een responstijd lager dan 50ms. De piek is duidelijk geïntroduceerd door de hoge belasting in het begin.
ResponseTime(average in ms) per Elapsed test Time (in s) 900 ResponseTime(avg ms) 800 Average Response Time (ms)
700 600 500 400 300 200 100 0 0:00:10
0:00:20
0:00:30
0:00:40
0:00:50
0:01:00
Elapsed Test Time (s)
Figuur 5.9: Graek van de gemiddelde responstijd t.o.v. de verstreken testtijd
Dit komt wederom overeen met de gemeten CPU-belasting die rond de 99% schommelde tot aan ongeveer het 150e verzonden bericht (d.i. de eerste 15 seconden). Daarna zakte de CPU-belasting tot een waarde tussen de 30% en 60%.
Hoofdstuk 5. Evaluatie
95
5.3.3 15 CAPS Call Rate
In de gemeten call rate werden bij deze test ook reeds schommelingen bemerkt t.o.v.
de ingestelde call rate. Enkele gepeilde call rates zijn uitgeplot in guur 5.10 t.o.v. de verstreken testtijd. De piek op het einde is te verklaren door de lage belasting van de proxy op het einde van de test, waardoor het aantal calls dat wordt afgesloten groter wordt. Dit heeft dan tot gevolg dat er ineens weer veel calls kunnen worden opgestart, wat de call rate dus doet stijgen. Er gingen bij deze testruns gemiddeld 1,4% van alle calls verloren.
CallRate(sample in caps) per Elapsed Test Time (in s) 16 CallRate(sample in caps) 14
Sample Call Rate (CAPS)
12 10 8 6 4 2 0 0:00:10
0:00:20
0:00:30
0:00:40
Elapsed Test Time (s)
Figuur 5.10: Graek van enkele sample call rates t.o.v. de verstreken testtijd
Responstijd
De responstijd vertoonde ook hier grote schommelingen: op guur 5.11 zien we
dat de responstijd tijdens de eerste 30 seconden van de test zeer hoog is ten opzichte van de responstijden erna. Hierbij merken we ook op dat de piek veel langer aangehouden wordt dan bij de vorige testen met lagere call rates, en dat de responstijd in de piek ook nog hoger ligt (zo'n 200ms) dan de hoogste responstijd verkregen bij de voorgaande test. De piek in responstijd is het hoogst bij aanvang van de test, wat overeenstemt met de resultaten van de vorige tests. Bij deze test merken we echter op dat het grootste deel van de berichten (ongeveer 60%) een responstijd heeft van boven de 200ms, en slechts iets meer dan 20% van de berichten een responstijd van minder dan 50ms heeft. Deze laatste berichten zijn degene die verstuurd zijn na de piek.
Hoofdstuk 5. Evaluatie
96
Door de uitmiddeling van de bekomen resultaten is dit niet zo duidelijk te zien op de guur, aangezien enkele zeer hoge waarden de gemiddelde responstijd zeer vlug de hoogte in jagen. Om de lezer niet te overdonderen met 200 graeken is ervoor gekozen deze resultaten te bespreken zonder graek.
ResponseTime(average in ms) per Elapsed Test Time (in s) 1.800 ResponseTime(avg ms) 1.600 Average Response Time (ms)
1.400 1.200 1.000 800 600 400 200 0 0:00:10
0:00:20
0:00:30
0:00:40
0:00:50
Elapsed Test Time (s)
Figuur 5.11: Graek van de gemiddelde responstijd t.o.v. de verstreken testtijd
Dit komt wederom overeen met de gemeten CPU-belasting die rond de 99% schommelde tot aan ongeveer het 400e verzonden bericht (d.i.
de eerste 25-30 seconden).
Daarna zakte de CPU-
belasting tot een waarde tussen de 70% en 90%.
De schommelende call rate en hoge responstijden zijn verwant met elkaar: indien de responstijd op de eerste verstuurde berichten zeer hoog ligt doordat de CPU van de proxy ze niet allemaal op tijd kan verwerken, zullen er in het interval dat gewacht wordt op een antwoord geen nieuwe calls meer opgezet worden, wat dus de call rate naar beneden haalt. Op termijn stabiliseert de call rate zich wel min of meer in de richting van de ingestelde call rate (nadat de piek in responstijd en CPU belasting voorbij is).
Hoofdstuk 5. Evaluatie
97
5.3.4 20 CAPS Call Rate
De ingestelde call rate van 20 werd nooit gehaald, en de eectief gemeten call rate
lag heel wat lager, gemiddeld rond de 14 CAPS. Enkele gepeilde call rates zijn uitgeplot in guur 5.12 t.o.v. de verstreken testtijd. De plotse daling op het einde van de test is te verklaren door op te merken dat de call rate op seconde 30 gestegen is tot 17, en op dat moment nog slechts een kleine hoeveelheid calls (68) moet opgezet worden. Met een hoge call rate van rond de 17 zal dit slechts een 4 tal seconden in beslag nemen, waardoor de UAC tijdens de laatste 6 seconden van de test geen calls meer opstart, en de corresponderende meting over het laatste interval van 10 seconden dus een stuk lager zal liggen. Er gingen bij deze testruns gemiddeld 1,6% van alle calls verloren.
CallRate(sample in caps) per Elapsed Test Time (in s) 18 16
Sample Call Rate (CAPS)
14 12 10 8 6 4 CallRate(sample caps) 2 0 0:00:10
0:00:20
0:00:30
0:00:40
Elapsed Test Time (s)
Figuur 5.12: Graek van enkele sample call rates t.o.v. de verstreken testtijd
Responstijd
De responstijd vertoonde hier minder schommelingen:
op guur 5.13 zien we
dat de responstijd tijdens de eerste 20 seconden van de test relatief hoog is ten opzichte van de responstijden erna, maar het verschil is niet zo enorm groot. Hierbij merken we ook op dat de piek 500ms hoger ligt dan in de voorgaande test. De responstijden na de piek worden iets beter, maar zijn nog steeds zeer hoog in vergelijking met de voorgaande tests. Slechts 20% van de verstuurde berichten heeft een responstijd van minder dan 250ms, terwijl 60%
Hoofdstuk 5. Evaluatie
98
van de verstuurde berichten maar een antwoord ontvangt na meer dan 1 seconde. Dit laatste is vrij onaanvaardbaar voor een signaling protocol.
ResponseTime(avg in ms) per Elapsed Test Time (in s) 2500 ResponseTime(avg ms)
Average Response Time (ms)
2000
1500
1000
500
0 0:00:10
0:00:20
0:00:30
0:00:40
Elapsed Test Time (s)
Figuur 5.13: Graek van de gemiddelde responstijd t.o.v. de verstreken testtijd
De CPU-belasting was in deze test bijna continu 99%, met een kleine daling naar het einde van de test toe (bij de laatste 20 à 40 berichten). Dit verklaart ook de zeer hoge responstijden; de CPU kan gewoon de toevloed van berichten niet aan, en daardoor moeten alle nieuw toekomende berichten lang wachten vooraleer behandeld te worden.
5.3.5 Conclusie Na overleg met de hoofdauteur van de gebruikte paper bleek dat voor de meest nauwkeurige metingen de proxy best wordt warmgelopen, d.i. de component reeds een groot aantal berichten laten verwerken vooraleer de metingen uit te voeren. Door het gevonden geheugenlek (zie 6.1.5) was dit echter niet mogelijk voor onze applicatie. De tuning zal ook meer winst opleveren bij performantere machines voorzien van vb. dual core processors. Niettemin bemerkten we toch dat de responstijd door deze tuning ietwat verbeterde (vooral bij hogere call rates). tuningparameters.
Hierdoor werd besloten de volgende tests enkel uit te voeren met deze
Hoofdstuk 5. Evaluatie
99
5.4 Test met retransmissies met optimalisaties met één SuperNode Deze test is analoog aan de tweede test, met één verschilpunt.
De NIST-SIP implementatie
voorziet standaard een mechanisme om retransmissies te versturen indien een bepaalde tijd (default 500ms) verstreken is vooraleer een antwoord ontvangen is voor een bericht. Deze retransmissies helpen het berichtverlies over het onbetrouwbare UDP protocol te beperken, en hiermee ook het aantal gefaalde calls. Er kan echter verwacht worden dat de responstijd hierdoor zal vergroten aangezien de proxy meer berichten te verwerken krijgt naarmate er meer retransmissies gebeuren.
5.4.1 5 CAPS Call Rate
De gemeten call rate bleef ook hier consistent met de ingestelde waarde, nl 5.
Er werden wederom geen calls verloren. Er waren ook quasi geen retranmissies : gemiddeld 0,6% van het totale aantal berichten werd opnieuw gestuurd.
Responstijd
De responstijd vertoonde wat schommelingen: op guur 5.8 zien we duidelijk
dat de responstijd tijdens de eerste 15 seconden van de test relatief hoog is ten opzichte van de responstijd erna, wat consistent is met de resultaten uit de voorgaande tests. Bij deze test lagen de responstijden in de piek gemiddeld wel iets hoger dan in de voorgaande test. Verder valt hier op te merken dat wederom 80% van de berichten een responstijd heeft van minder dan 20ms, en de piek dus weer veroorzaakt wordt door de burst van berichten in het begin van de test. In deze burst zal een klein aantal berichten een relatief zeer hoge responstijd hebben t.o.v. de andere berichten, waardoor de gemiddelde responstijd negatief wordt beïnvloed.
Hoofdstuk 5. Evaluatie
100
ResponseTime(avg in ms) per Elapsed Test Time (in s) 100 ResponseTime(avg ms)
Average Response Time (ms)
90 80 70 60 50 40 30 20 10 0
0:00:10 0:00:20 0:00:30 0:00:40 0:00:50 0:01:00 0:01:10 0:01:20 0:01:30 0:01:40 Elapsed Test Time (s)
Figuur 5.14: Graek van de gemiddelde responstijd t.o.v. de verstreken testtijd
Deze resultaten zijn consistent met het CPU gebruik, dat tot aan ongeveer het 50e bericht (d.i. de eerste 10 seconden van de test) steeds op 99% stond, en daarna fel zakte tot tussen de 10% en 40%.
5.4.2 10 CAPS Call Rate
De gemeten call rate bleef in deze test ook vrij consistent met de ingestelde waarde,
nl. 10. Er gingen geen calls verloren. Er werden echter wel een aantal retransmissies verstuurd: gemiddeld 2% van het totale aantal berichten werd opnieuw verstuurd.
Responstijd
De responstijd was hier vrij vergelijkbaar met de test zonder retransmissies,
hoewel hier zelfs iets beter gepresteerd werd. In guur 5.15 zien we ook weer een piek tijdens de eerste 10 seconden, en erna weer een vrij steile daling van de responstijd. Ook hier kunnen we dit verklaren aan de hand van de burst van berichten. Evenals in de test zonder retransmissies ligt het percentage antwoorden ontvangen binnen de 50ms rond de 80 à 85%.
Enkele berichten verstuurd in het begin van de test moeten echter
wachten op verwerking door de proxy, en genereren dus de piek in responstijd.
Hoofdstuk 5. Evaluatie
101
ResponseTime(average in ms) per Elapsed Test Time (in s) 800
Average Response Time (ms)
700
ResponseTime(avg ms)
600 500 400 300 200 100 0 0:00:10
0:00:20
0:00:30
0:00:40
0:00:50
Elapsed Test Time (s)
Figuur 5.15: Graek van de gemiddelde responstijd t.o.v. de verstreken testtijd
Ook hier lag het CPU gebruik tijdens de piek op 99%, en stabiliseerde zich na ongeveer 150 berichten op een waarde tussen de 30 en 60%.
5.4.3 15 CAPS Call Rate
De gemeten call rate benaderde de ingestelde call rate, maar haalde deze over het
algemeen niet. De waarde schommelde meestal tegen de 12 CAPS aan. Wel werd een stijgende lijn vastgesteld naarmate de test vorderde. In guur 5.16 is hiervan een voorbeeld te zien. Er gingen gemiddeld 0,4% van de calls verloren, wat een verbetering van 1% inhoudt ten opzichte van de test zonder retransmissies. Indien we echter kijken naar het aantal retransmissies zien we dat er een enorm aantal berichten opnieuw wordt gestuurd: gemiddeld 350 retransmissies op een totaal van 500 berichten. Dit is 70% van alle berichten!
Hoofdstuk 5. Evaluatie
102
CallRate(sample in caps) per Elapsed Test Time (in s) 16 CallRate(sample caps) 14
Sample Call Rate (CAPS)
12 10 8 6 4 2 0 0:00:00
0:00:10
0:00:20
0:00:30
Elapsed Test Time (s)
Figuur 5.16: Graek van enkele sample call rates t.o.v. de verstreken testtijd
Responstijd
Een blik op de gemiddelde responstijd (zie 5.17) verklaart het grote aantal re-
transmissies. Meer dan 50% van alle verstuurde berichten kregen slechts een antwoord na meer dan 500ms, wat het interval is waarin gewacht wordt op een antwoord bij de UAC en UAS vooraleer een retransmissie te sturen. Door het toekomen van deze retransmissies vergroot de belasting van de proxy nog meer, en dus verhogen ook de responstijden, met als gevolg nog meer retransmissies. Dit fenomeen doet zich voor in de piek van de responstijd, en zal pas stabiliseren wanneer het herstuurde bericht uiteindelijk beantwoord wordt. Op dat moment worden alle retransmissies ervan namelijk verwijderd uit de queue van af te handelen berichten. Verder had slechts 20% van de verstuurde berichten (die geen retransmissies waren) een responstijd onder de 100ms.
Hoofdstuk 5. Evaluatie
103
ResponseTime(average in ms) per Elapsed Test Time (in s) 2000 ResponseTime(avg ms)
1800
Average Response Time (ms)
1600 1400 1200 1000 800 600 400 200 0 0:00:00
0:00:10
0:00:20
0:00:30
Elapsed Test Time (s)
Figuur 5.17: Graek van de gemiddelde responstijd t.o.v. de verstreken testtijd
De belasting van de CPU is navenant: continu 99% tijdens zowat de hele test; enkel naar het einde toe, na de 350e call ongeveer zakt dit naar een waarde tussen de 50 en de 80%.
5.4.4 20 CAPS Call Rate
De ingestelde call rate van 20 werd nooit gehaald, en de eectief gemeten call rate
lag heel wat lager, gemiddeld 13 CAPS. Enkele gepeilde call rates zijn uitgeplot in guur 5.18 t.o.v. de verstreken testtijd. Er gingen gemiddeld 0,8% calls verloren, wat wederom een verbetering inhoudt tegenover de test zonder retransmissies. Indien we echter kijken naar het aantal retransmissies, zien we hier het duizelingwekkende aantal van gemiddeld 470 retransmissies op een totaal van 500 berichten (ongeveer 97%)!
Hoofdstuk 5. Evaluatie
104
CallRate(sample in caps) per Elapsed Test Time (in s) 16 14
Sample Call Rate (CAPS)
12 CallRate(sample caps)
10 8 6 4 2 0 0:00:10
0:00:20
0:00:30
0:00:40
Elapsed Test Time (s)
Figuur 5.18: Graek van enkele sample call rates t.o.v. de verstreken testtijd
Responstijd
Net als bij een ingestelde call rate van 15 zal zich hier de vicieuze cirkel voordoen:
in de beginpiek toegekomen berichten hebben al een zeer hoge responstijd en geven dus aanleiding tot (soms meerdere) retransmissies, die op hun beurt weer de proxy vertragen, waardoor weer meer retransmissies gegenereerd worden. Hier is het probleem zelfs nog een pak erger aangezien de gemiddelde responstijd (te zien in guur 5.19) nog hoger ligt dan bij een call rate van 15 (gemiddeld 1 seconde hoger in de piek, dit betekent minimum 1 retransmissie meer). Ook hier zal de responstijd slechts dalen wanneer uiteindelijk het antwoord op het (meermaals) herstuurde bericht toegekomen is, en dus de retransmissies ervan uit wachtlijn van de proxy verdwijnen.
Verder heeft slechts 20% van alle berichten (die geen retransmissies waren) een responstijd onder de 500ms, wat dus consistent is met het feit dat er voor 80%, dit zijn 400 berichten, een retransmissie verstuurd werd. De verdere retransmissies zijn veroorzaakt door ofwel retransmissies die zelf niet intijds beantwoord werden, ofwel door berichten waarvoor meerdere retransmissies gestuurd zijn.
Hoofdstuk 5. Evaluatie
105
ResponseTime(average in ms) per Elapsed Test Time (in s) 3500 ResponseTime(avg ms)
Average Response Time (ms)
3000 2500 2000 1500 1000 500 0 0:00:00
0:00:10
0:00:20
0:00:30
Elapsed Test Time (s)
Figuur 5.19: Graek van de gemiddelde responstijd t.o.v. de verstreken testtijd
De CPU-belasting is ook hier weer 99% over de gehele testperiode, behalve helemaal op het einde (de laatste 20 à 30 berichten), waar de belasting zakt tot 70 à 80%.
5.4.5 Conclusie Indien we deze testresultaten bekijken, zien we dat het percentage gefaalde calls inderdaad zakt door het gebruik van retransmissies. Als de proxy echter al zwaar belast is, dan zal deze verbetering in het aantal opgezette calls wel ten koste gaan van de responstijd. Een call rate van 15 is al vrij problematisch indien er retransmissies gebruikt worden, aangezien de gemiddelde responstijd al hoger ligt dan 1 seconde en dus de beschreven vicieuze cirkel zich zal voordoen.
Gaan we hoger dan 20 CAPS, dan observeren we dat het percentage gefaalde
calls (dat bij hogere ingestelde call rates zonder retransmissies veel hoger ligt, tussen de 3% en 10%) ook daar zwaar afneemt, maar de responstijden steeds hoger liggen dan 2 seconden, wat niet aanvaardbaar is met slechts 1 hop tussen caller en callee. Indien ingestelde call rates kleiner dan 15 gebruikt worden, kunnen retransmissies wel een positieve invloed hebben op het aantal gefaalde calls zonder de responstijd al te veel te beïnvloeden.
Hoofdstuk 5. Evaluatie
106
Als echter een verlies van ongeveer 1% van de calls aanvaardbaar wordt bevonden, dan zouden we eerder opteren geen retransmissies te gebruiken aangezien zonder retransmissies iets hogere eectieve call rates bekomen kunnen worden.
5.5 Test zonder retransmissies met optimalisaties met twee SuperNodes In deze test gaan we na wat de impact is van de opzoekoperatie op de DHT, die nodig is om de proxy van de callee te bepalen indien deze niet beheerd wordt door de SuperNode waarop de calls eerst toekomen (d.i. de SuperNode die de proxy van de callers omvat).
Eerst schetsen we het testscenario: de callers zetten steeds een sessie op met de callee via een proxy die zich bevindt op een SuperNode (SN A) die niet verantwoordelijk is voor de callee. De SuperNode die wel verantwoordelijk is (SN B), wordt dan in SN A bepaald tijdens het verwerken van de INVITE via een lookupProxyLP(callee) operatie. Deze operatie zal, zoals uitgelegd in 4.2.3, via de DHT component van SN A een getProxyLPMessage sturen naar SN B. SN B zal dit bericht ontvangen en er het listening point van zijn proxy inzetten. Het antwoordbericht zal dan teruggestuurd worden naar SN A, en de proxy van SN A zal dan pas het INVITE bericht kunnen doorsturen naar de juiste proxy. Er zijn dus 2 proxy-hops betrokken bij deze test. Ook belangrijk is dat SN A en SN B voor deze test slechts een afstand 1 van elkaar verwijderd zijn in de DHT, m.a.w. de adressen van hun respectieve DHT-componenten zitten vervat in de ngertabellen, en ze kunnen elkaar dus rechtstreeks bereiken zonder tussenliggende DHT-hops. In een groter p2p-netwerk met imum van ongeveer
n DHT-nodes kan dit aantal hops uiteraard variëren tot een max-
log(n).
Het gebruikte scenario is schematisch weergegeven in guur 5.20.
Hoofdstuk 5. Evaluatie
107
Proxy A
UAC
INVITE TRYING
DHT A
DHT B
Proxy B
UAS
lookupProxyLP lookupProxyLP (callee ) (callee ) B ProxyLP LP B Proxy
Responstijd
INVITE
TRYING
INVITE G
RINGIN
TRYING
RINGING G RINGIN
OK
OK
OK
ACK
ACK
ACK
BYE
ACK
BYE BYE OK
OK
OK
Figuur 5.20: Schematische voorstelling van de SIP-ow in de DHT test
Wat van belang is om onderstaande resultaten in de juiste context te plaatsen, is dat er dus 2 roundtriptimes (RTTs) tussen SN A en SN B bij de normale RTT tussen UAC en UAS komen: 1 RTT voor de DHT-oproep en 1 RTT voor de routering van het INVITE-bericht.
Verder werd ervoor gekozen om slechts 2 ingestelde call rates te testen: 10 en 15 CAPS, aangezien 5 CAPS in de praktijk te weinig is.
Hoofdstuk 5. Evaluatie
108
5.5.1 10 CAPS De ingestelde call rate van 10 werd nooit gehaald, en de eectief gemeten call rate lag veel lager, gemiddeld ongeveer 3 CAPS. Enkele gepeilde call rates zijn uitgeplot in guur 5.21 t.o.v.
de
verstreken testtijd.
CallRate(sample in caps) 4
Sample Call Rate (CAPS)
3,5 3 2,5 2 1,5 1 CallRate(sample in caps)
0,5
0
0
:5
:4 0:
02
0 02 0:
0
:3
:2 0:
02
0 02 0:
0
:1
:0
02 0:
0 :5 0:
01 0:
02
40
0 :3
0:
01 0:
01 :
20
0 :1
01 : 0:
0 0:
01
0
:0 01 0:
0
:5
:4 0:
00
0 0:
00
0
:3
:2
00 0:
00
00 0:
0:
:1
0
0
Elapsed Test Time (s)
Figuur 5.21: Graek van enkele sample call rates t.o.v. de verstreken testtijd
De grilligheid van de graek wordt veroorzaakt door het feit dat de UAC kant steeds moet wachten tot hij een aantal OKs krijgt van de UAS vooraleer hij nieuwe calls zal plaatsen. Kijken we vervolgens naar de responstijd in guur 5.22, dan zien we onmiddellijk waardoor de lage call rate en de grilligheid van de graek veroorzaakt wordt.
De responstijden liggen in
termen van netwerken astronomisch hoog, nl. een gemiddelde van ongeveer 10 seconden. Zelfs indien we de extra RTTs in rekening brengen is dit een zeer hoog resultaat. Aangezien de tijd om een call op te zetten reeds zo hoog is zal het nog langer duren om een call terug af te sluiten, en hierdoor zal UAC steeds zeer lang moeten wachten vooraleer nieuwe calls te kunnen plaatsen. Dit impliceert dus de zeer lage call rate.
Hoofdstuk 5. Evaluatie
109
ResponseTime(average in ms) per Elapsed test Time (in s) 12000
Average Response Time (ms)
10000 8000 6000 4000 2000
ResponseTime (avg ms)
50
40 0:
02 :
0 0:
02 :
0
:3
:2 0:
02
0 0:
02
0
:1
0:
02
0
:0
:5 0:
01 0:
02
40
0 0:
01 :
0
:3
0:
01
0
:2
0:
01
0
:1
0:
01
0
:0
0:
01
0
:5
:4 0:
00
0 0:
00
0
:3 00
0:
:2 00
00 0:
0:
:1
0
0
Elapsed Test Time (s)
Figuur 5.22: Graek van de gemiddelde responstijd t.o.v. de verstreken testtijd
De CPU-belasting van zowel SN A als SN B is hier bijna continu 99%, hoewel er soms minieme intervallen zijn waarin SN A ietwat zakt, om daarna weer te stijgen naar het maximum. Dit is vrij logisch aangezien de DHT-componenten van de SN A en B continu (hetzelfde) bericht naar elkaar sturen en dit dus moeten verwerken, terwijl ze ondertussen ook de SIP-berichten moeten opvangen en routeren. Met name de vele DHT berichten vormen het grootste deel van de belasting.
5.5.2 15 CAPS De resultaten van deze test zijn vrij analoog aan die van de test met 10 CAPS, met dat verschil dat de resultaten nu nog iets slechter zijn qua responstijd, wat te verklaren is door de hogere ingestelde call rate die SIPp probeert te halen.
Dit zal weer aanleiding geven tot een grotere
belasting van de proxies, en dus ook de responsetijd verhogen. Ter illustratie geven we hieronder nog de graeken van de gesamplede call rates en de gemiddelde responstijd in guren 5.23 en 5.24.
Hoofdstuk 5. Evaluatie
110
CallRate(sample in caps) 5 4,5 Sample Call Rate (CAPS)
4 3,5 3 2,5 2 1,5 1 0,5
CallRate(sample in caps)
40
0
02 :
:3
0 :2
0:
0:
02
0 0:
02
0
:1 0:
02
:0
0 0:
02
:5
0 01 0:
0:
01
:4
0
0
:3 0:
01
:2
0 0:
01
:1
0 01 0:
0:
01
:0
0
0 0:
00
:5
0
:4 0:
00
:3
0 :2
00 0:
00 0:
0:
00
:1
0
0
Elapsed Test Time (s)
Figuur 5.23: Graek van enkele sample call rates t.o.v. de verstreken testtijd
ResponseTime(average in ms) per Elapsed test Time (in s) 16000
Average Response Time (ms)
14000 12000 10000 8000 6000 4000 ResponseTime (avg ms)
2000
0
0
:4 02
0:
:3
0 02 0:
0
:2 02
0:
:1
0 02 0:
:0
0 :5 0:
02
0 :4
01 0:
0 :3 0:
01
0 :2
01 0:
01
1:
10 0:
0 :0 01
0: 0
0:
50 0:
0 00
0:
0: 0
:4
0
0:
00
:3
0 :2 00
0:
0:
00
:1
0
0
Elapsed Test Time (s)
Figuur 5.24: Graek van de gemiddelde responstijd t.o.v. de verstreken testtijd
Hoofdstuk 5. Evaluatie
111
5.5.3 Conclusies De resultaten van deze test vallen zoals hierboven reeds gezegd nogal tegen, zowel qua call rate als qua responstijd. Zelfs met het in rekening brengen van de extra RTTs zijn de responstijden zeer hoog, en niet aanvaardbaar qua call setup tijd.
Er zijn echter een paar aandachtspunten waaraan deze test voorbijgaat, en die wel van invloed zijn.
Ten eerste is dit een test waarin steeds één callee opgebeld wordt, en de callers allemaal op dezelfde proxy zitten. In een groot p2p netwerk zullen de gebruikers over het algemeen verdeeld zitten over verschillende nodes, en zal ook niet steeds dezelfde gebruiker opgebeld worden. De throughput van het systeem zal eerder proportioneel zijn met het aantal SuperNodes indien elke keer een verschillende gebruiker wordt opgebeld door gebruikers die zelf ook gedistribueerd zijn over het netwerk. Stel bijvoorbeeld dat we 200 verschillende gebruikers die verdeeld zijn over 25 SuperNodes elkaar in willekeurige volgorde laten uitnodigen voor een sessie, dan zou de belasting van de SuperNodes hoogstwaarschijnlijk al heel wat minder groot zijn dan in deze test het geval is. Deze belasting in de vorm van oproepen op de DHT en verwerking/routering van INVITE berichten zal gedeeld worden door alle SuperNodes in het netwerk.
Aangezien dit echter zeer moeilijk te testen is
zonder veel resources en we ook maar een beperkt tijdsbestek hadden, konden wij geen verdere testen in deze richting uitvoeren.
Ten tweede is er geen enkele optimalisatie aan de DHT-component doorgevoerd. Er is hier wel wat onderzoek naar gedaan, maar zoals hierboven opgemerkt is dit niet eenvoudig te testen. Indien er een mogelijkheid zou bestaan om de interne scheduler van de DHT te tunen zodat berichten speciek voor deze applicatie een prioritaire behandeling krijgen, zou de performantie ook vergroten. De nadruk in de DHT implementatie ligt echter op consistentie van de opgeslagen informatie en robuustheid van het netwerk, en niet op snelheid van het routeren van berichten, aangezien dit over het algemeen in DHT-applicaties (die in se enkel een gedistribueerd opslagmechanisme aanbieden) ook niet zo'n belangrijke factor is.
Hoofdstuk 5. Evaluatie
112
Hetzelfde kan gezegd worden voor de NIST-SIP implementatie. Indien die zou kunnen getuned worden voor betere performantie, zou heel de opgebouwde applicatie een heel stuk sneller lopen. Enkele aanzetten hiertoe worden besproken in hoofdstuk 6.
Algemeen kunnen we m.b.t. deze test besluiten dat die geen sluitend antwoord kan leveren over de invloed van de DHT-component op de throughput van het systeem. Hiervoor zouden verdere testen moeten uitgevoerd worden op een veel groter netwerk.
Hoofdstuk 6
Verder Werk In dit stuk kunnen we een licht werpen op de diverse problemen en uitbreidingen waar nog verder aan kan gewerkt worden. Enkele van deze uitbreidingen zijn : Firewall/NAT-Traversal, Security, Authentication, ...
Dit hoofdstuk zal opgesplitst worden in twee delen : enerzijds zullen mogelijke tweaks en verbeteringen aangebracht worden voor het systeem zoals het nu is. Anderzijds zullen ook enkele uitbreidingen overlopen worden, die meer veelgevraagde functionaliteit aan de applicatie zouden toevoegen.
6.1 Verbetering van de huidige applicatie De huidige applicatie biedt zo goed als volledig alle gevraagde features, edoch zijn er op sommige punten nog verbeteringen en/of aanpassingen mogelijk. Deze verbeteringen en/of aanpassingen zullen in deze sectie aan bod komen.
6.1.1 Preferences Het preferences gedeelte van de applicatie biedt een manier om voor (groepen van) gebruikers regels te speciëren. Zoals gezegd worden deze regels door de gebruiker ingevoerd in de GUI, en worden deze via een PUBLISH bericht naar de verantwoordelijke SuperNode overgebracht. De
113
Hoofdstuk 6. Verder Werk
114
SuperNode is namelijk de entiteit die ervoor zal in staan dat deze regels nageleefd zullen worden. Een regel heeft zoals gespeciëerd in 3.2.1 de vorm ACTIE - VAN - TOT, waarbij VAN en TOT een bepaald tijdstip is uitgedrukt in hh:mm. Er treedt echter een probleem op indien ofwel de tijd in VAN ofwel de tijd in TOT gepasseerd wordt. Op dat moment zou voor de desbetreende subscriber(s) ofwel de regel moeten beginnen gelden, ofwel de regel ongeldig moeten worden. Laten we als voorbeeld het volgende scenario nemen : Alice heeft een regel ingesteld voor Bob zodanig dat deze haar presence informatie niet kan zien tussen 14u00 en 15u00. Om 13u55 is de status van Alice Away. Bob vraagt op dat moment de presence van Alice op (omdat hij vb. in het systeem binnentreedt en Alice een van zijn contactpersonen is), en hij zal nog toegelaten worden om Alice haar presence informatie te ontvangen.
Om 14u00 echter zou Bob Alice als
Oine moeten zien, aangezien hij op dat moment zou moeten geblokkeerd worden door de regel. In het huidige systeem is dit echter niet het geval, Bob zal pas aan de regel onderworpen worden als hij nogmaals een vraag doet naar de presence van Alice, of als Alice haar presence zelf nog eens verandert.
Indien Bob fetchers zou gebruiken om de presence info van Alice te
bemachtigen, dan zal hij na een bepaalde periode geconfronteerd worden met de regel van Alice (vb. na maximaal 5 minuten indien Bob om de 5 miuten een fetcher stuurt voor Alice). In het extreme geval waarin zowel Bob geen aanvraag doet naar de presence van Alice, en waarin Alice haar presence niet verandert, zal Bob Alice gedurende de gehele periode als Away zien.
Er zijn twee mogelijke oplossingen voor dit probleem : in de eerste oplossing stellen we de Node verantwoordelijk om telkens een aangrijpingspunt van een regel verstrijkt, opnieuw de huidige status te publiceren, zodat de geblokkeerde subscribers op dat moment ook met een status Oline zullen geüpdatet worden. In het voorbeeld zou de client van Alice dan om 14u00 en om 15u00 een PUBLISH bericht moeten sturen. Een alternatief is om in de SuperNode de vlag allowed bij de subscribers dynamisch aan te passen met behulp van een Task die voor elke regel waaraan de subscriber onderworpen kan worden, bij aopen kijkt of de subscriber moet toegelaten worden of niet. In het voorbeeld zou dit willen zeggen dat de verantwoordelijke SuperNode voor Alice een Task zou hebben die om 14u00 aoopt en voor alle subscribers op wie de regel van toepassing is (in dit geval Bob) de allowed vlag in hun Subscriber object op false zet, en dan een NOTIFY stuurt naar Bob met als presence info de status Oine. Ook zal er dan een Task nodig zijn die aoopt om 15u00 en die dan de allowed vlag in het Subscriber object voor Bob op true zet, en een NOTIFY bericht
Hoofdstuk 6. Verder Werk
115
stuurt naar Bob met de huidige status van Alice. Beide methoden hebben hun voordelen en nadelen. Bij het eerste geval staat de client zelf in om de SuperNode op de hoogte te brengen van het feit dat de regel is ingegaan (of is afgelopen), terwijl de SuperNode deze informatie eigenlijk zelf ook bevat. Bij dit systeem wordt de SuperNode wel minder belast aangezien hij geen grote hoeveelheid Tasks moet opstarten en bijhouden. Bij het tweede systeem zit alles wat eigenlijk logisch gezien bij elkaar past ook eectief bij elkaar, maar wordt de SuperNode zelf wel een pak meer belast aangezien alle gebruikers van deze SuperNode samen potentieel zeer veel regels kunnen hebben.
6.1.2 Redirection van de subscribers Zoals gezegd in 4.3.3 moeten de subscribers op de hoogte gebracht worden van het feit dat hun notier van proxy veranderd is. Dit gebeurt aan de hand van een SERVICE_UNAVAILABLE response (met een Retry-After header) die geconstrueerd wordt uit het laatste SUBSCRIBE request dat voor door de subscriber voor die notier gestuurd is.
Indien er in de client gepast
gereageerd wordt op de ontvangst van zo'n SERVICE_UNAVAILABLE response (wat ook zo is, aangezien alles werkt zoals het zou moeten als de response eectief aankomt in de client), dan zou dit systeem moeten werken. Er zit echter ergens een bug in dit procédé, aangezien de SERVICE_UNAVAILABLE response op sommige momenten niet aankomt bij de subscriber.
Er zijn enkele dagen gespendeerd om
de fout te proberen vinden, deze hebben echter niks opgeleverd. In sommige gevallen werkt het procédé echter wel, en dan reageert de subscriber ook zoals het hoort, en zal hij zich inschrijven bij de notier die ondertussen al van proxy veranderd is.
Als voorlopige oplossing werd nu beslist om in de conguratiele van de client een parameter te voorzien waarin men de expires parameter van de inschrijving kan aanpassen. De inschrijving zal telkens na die periode ververst worden, en dus zal men op die manier (met enige vertraging) ook bij de goede proxy terecht komen. Merk op dat indien de gebruiker ervoor kiest om fetchers te gebruiken (wat ook in de conguratiele kan opgegeven worden), dit probleem zich niet zal stellen (voor die gebruiker althans), aangezien er geen inschrijving wordt bijgehouden voor die gebruiker.
Hoofdstuk 6. Verder Werk
116
6.1.3 Proxy volledig stateless maken Zoals in hoofdstuk 5 beschreven is, vielen de testresultaten qua call rate wat aan de lage kant uit. Na enig onderzoek bleek dat één van de beïnvloedende factoren hierop het bijhouden van informatie in de proxy is over de sessies tijdens het opzetten ervan. Het bijhouden en aanpassen van deze statusinformatie over de actieve connecties (meerbepaald de Transactions en Dialogs die door de NIST-SIP implementatie gebruikt worden) genereert een overheadkost in de proxycomponent. Dit zou normaalgezien enkel het geval mogen zijn bij het statefull werken van de proxy, maar de gebruikte implementatie houdt deze connectieinformatie in feite altijd bij, of er nu transaction statefull of stateless gewerkt wordt. Bij een volledig stateless proxy stelt dit probleem zich normaalgezien niet, daar er nergens statusinformatie wordt bijgehouden over transacties. De performantie van de applicatie, meerbepaald de responstijd en de call rate, zou dus baat hebben bij een aanpassing naar volledig stateless werken.
Aangezien het aanpassen van de proxycomponent naar een volledige stateless proxy
echter een volledig herschrijven ervan zou vereisen, werd dit door tijdsgebrek niet meer geïmplementeerd.
Wat ook bijdraagt tot dit probleem, en het probleem van het memory leak, is dat de controle over het bijhouden van deze extra informatie over actieve connecties niet bij de applicatie ligt, maar wel bij de NIST-SIP implementatie zelf. Er zijn slecht enkele parameters die kunnen aangepast worden, maar het is onmogelijk om de applicatie alle controle te geven over het al dan niet bijhouden van deze informatie. Door deze beperking is het ook nodig om ACK en BYE berichten steeds langs de proxy te sturen in plaats van point-to-point, aangezien de statusinformatie in de proxy anders niet wordt aangepast, en de proxy anders dus nooit calls als gesloten zou beschouwen (met als gevolg allerlei retransmissies, en meer resource problemen).
Verder rijst de vraag of het niet beter zou zijn om een volledig andere implementatie van SIP te gebruiken, aangezien de gebruikte open-source implementatie volgens de auteurs ervan niet gericht is op hoge performantie en throughput, maar eerder op het begrijpelijk zijn van de code. Enige aspecten van dit probleem kunnen eventueel ook veranderen bij nieuwe versies van de NIST-SIP implementatie, aangezien deze ook nog steeds onder ontwikkeling is en er geregeld nog bugs gevonden worden. Getuige hiervan ook het bemerkte geheugenlek dat bij de testen naar voren kwam, en dat ook verband houdt met het bijhouden van de transacties. (zie ook 6.1.5).
Hoofdstuk 6. Verder Werk
117
Wat hierbij zeker moet vermeld worden, is dat de tweede JAIN SIP API versie (1.2) waarschijnlijk veel van de onduidelijkheden omtrent Dialog- en Transaction-controle zal oplossen, en waardoor dus ook in de NIST implementatie ervan het resourcegebruik makkelijker te controleren zal zijn.
De laatste voorstellen voor veranderingen ([26]) zien er alleszins veelbelovend uit in dit
opzicht. Ook is er veel gewerkt rond performantieverbetering, vb. het onmiddellijk doorgeven van IOExceptions i.v.m. transacties in plaats van op TimeOutEvents geassocieerd met die transacties te wachten.
6.1.4 Notify onder Linux Verder doet er zich een bizar probleem voor onder Linux. Op sommige momenten zal een NOTIFY die aankomt in de SipStack van de SipClient geen event genereren, zodat er ook niet op kan gereageerd worden. Er zijn tests uitgevoerd om een minimale case op te stellen waarin het probleem zich voordoet. De bekomen resultaten laten echter niet toe een sluitende conclusie te trekken. Voor elk scenario waarin het probleem zich voordeed, zijn er identieke scenario's gevonden waarin het probleem zich niet voordeed. Er is wel op te merken dat bij een NOTIFY die volgt op een SUBSCRIBE dit zo goed als elke keer volledig juist afgehandeld wordt (met enkele uitzonderingen op vele tests). Merk op dat dit probleem zich niet stelt als er fetchers gebruikt worden, aangezien dan enkel nog NOTIFY berichten gestuurd die volgen op een SUBSCRIBE. Dit heeft echter wel als gevolg dat er meer netwerkverkeer gegeneerd wordt.
Wat dit probleem extra bizar maakt, is dat het zich op het Windows platform niet voordoet. Ook hierbij kunnen volgende versies van de NIST-SIP implementatie misschien verbetering brengen.
6.1.5 Proxy geheugenlek Zoals reeds vermeld in hoofdstuk 5, werd er een geheugenlek opgemerkt bij het testen van throughput van de applicatie. Om te testen of dit door ons was geïntroduceerd, werden dezelfde testen ook uitgevoerd op de proxy van NIST, waarop onze code voor die component gebaseerd is. Het bleek dat het geheugenlek ook daar aanwezig was. Na veel onderzoek bevonden we dat het geheugenlek zich voordoet doordat sommige transactie-objecten in de onderliggende NIST-SIP
Hoofdstuk 6. Verder Werk
118
implementatie blijven leven en nooit verwijderd worden uit het geheugen. Meerbepaald zouden onder meer transacties geassocieerd met een late ACK die toekomt nadat een BYE reeds ontvangen is, niet verwijderd worden. Enkele voorgestelde aanpassingen in de source code van deze bibliotheek bleken niet te helpen, waarschijnlijk omdat het geheugenlek zich verder propageert over de verschillende componenten van de bibliotheek. Zoals reeds gesteld in 6.1.3, zou het probleem zich bij een stateless proxy waarschijnlijk niet meer voordoen, aangezien daarbij helemaal geen statusinformatie wordt bijgehouden over open connecties.
6.2 Mogelijke uitbreidingen op de applicatie In deze sectie zullen enkele mogelijke uitbreidingen ter sprake gebracht worden die het systeem zouden verbeteren, maar die niet echt deel uitmaken van de basisvereisten.
6.2.1 Persistentie van subscribers In het huidige systeem worden subscribers niet persistent bijgehouden, en worden de benodigde objecten hiervoor steeds opnieuw aangemaakt door het sturen van SUBSCRIBE berichten (al dan niet met een extra BuddyXML als inhoud). Er is een uitbreiding mogelijk van het systeem van de subscribers, waarin deze ook per gebruiker persistent worden bijgehouden. Deze extra voorziening zou de oplossing van enkele problemen in de huidige applicatie vergemakkelijken. Hiermee wordt voornamelijk gedoeld op het redirecten van subscribers indien hun notier van SuperNode verandert. In het huidige systeem is ervoor gekozen om dit te doen d.m.v. het sturen van een SERVICE_UNAVAILABLE bericht naar de te redirecten subscribers, waarna deze zich na een kleine vertaging opnieuw zullen inschrijven voor de presence informatie van de notier bij diens nieuwe SuperNode, meerbepaald bij de bijhorende PA. Zie in dit verband ook 3.3.2, 4.2.4, 4.3.3 en 4.3.4.
Indien we echter de subscribers zelf persistent in een lijst zouden bijhouden voor elke gebruiker, met een analoog systeem als dat van de UserXML (of eventueel erin verweven), dan zou de oplossing van het redirecten geen actie meer vereisen van de subscribers zelf, noch zou er een extra bericht moeten gestuurd worden door de oude PA van de notier. In dat geval zou namelijk
Hoofdstuk 6. Verder Werk
119
de informatie over wie er precies ingeschreven is op wie mee verhuizen met de UserXMLs, en zou de nieuw verantwoordelijke SuperNode (via de DHT) voor een gebruiker automatisch zijn huidige subscribers kunnen inladen. Hierna zou de nieuwe PA van de notier dan een NOTIFY bericht sturen met daarin de laatste presence informatie van de notier. De subscriber merkt m.a.w. niks van het feit dat de notier geredirect is. Deze oplossing vergt uiteraard wel meer opslagruimte in de DHT, en hierdoor zal ook iets meer data over het netwerk moeten verstuurd worden bij veranderingen in het p2p netwerk.
Een bijkomend voordeel van het hierboven voorgestelde systeem is de mogelijkheid tot het bijhouden van een zogenaamde grey list.
Deze lijst bevat gebruikers die de presence van een
bepaalde gebruiker wensen te ontvangen (of ermee wensen te communiceren), maar waarvoor de bestemmeling nog geen toelating heeft gegeven. De gebruikers in de grey list moeten dan wachten tot de bestemmeling hen toelaat of blokkeert. Dit mechanisme is eigenlijk ook een uitbreiding van het gebruikersvoorkeurensysteem zoals beschreven in 3.2.1 en 3.4.4. In de geïmplementeerde applicatie wordt standaard elke gebruiker toegelaten tenzij men speciek regels instelt die dit vermijden. In het hierboven voorgestelde systeem wordt elke gebruiker standaard geweigerd, tot de gebruiker hem toelaat (wat ook als een regel kan worden gezien).
6.2.2 Security In onze informatiemaatschappij wordt beveiliging en vertrouwelijkheid van informatie steeds belangrijker.
Er zijn veel gevallen waarbij gebruikers hun communicatie geheim willen houden,
of toch zeker niet willen dat derden hun communicatie kunnen auisteren (denken we bijvoorbeeld maar aan industriële spionage en elektronische identiteitsdiefstal die de laatste jaren steeds meer toenemen). Om aan deze extra eisen in verband met communicatie te voldoen, zal extra ondersteuning moeten worden voorzien. De fundamentele security services nodig voor SIP zijn: behoud van de geheimhouding en integriteit van de communicatie, replay aanvallen en spoong tegengaan, in staan voor de authenticatie en de privacy van de partijen in de communicatie, en het tegengaan van Denial of Service (DoS) aanvallen. SIP voorziet verscheidene beveiligingsmechanismen voor hop-by-hop en end-to-end encryptering van bepaalde veiligheids/privacy gevoelige header velden en van de inhoud. Sommige mechanis-
Hoofdstuk 6. Verder Werk
120
men zijn ingebouwd in het protocol, zoals vb. verschillende variaties van HTTP autenticatie of secure attachments. De transport- of netwerklaagbeveiliging kan het SIP verkeer ook encrypteren, en garandeert op die manier beveiliging en integriteit. IP security (IPSec) is een populair netwerk-beveiligingsmechanisme dat beveiliging biedt op het niveau van de transportlaag.
In een SIP netwerk, kan de autenticatie plaats vinden tussen een UA en een proxy, waarbij de proxy verwacht dat een UA zich authenticeert voordat een request behandeld wordt. Op dezelfde wijze kan een UA ook authenticatie vragen van een proxy. SIP voorziet hiervoor verschillende headers, waarvan de Authorization-header er een van is.
Om de RTP communicatie te beveiligen kan er ook versleuteling gebruikt worden op de RTP data-stroom.
Voor meer informatie omtrent deze aspecten van SIP kan men altijd terecht bij [27] en [28].
6.2.3 Firewall/NAT-Traversal SIP kan met enkele aandachtspunten ook gebruikt worden met een rewall of een NAT (Network Address Translation).
RTP echter heeft een groter probleem:
het source adres in het SDP
pakket dat onderhandelt over het formaat van de audio sessie zal een intern adres zijn, en niet het publieke adres van de NAT-router.
Er zijn verschillende opties voor de oplossing van dit
probleem:
•
relay-node
•
STUN-TURN
Bij het relay-node mechanisme wordt een node die niet zal deelnemen in de RTP sessie als een hulpnode gebruikt om het publieke IP van de node achter het NAT te weten te komen. Op die manier kan de juiste parameter ingevuld worden in het SDP pakket. Deze relay-node wordt ook wel een third-party call controller genoemd (3PCC).
Hoofdstuk 6. Verder Werk
121
Het Simple Traversal of UDP Through Network Address Translators (STUN) protocol laat een SIP client toe te ontdekken of hij al dan niet achter een NAT zit, en indien dat zo is, achter welk type NAT. STUN heeft al veel aandacht gekregen van de IETF, maar het heeft ook een tekortkoming. Hiermee wordt bedoeld dat STUN maar met bepaalde types van NAT overweg kan. Het is zelfs zo dat STUN niet overweg kan met het meest voorkomende type van NAT in een corporate netwerk, nl. symmetrische NAT. De IETF heeft echter een ander mechanisme voorgesteld, Traversal Using Relay NAT (TURN), dat ontworpen is om het probleem bij symmetrische NAT op te lossen.
Zie in dit verband ook [27], [28], [29] en [30].
6.2.4 Authenticatieservice Een met security verwant probleem is dat van authenticatie: gebruikers willen zeker zijn van elkanders echtheid, d.i. dat de andere partij gegarandeerd is wie hij of zij zegt te zijn. Om deze eis in te willigen, kan er gewerkt worden met een authenticatie service, aangeboden door een vertrouwde entiteit, die centraal loopt op het netwerk, aangezien distributie hiervan risico's qua beveiliging inhoudt.
RSA of een ander public key algoritme kan hier eventueel gebruikt
worden. RSA vraagt natuurlijk wel wat rekenkracht, dus misschien is dit niet aangewezen voor thin clients (vb. een gsm).
Een andere optie voor authenticatie is om elke gebruiker die het netwerk wil gebruiken, eerst enkele gegevens zoals gebruikersnaam en e-mail te laten ingeven via een webservice op de authenticatieserver. Eens ingevuld stuurt de server naar het ingegeven e-mailadres een mail met daarin een registratiecode/paswoord.
Enkel met die code kan de gebruiker dan inloggen.
De
code kan uiteraard ook aangepast worden door de gebruiker nadat de registratie in orde is.
De authenticatie service kan bijvoorbeeld gedraaid worden op de bootstrap SuperNode. Op die manier zou de verantwoordelijke proxy voor een gebruiker ook direct meegegeven kunnen worden wanneer de gebruiker in het systeem inlogt.
Hoofdstuk 6. Verder Werk
122
6.2.5 Caching Om de bootstrap SuperNode wat van zijn belangrijke taak te ontlasten zou men ook een systeem van caching kunnen toevoegen waarbij een Node de adressen van enkele SuperNodes lokaal cacht zodat niet elke keer naar de bootstrap SuperNode moet gegaan worden om in te (opnieuw) loggen in het netwerk. Aangezien een SuperNode een vrij grote beschikbaarheid zou moeten hebben, zal er zo goed als zeker een beschikbare SuperNode tussen de gecachete SuperNodes zitten. Op deze manier zou men de afhankelijkheid van de bootstrap SuperNode, die nu de enige component vormt die niet oine mag gaan, fel kunnen verminderen. Verder zou deze caching kunnen voortbouwen op de routeertabel gehanteerd door de DHT, aangezien deze sowieso consistent gehouden wordt bij joins en leaves in het p2p netwerk.
6.2.6 Automatisch starten van een SuperNode In het systeem zoals het nu is, wordt een SuperNode handmatig gestart en gestopt door een gebruiker.
Het zou echter mogelijk moeten zijn om dit op een automatische manier te laten
gebeuren. Hiervoor zouden dan parameters omtrent de specicatie van de machine waarop de applicatie draait, gebruikt kunnen worden om te kijken of een machine over genoeg troeven beschikt om een SuperNode te kunnen draaien.
We denken hierbij bijvoorbeeld aan proces-
sorsnelheid, een goede hoeveelheid geheugen, en een snelle netwerktoegang. Er kan evenwel nog steeds een functie ingebouwd worden waarbij de gebruiker nog steeds het laatste woord heeft over het al dan niet draaien van een SuperNode op het systeem.
6.2.7 Echo cancellation Bij het opzetten van een VoIP gesprek door middel van RTP, is er in de ontwikkelde applicatie wel wat echo te horen. Hieronder verstaan we dat een gebruiker zijn eigen stem met enige vertraging kan horen als hij een andere gebruiker belt, en dit doordat het outputsignaal bij de ontvangende gebruiker samengevoegd wordt met zijn eigen inputsignaal, wat dus een echo-eect genereert. De gebruikelijke techniek uit traditionele telefonie om dit probleem te verhelpen, wordt echo cancellation genoemd. Er bestaan reeds enkele gelijkaardige technieken die speciek voor VoIP ontworpen zijn.(zie [31])
Hoofdstuk 7
Conclusie Vooraleer de conclusies aan te vatten, zullen de doelstellingen van deze scriptie nog eens opgefrist worden. Er werd vooropgesteld om een prototype voor een p2p-gebaseerde multimedia applicatie met ondersteuning voor presence te ontwerpen en implementeren. Deze applicatie moet in staat zijn om onderstaande features aan te bieden.
Gebruikers moeten in staat zijn andere gebruikers uit te nodigen tot een multimediasessie. De presence informatie van andere gebruikers moet kunnen opgevraagd worden en de eigen presence moet kunnen aangeboden worden aan andere gebruikers.
Gebruikersvoorkeuren die aangeven
wanneer en door welke (groepen van) gebruiker(s) men al dan niet wil kunnen bereikt worden, moeten kunnen gedeniëerd worden. Deze voorkeuren moeten afgedwongen worden, en dienen persistent te worden bijgehouden in het netwerk, evenals een lijst van contactpersonen. Dit alles moet aangeboden worden op een betrouwbare manier (m.a.w. het systeem dient bestand te zijn tegen veranderingen in het p2p netwerk).
Nu zullen deze doelstellingen achtereenvolgens bekeken worden, en zal nagegaan worden in hoeverre de geïmplementeerde applicatie aan deze punten beantwoordt. licht geworpen worden op de testresultaten uit hoofdstuk 5.
123
Daarna zal ook nog een
Hoofdstuk 7. Conclusie
124
7.1 Toetsen van de applicatie aan de opgegeven doelstellingen Er werd eerst en vooral voor gezorgd dat gebruikers met elkaar een multimediasessie kunnen opzetten met behulp van SIP en RTP. Hiervoor werd een volledig werkend systeem op poten gezet. Hierbij moet wel opgemerkt worden dat er wel wat echo en vertraging op het eigenlijke geluidssignaal zit, maar aangezien de focus van deze scriptie niet op de (geluids)kwaliteit van de communicatie ligt, werd daar verder geen aandacht aan besteed.
Gebruikers zijn ook in staat om elkaars presence informatie op te vragen. Hiervoor werd dus ook een werkend systeem geïmplementeerd, op een klein detail na (zie 6.1.4).
De gebruikersvoorkeuren werden ook volledig geïmplementeerd en dit deelsysteem werkt zoals het zou moeten.
Gebruikers worden altijd op het juiste moment toegelaten of geblokkeerd.
Voorkeuren worden ook persistent bijgehouden, zodat gebruikers de volgende keer ze inloggen nog altijd over dezelfde voorkeuren beschikken. Er is nog een kleine verbetering aan het voorkeurensysteem mogelijk, zoals beschreven in 6.1.1.
Voor elke gebruiker wordt persistent een lijst met contactpersonen bijgehouden (de Buddy List), en dit met behulp van de UserXML. De contactpersonen kunnen ook in groepen worden onderverdeeld. Dit gedeelte werkt ook volledig zoals het hoort.
Het geheel is bestand gemaakt tegen veranderingen in het p2p netwerk. Er kan echter wel een klein inconsistentie-interval optreden wanneer een subscriber moet op de hoogte gebracht worden van het feit dat zijn notier geredirect is naar een andere SuperNode. De inconsistentie zal na een tijdje zichzelf oplossen, en de gebruiker zal opnieuw de juiste presence informatie te zien krijgen. Er zal echter nooit een UserXML verloren gaan zolang de replicatiefactor voor de DHT voldoende hoog gekozen wordt. Het enige zwakkere punt in het p2p netwerk is de bootstrap SuperNode, maar dit kan verbeterd worden d.m.v. caching.
Hoofdstuk 7. Conclusie
125
7.2 Conclusies getrokken uit de behaalde testresultaten Uit de testresultaten kunnen enkele conclusies getrokken worden, te beginnen met de optimale waarde voor de call rate. Er dient hier eerst opgemerkt te worden dat de call rate voor een bepaalde SuperNode in de eerste plaats afhankelijk zal zijn van de verhouding tussen het aantal Nodes en het aantal SuperNodes en dit dus geen parameter is die ingesteld kan worden. In dat opzicht dienen de voorgestelde waarden geïnterpreteerd te worden als een indicatie voor een verdeling de calls over het aantal SuperNodes, zodanig dat geen enkele SuperNode in het netwerk de aangegeven waarde voor de call rate overschrijdt.
Deze verdeling hangt uiteraard af de verdeling van Nodes over de aan-
wezige SuperNodes.
Voor de call rate kunnen we een onderscheid maken tussen een focus op een grote throughput en een focus op een zo laag mogelijke responstijd.
Kiest men voor het eerste, dan is een waarde van 15 CAPS het maximum voor een goede throughput met een aanvaardbare respons- en call-setuptijd. Dit komt overeen met de de maximale throughput die de hoofdontwikkelaar van NIST-SIP vooropstelt voor machines met één processor. Opteert men eerder voor een zo laag mogelijke responstijd, dan neemt men beter een lagere call rate, waarbij 5 CAPS de beste resultaten geeft. Aangezien de processor hierbij onderbenut wordt, is dit echter ook niet optimaal te noemen. Ook is 5 CAPS vrij weinig voor een VoIP-applicatie. Kiest men voor de gulden middenweg, dan kunnen call rates van 7 tot 12 CAPS genomen worden, afhankelijk van welk van de 2 aspecten het belangrijkst wordt geacht.
Indien men het falen van calls, veroorzaakt door pakketverlies, wil minimaliseren, dan kan men best een call rate lager dan 15 CAPS gebruiken, en retransmissies aanzetten.
Het ver-
lies van berichten wordt hiermee drastisch verkleind, maar dit gaat ten koste van de responstijd. Aangezien bij hogere call rates de responstijd al vrij hoog ligt, neemt men in dit geval best een call rate van 10 CAPS. Er zullen dan zo goed als geen calls verloren gaan terwijl de responstijd binnen aanvaardbare grenzen blijft.
Hoofdstuk 7. Conclusie
126
Verder stellen we ook vast dat over het algemeen responstijden verbeteren wanneer de garbage collector van Java getuned wordt zoals beschreven in 5.3, en raden we dus aan deze parameters steeds te gebruiken. Hierbij moet echter wel vermeld worden dat deze parameters voor elke conguratie apart moeten bekeken worden om optimale waarden te bekomen voor het gehele systeem.
Met betrekking tot de impact van de DHT op de performantie van de applicatie kon geen sluitende conclusie getrokken worden uit de bekomen testwaarden. Om dit aspect van de ontwikkelde applicatie na te gaan zijn verdere testen nodig die vrij complex zijn, en ook praktisch moeilijk haalbaar.
7.3 Algemene conclusie We kunnen stellen dat in deze scriptie een architectuur werd voorgesteld die aan de doelstellingen tegemoet komt.
Deze architectuur werd geïmplementeerd in een werkende applicatie, die
behoudens enkele kleine aandachtspunten inzetbaar is op het Internet. Uiteraard is de geïmplementeerde applicatie hiervoor slechts een prototype, waar verder aan moet ontwikkeld worden om tot een echt gebruiksvriendelijk programma te komen. Hiervoor is de basis echter zeker gelegd.
Met de ontwikkelde applicatie achten we de mogelijkheid bewezen om een volledig gedistribueerd systeem met ondersteuning voor presence informatie en extra gebruikersvoorkeuren te ontwikkelen aan de hand van bestaande standaarden. Hierbij wensen we te benadrukken dat de focus niet ligt op de performantie, maar dat het systeem desalniettemin een behoorlijke belasting aankan.
B¼lage A
Legende bij UML Diagrammen Uses Implements Extends <>
Class
Figuur A.1: Legende die bij de UML diagrammen uit hoofdstuk 4 hoort.
127
B¼lage B
SIP ow voor enkele SIP berichten B.1 REGISTER Proxy
Alice
REGI
STER
OK
Figuur B.1: SIP ow voor een REGISTER bericht
128
B¼lage B. SIP ow voor enkele SIP berichten
129
B.2 INVITE Proxy
Alice
Bob
INVI
TE INVI
ING
TE
TRY
G
GIN
RIN
OK G GIN
RIN
OK
ACK
Figuur B.2: SIP ow voor een INVITE bericht
B.3 BYE Bob
Alice
BYE
OK
Figuur B.3: SIP ow voor een BYE bericht
B¼lage B. SIP ow voor enkele SIP berichten
130
B.4 SUBSCRIBE PA
Alice
SUBS
CRIB
E
OK
NOT
IFY
OK
Figuur B.4: SIP ow voor een SUBSCRIBE bericht
B.5 PUBLISH PA
Alice
Subscriber
PUBL
ISH
OK
NOTI
FY
OK
Figuur B.5: SIP ow voor een PUBLISH bericht
B¼lage C
Layout van de bijgevoegde CD-ROM De mapstructuur van de CD-ROM is te zien op guur C.1.
In de map boek zijn de bestanden te vinden die gebruikt zijn voor dit manuscript. De oorspronkelijke guren, gemaakt met SmartDraw 7, zijn terug te vinden in de submap smartDrawFiguren. In omgezette vorm (veelal pdf-formaat) zijn ze te vinden in de g submap, die alle gebruikte
A
guren uit dit document bevat. De bronbestanden voor dit manuscript in L TEX en dit manuscript zelf in pdf formaat, evenals die voor het extended abstract, zijn ook terug te vinden is de map boek.
In de map presentatie zijn alle bestanden te vinden die gebruikt werden bij de verdediging van deze scriptie.
In de map Skaaip_beta vindt men het eigenlijke programma. In de hoofdmap staan de batch, voor Windows, en het script, voor Linux, waarmee het programma kan worden opgestart. De uitvoerbare code in de vorm van .class bestanden zijn terug te vinden in de bin submap, die ook nog enkele hulpbestanden bevat zoals een java.policy bestand dat benodigd is voor de Java security manager. De bytecode is uiteraard in dezelfde package structuur onderverdeeld als beschreven in bovenstaande tekst. In de submap conguration vindt men de conguratiebestanden die in appendix D worden beschreven, en de lib submap bevat alle nodige bibliotheken voor het compileren en uitvoeren van het programma, in de vorm van .jar bestanden. Indien logging wordt aangezet, dan zal men
131
B¼lage C. Layout van de bijgevoegde CD-ROM
132
na uitvoeren van het programma diverse logbestanden terugvinden in de log submap. De Java broncode voor het programma is bevat in de submap src, die uiteraard ook de beschreven onderverdeling in packages vertoont. In de users submap tenslotte kan men de UserXML-bestanden vinden waarmee de gebruikers van het systeem kunnen worden ingesteld. Deze gebruikers zullen in de bootstrap SuperNode worden ingeladen. In deze map is ook nog een submap dht te vinden, waar de dht component van de SuperNode de bestanden zal opslaan waar die verantwoordelijk voor is (in een gegenereerde storage submap).
Het programma werd (voornamelijk) ontwikkeld met het Eclipse platform, onder Java JDK 1.5.0_06.
In de map test tenslotte kan men de gebruikte bestanden van onze testen terugvinden.
Deze
omvatten het installatiebestand van SIPp (voor Linux), de aangepaste SIPp scenario XML- en inputbestanden, evenals alle bekomen waarden uit de nale tests, in .csv formaat. Verder moet opgemerkt worden dat voor enkele testen de broncode is aangepast. Dit was bijvoorbeeld het geval om de UAS die gesimuleerd wordt door een SIPp scenario statisch te registeren met een correcte contactURI in de proxy, en om optimalisaties van de garbage collector aan te passen of weg te laten. Uiteraard werden er bij deze kleine aanpassingen geen functionele veranderingen doorgevoerd.
B¼lage C. Layout van de bijgevoegde CD-ROM
Root | +--| | | | +--| +--| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | +---
Boek +--- fig +--- smartdrawFiguren +--- texfiles van het boek + boek.pdf Presentatie Skaaip_beta +--- bin | +--- node | | +--- gui | | +--- media | | +--- sip | | +--- pidf | +--- supernode | | +--- dht | | +--- proxy | | +--- presenceserver | | +--- registrar | +--- java.policy file | +--- configuration +--- lib +--- log +--- src | +--- node | | +--- gui | | +--- media | | +--- sip | | +--- pidf | +--- supernode | | +--- dht | | +--- proxy | | +--- presenceserver | | +--- registrar +--- users | +--- dht | +--- skaaip.bat (batch voor Windows) +--- skaaip (opstartscript voor Linux) tests
Figuur C.1: Layout van de bijgevoegde CD-ROM
133
B¼lage D
Opmerkingen in verband met het opstarten van het programma D.1 Conguratiebestanden De conguratiebestanden in de map conguration bieden de mogelijkheid diverse instellingen aan te passen alvorens men het programma opstart.
D.1.1 Conguratiebestanden voor de Node clientCong.xml De volgende parameters kunnen ingevuld worden :
•
stack_name : dit speciëert de naam van de SipStack van de Node, dit heeft echter geen invloed op de werking van het programma, maar is verplicht door de NIST-SIP implementatie. Default waarde is client.thesis.test.
•
outbound_proxy : hier kan het IP-adres van de proxy ingesteld worden. Deze waarde wordt echter automatisch ingevuld wanneer men inlogt met het programma (hiervoor dient wel de bootstrap SuperNode te lopen, en ingesteld te zijn in de dhtCong.xml).
•
proxy_port en proxy_protocol : speciëren de poort en het protocol van de proxy. Deze parameters worden ook automatisch ingevuld als men inlogt.
134
B¼lage D. Opmerkingen in verband met het opstarten van het programma
•
135
port en protocol : deze parameters geven de poort en het eigen protocol aan waarmee de SipStack van deze Node zal werken. De gebruiker dient een vrije poort op te geven, en het protocol dient ofwel UDP ofwel TCP te zijn. Default is poort 5060 over UDP.
•
subscription_refresh_rate : geeft het interval aan (in seconden) waarin een inschrijving van deze client voor presence informatie geldig blijft, m.a.w. om de zoveel tijd zal de inschrijving ververst worden door een SUBSCRIBE bericht.
Indien hier 0 wordt ingegeven, zal het
systeem van de fetchers gebruikt worden. Default wordt deze manier van inschrijven voor presence gebruikt, en default waarde is 600, dus om de 10 minuten wordt de inschrijving ververst.
•
fetch_interval : indien de subscription_refresh_rate op 0 staat, zal presence informatie opgevraagd worden door middel van fetchers. Deze fetchers maken geen echte inschrijving aan op de PA van de notier, maar krijgen wel een NOTIFY terug van die PA. De waarde voor fetch_interval geeft aan om de hoeveel tijd zo'n fetcher zal gestuurd worden voor elke actuele inschrijving. Deze parameter mag niet tegelijk met de subscription_refresh_rate gelijk zijn aan 0. Default waarde is 300, dus om de 5 minuten wordt de presence informatie opgevraagd.
D.1.2 Conguratiebestanden voor de SuperNode dhtCong.xml De parameters zijn de volgende :
•
node_IP : het IP-adres van de host waarop deze SuperNode draait, dit zal automatisch juist ingevuld worden.
•
node_bindport : de poort die de DHT-component van de SuperNode zal gebruiken voor de communicatie met de andere DHT-nodes.
Dit is standaard 5009, de standaardpoort
waarop BunshinDHT werkt, maar kan door de gebruiker aangepast worden.
•
isBootstrap : geeft aan of de SuperNode als bootstrap zal fungeren of niet (deze parameter kan ook aangepast worden a.d.h.v. de initiële GUI). Hierdoor wordt een nieuwe DHT ring door deze SuperNode opgestart, waarin alle UserXMLs uit de users map worden ingeladen. Uiteraard is het aangeraden nooit meer dan één SuperNode als bootstrap van het netwerk
B¼lage D. Opmerkingen in verband met het opstarten van het programma
136
te congureren, aangezien dan 2 gescheiden netwerken zouden bestaan die van elkaars bestaan niet afweten, maar wel dezelfde bestanden beheren en dus voor dezelfde gebruikers zouden instaan.
•
bootstrap_IP en bootstrap_port : geven het IP-adres en de poort van (de DHT-component van) de bootstrap SuperNode aan. Een opstartende SuperNode zal proberen deze bootstrap te contacteren en zo het p2p netwerk proberen te vervoegen (indien er bij isBootstrap de waarde false is ingegeven).
Indien de bootstrap SuperNode niet gevonden wordt, zal de
SuperNode een eigen DHT ring starten (merk op : aangezien de waarde voor isBootstrap false is, zullen er geen UserXMLs ingeladen worden in de DHT).
•
replication_factor : bijgehouden worden.
stelt in hoeveel replica's er van elke UserXML in de DHT moeten Default is 1, maar voor grotere netwerken moet deze parameter
groter gekozen worden om consistentie te garanderen.
•
refresh_time : stelt de refresh time van de dht in, die aangeeft om de hoeveel tijd het p2p netwerk zal worden onderzocht op consistentie en indien nodig geüpdatet zal worden. Wordt uitgedrukt in seconden, default is 20.
proxyCong.xml Voor de SIP-Proxy kunnen volgende parameters worden ingesteld :
•
stack_name : zet de naam van de SipStack van de proxy van deze SuperNode, dit heeft geen invloed van de werking van het programma, maar is verplicht door de NIST-SIP implementatie. Default waarde is proxy.thesis.test.
•
stack_IP_address : het IP-adres van de proxy, zal automatisch juist gezet worden wanneer de proxy start.
•
max_connections : het maximale aantal connecties dat de proxy op een gegeven moment mag onderhouden.
•
max_server_transactions : het maximale aantal servertransacties dat de proxy mag onderhouden.
•
thread_pool_size : de grootte van de threadpool in de proxy.
B¼lage D. Opmerkingen in verband met het opstarten van het programma
•
137
Listening_Point port en transport : de poort en het protocol waarop een Listening Point van de proxy zal luisteren naar inkomende berichten. Er zullen meestal meerdere van deze luisterpunten zijn, typisch één voor UDP en één voor TCP op dezelfde poort.
Default
waarde voor de poort is 4000.
•
domain :
het domein waarvoor de proxy verantwoordelijk zal zijn.
In deze applicatie
moeten alle proxies verantwoordelijk zijn voor dezelfde domeinen (namelijk die domeinen waarvoor de gebruikers worden bijgehouden). Default is 1 domein, nl. thesis.test.
•
expires_time : maximale tijd voor een registratie verwijderd wordt indien niet geüpdatet.
•
enable : zet de presence server aan of uit. Hier dient deze altijd aan te staan.
Zoals aangegeven in hoofdstuk 5, is het van belang dat de waarden voor max_connections, max_server_transactions en thread_pool_size voor het halen van hoge performantie goed gekozen worden, afhankelijk van het systeem waarop men de SuperNode draait. Default waarden (uit onze tests) zijn respectievelijk 2000, 2000 en 256.
superNodeCong.xml Er is slechts één parameter, en deze is :
•
superNodeRMIControllerBinding : zet de RMI binding voor de SuperNodeController (deze zal indien nodig aangepast worden door de applicatie zelf ).
D.2 Opstarten van het programma Het programma wordt opgestart door in de hoofdmap van het programma de batch skaaip.bat (onder Windows) of het script skaaip (onder Linux) uit te voeren. In beide scripts moet niks aangepast worden, zolang men de mapstructuur behoudt zoals ze is. Vooraleer men met een gebruiker kan inloggen, dient men er zich van te verzekeren dat er een bootstrap SuperNode draait op het aangegeven bootadres, de gebruiker zal immers het adres van zijn verantwoordelijke proxy opvragen bij de bootstrap. Uiteraard dient ook voor alle gebruikers
B¼lage D. Opmerkingen in verband met het opstarten van het programma
138
van het systeem een UserXML te zijn voorzien in de users map van de bootstrap SuperNode. Verder dient men ervoor te zorgen dat er geen poortconicten zijn door componenten die dezelfde poort gebruiken. Met de standaard ingestelde parameters zal dit echter niet het geval zijn. Uiteraard moet hieraan extra aandacht geschonken worden indien meer dan één instantie van het programma op dezelfde host wordt uitgevoerd, aangezien dan alle poorten moeten aangepast worden voor elk bijkomend programma.
Bibliograe [1] Skype. The whole world can talk for free http://www.skype.com/
[2] P2P SIP http://www.p2psip.org/
[3] J. Rosenberg, H. Schulzrinne, G. Camarillo, A. Johnston, J. Peterson, R. Sparks, M. Handley, E. Schooler, SIP: Session Initiation Protocol, RFC 3261, Internet Engineering Task Force, June 2002 http://www.ietf.org/rfc/rfc3261.txt
[4] A. B. Roach,
Session Initiation Protocol (SIP)-Specic Event Notication, RFC 3265,
Internet Engineering Task Force, June 2002 http://www.ietf.org/rfc/rfc3265.txt
[5] A. Niemi, Ed., Session Initiation Protocol (SIP) Extension for Event State Publication, RFC 3903, Internet Engineering Task Force October 2004, http://www.ietf.org/rfc/rfc3903.txt
[6] J. Rosenberg, A Presence Event Package for the Session Initiation Protocol (SIP), RFC 3856, Internet Engineering Task Force, August 2004 http://www.ietf.org/rfc/rfc3856.txt
[7] M. Handley, V. Jacobson, SDP: Session Description Protocol, RFC 2327, Internet Engineering Task Force, April 1998 http://www.ietf.org/rfc/rfc2327.txt
139
Bibliograe
140
[8] H. Schulzrinne, S. Casner, R. Frederick, V. Jacobson, RTP: A Transport Protocol for RealTime Applications, RFC 1889, Internet Engineering Task Force, January 1996 http://www.ietf.org/rfc/rfc1889.txt
[9] H. Sugano, S. Fujimoto, G. Klyne, A. Bateman, W. Carr, J. Peterson, Presence Information Data Format (PIDF), RFC 3863, Internet Engineering Task Force, August 2004 http://www.ietf.org/rfc/rfc3863.txt
[10] H. Schulzrinne, V. Gurbani, P. Kyzivat, J. Rosenberg, RPID - Rich Presence Information Data Format, draft-ietf-simple-rpid-01, Internet Engineering Task Force, February 9, 2004 http://xml.coverpages.org/draft-ietf-simple-rpid-01.txt
[11] A. Rowstron, P. Druschel,
Pastry: Scalable, distributed object location and routing for
large-scale peer-to-peer systems, IFIP/ACM International Conference on Distributed Systems Platforms (Middleware), Heidelberg, Germany, pages 329-350, November, 2001 http://freepastry.org/PAST/pastry.pdf
[12] I. Stoica, R. Morris, D. Karger, M. F. Kaashoek, H. Balakrishnan, Chord: A Scalable Peerto-peer Lookup Service for Internet Applications, To Appear in IEEE/ACM Transactions on Networking http://pdos.csail.mit.edu/papers/chord:sigcomm01/chord_sigcomm.pdf
[13] NIST SIP IP Telephony http://snad.ncsl.nist.gov/proj/iptel/
[14] Java Media Framework http://java.sun.com/products/java-media/jmf/
[15] Java Distributed Hash Table http://dks.sics.se/jdht/
[16] The Bamboo Distributed Hash Table A Robust, Open-Source DHT http://bamboo-dht.org/
[17] PAST:A large-scale, peer-to-peer archival storage facility http://research.microsoft.com/%7Eantr/PAST/
[18] R. Mondéjar, P. García, C. Pairot, Bunshin: DHT for distributed applications, XIII Jornadas de Concurrencia y Sistemas Distribuidos (JCSD), I Congreso Español de Informática
Bibliograe
141
(CEDI 2005), Granada, Spain, September 2005 http://planet.urv.es/bunshin/papers/Bunshin_CEDI2005_Translation.pdf
[19] JDOM: a complete, Java-based solution for accessing, manipulating, and outputting XML data from Java code http://www.jdom.org/
[20] Java Remote Method Invocation (RMI) http://java.sun.com/products/jdk/rmi/
[21] A. Wollrath, J. Waldo, Java Remote Method Invocation tutorial http://java.sun.com/docs/books/tutorial/rmi/index.html
[22] Code Sample : Receiving Audio and Video using RTP http://java.sun.com/products/java-media/jmf/2.1.1/solutions/AVReceive.html
[23] Code Sample : Transmitting Audio and Video using RTP http://java.sun.com/products/java-media/jmf/2.1.1/solutions/AVTransmit.html
[24] O. Jacques, SIPp : a free Open Source test tool / trac generator for the SIP protocol http://sipp.sourceforge.net/
[25] B. Van Den Bossche, F. De Turck, P. Demeester, B. Dhoedt, Enabling Java-based VoIP backend platforms through JVM performance tuning, published in VoIP Mase '06 workshop, IEEE Catalog Number 06EX1301, March 2005 http://dev2dev.bea.com/pub/a/2006/05/voip-jvm-tuning.html
[26] Proposed changes for JSR32 : Change-Log for JSIP v1.2 http://jcp.org/aboutJava/communityprocess/maintenance/jsr032/32changelog.html
[27] Security in SIP-Based Networks http://www.cisco.com/warp/public/cc/techno/tyvdve/sip/prodlit/sipsc_wp.pdf
[28] SIP, Security and Session Controllers http://www.newport-networks.com/whitepapers/security1.html
[29] NAT Traversal for Multimedia over IP http://www.newport-networks.com/cust-docs/33-NAT-Traversal.pdf
Bibliograe
142
[30] D. Schwartz, B. Sterman, Ph.D.,
NAT Traversal in SIP, Kayote Networks, September
2005 http://www.kayote.com/web/docs/WhitePapers/KayoteNetworksWhitePaperNAT_Traversal_in_SIP.pdf
[31] J. C. Gammel, Echo Cancellation for VoIP http://www.commsdesign.com/main/1999/10/9910feat4.htm
[32] J. Peterson, Common Prole for Presence (CPP), RFC 3859, Internet Engineering Task Force, August 2004 http://www.ietf.org/rfc/rfc3859.txt
[33] D. Bryan, C. Jennings,
A P2P Approach to SIP Registration and Resource Location,
draft-bryan-sipping-p2p-01, Internet Engineering Task Force, July 15, 2005 http://www.p2psip.org/drafts/draft-bryan-sipping-p2p-01.html
[34] Java Media Framework API Guide, JMF 2.0 FCS, November 19, 1999
[35] K. Singh, H. Schulzrinne,
Peer-to-peer Internet Telephony using SIP, Department of
Computer Science, Columbia University,
[36] D. A. Bryan, B. B. Lowekamp,
{kns10,hgs}@cs.columbia.edu
SOSIMPLE : A SIP/SIMPLE Based P2P VoIP and IM
System, Computer Science Department, College of William and Mary, Williamsburg, VA 23185,
{bryan,
lowekamp}@cs.wm.edu
[37] S. A. Baset, H. Schulzrinne,
An Analysis of the Skype Peer-to-peer Internet Telephony
Protocol, Department of Computer Science, Columbia University, New York NY 10027,
{salman,hgs}@cs.columbia.edu [38] J. Walkerdine, L. Melville, I. Sommerville, Designing for Presence within P2P Systems, Computing Department, Lancaster University, Lancaster, UK, @comp.lancs.ac.uk
[39] JSR 32: JAINTM SIP API Specication http://www.jcp.org/en/jsr/detail?id=32
[40] J. Janak, SIP Introduction, FhG FOKUS, 2003 http://www.iptel.org/ser/doc/sip_intro/sip_introduction.html
{walkerdi,
l.melville, is}
Bibliograe
143
[41] B. Campbell, S. Olson, J. Peterson, J. Rosenberg, B. Stucker, SIMPLE Presence Publication Mechanism, draft-ietf-simple-publish-00, Internet Engineering Task Force, February 24, 2003 http://www3.ietf.org/proceedings/03mar/I-D/draft-ietf-simple-publish-00.txt
[42] Peer-to-peer Internet telephony using SIP http://www1.cs.columbia.edu/ kns10/research/p2p-sip/
[43] M. Castro, M. Costa, A-M. Kermarrec, A. Rowstron, P. Druschel, A. Haeberlen, J. Hoye, S. Iyer, A. Mislove, A. Nandi, A. Post, A. Singh, D. Wallach, Y. C. Hu, M. Jones, M. Theimer, A. Wolman, R. Mahajan, Pastry A scalable, decentralized, self-orngaizing and fault-tolerant substrate for peer-to-peer applications http://freepastry.org/
[44] J. Hoye,
The FreePastry Tutorial, Version 1.3, For FreePastry version 1.4.2, August 1,
2005 http://freepastry.org/FreePastry/tutorial/
[45] JAVA API for SIP Signalling https://jain-sip.dev.java.net/
[46] Session Initiation Protocol (SIP) Working Group Supplemental Home Page http://www.softarmor.com/sipwg/
[47] P. E. Jones, SIP Standards http://www.packetizer.com/voip/sip/standards.html
[48] M. C. Daconta, When Runtime.exec() won't http://www.javaworld.com/javaworld/jw-12-2000/jw-1229-traps.html
[49] VoIP Foro SIP Architecture, RTP/RTPC and SDP http://www.en.voipforo.com/SIP/SIP_architecture.php
[50] A. Ahmed, G. Kawaguchi, S. Tokuno, S. Okumura, A guideline on message headers and URI in SIP/SIMPLE framework, draft-ashir-simple-message-guideline-00, Internet Engineering Task Force, February 9, 2004 http://www.softarmor.com/wgdb/docs/draft-ashir-simple-message-guideline-00.txt