-
Notifications
You must be signed in to change notification settings - Fork 0
/
php-lecture.tex
83 lines (67 loc) · 6.51 KB
/
php-lecture.tex
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
\subsection{Lecture du journal créé par \frad}
\subsubsection{Accès au journal}
Les fichiers constituant le journal que crée {\frad} sont situés dans le dossier \texttt{/var/log/freeradius/radacct/127.0.0.1}. Un fichier est créé pour chaque jour d’activité, son nom étant de la forme \texttt{detail-aaaammjj} où \texttt{a}, \texttt{m} et \texttt{j} représentent les chiffres de l’année, du mois et du jour du mois.
Lors de l’installation, tous ces fichiers sont accessibles uniquement à \texttt{root}. Nous avons dans un premier temps modifié le groupe des répertoires pour permettre au démon HTTP d’accéder aux fichiers et nous avons configuré le dernier répertoire en mode \texttt{setgid} afin que les nouveaux fichiers héritent du bon groupe.
Cependant cette configuration n’a pas été suffisante, car {\frad} créer les fichiers avec des droits de lecture uniquement pour l’utilisateur propriétaire. Afin de nous concentrer sur le cœur du projet, nous nous sommes contentés d’une solution simple, consistant à ajouter un job dans la \texttt{crontab} donnant régulièrement les droits au démon HTTP sur les fichiers nouvellement créés.
Pour notre confort pendant le travail, nous avons choisi une fréquence relativement élevée, mais une fréquence nettement plus faible — le premier du mois par exemple — serait suffisante sur un serveur en production et représente une charge négligeable pour le système. Cependant il aurait pu être intéressant de configurer ce comportement directement dans {\frad} ou de l’intégrer dans un script de déplacement des fichiers (permettant leur classement et donc une meilleure lisibilité, le répertoire pouvant se remplir vite avec un fichier par jour).
\subsubsection{Format du journal}
\begin{figure}[h!]
\begin{verbatim}
Mon Jan 19 10:52:26 2015
Acct-Status-Type = Start
Service-Type = SIP
Sip-Response-Code = 200
Sip-Method = Invite
Event-Timestamp = "Jan 19 2015 10:52:26 CET"
Sip-From-Tag = "1514023998"
Sip-To-Tag = "DbEJdfR"
Acct-Session-Id = "48771904"
Calling-Station-Id = "sip:[email protected]"
Called-Station-Id = "sip:[email protected]"
NAS-Port = 5060
Acct-Delay-Time = 0
NAS-IP-Address = 127.0.0.1
Acct-Unique-Session-Id = "313763d445993202"
Timestamp = 1421661146
\end{verbatim}
\caption{Exemple d’enregistrement dans le journal de \frad}
\label{radrecord}
\end{figure}
Ces fichiers sont constitués d’une liste d’enregistrements correspondant à des actions des utilisateurs, séparés par un double saut de ligne. Chacun de ces enregistrements commence par une date formatée, puis est constitué d’une liste de champs extensible (voir \cref{radrecord}). Nous avons ajouté pour nos besoins les champs \texttt{Calling-Station-Id} et \texttt{Called-Station-Id} \textit{via} la variable de configuration \texttt{radius\_extra} de {\kam} (voir \cref{extension}).
Le champ \texttt{Acct-status-Type} permet de connaître le type d’action qui a provoqué la journalisation. Nous avons rencontré trois valeurs lors de nos essais :
\begin{description}
\item[\texttt{Start}] Début d’un appel, a lieu lorsque l’appelé décroche.
\item[\texttt{Stop}] Fin d’un appel, a lieu lorsque l’une des deux personnes en communication raccroche.
\item[\texttt{Failed}] Appel avorté, a lieu lorsque l’appelant abandonne ou lorsque l’appelé décline l’appel.
\end{description}
\subsubsection{Interprétation du journal}
Pour simplifier les évolutions éventuelles, nous avons décidé d’effectuer une désérialisation intégrale des données. Bien que moins efficace en mémoire et en temps qu’un algorithme d’extraction optimisé, une désérialisation simplifie l’adaptation aux modifications de configuration (ajout de champs) et de besoins (nécessité de lire un champ laissé de côté).
La désérialisation est effectuée séparément pour chaque fichier et son résultat est un tableau ordonné des enregistrements, représentés sous forme d’un tableau associatif correpondant directement aux associations clé-valeur du journal produit par {\frad}. La date donnée sur la première ligne d’un enregistrement étant redondante avec le champ \texttt{Timestamp}, nous avons choisi de l’ignorer, ce qui évite de compliquer la structure ou d’ajouter un champ spécifique dans le résultat de la désérialisation.
Afin de produire des factures et des listes mensuelles, ces tableaux d’enregistrements sont concaténés avant d’être interprétés.
La transformation du journal d’événements en une liste d’appels est effectuée selon l’algorithme suivant :
\begin{itemize}
\item initialiser une liste vide d’appels ;
\item initialiser une liste vide de débuts d’appels ;
\item lire la liste des enregistrements pour la période ;
\item pour tous les enregistrements :
\begin{itemize}
\item si l’enregistrement est de type \texttt{Start}, ajouter un début d’appel à la liste des débuts d’appels,
\item si l’enregistrement est de type \texttt{Stop} :
\begin{itemize}
\item si le début de l’appel n’a pas été rencontré, lever une exception
\item si le début de l’appel a avorté, passer à l’enregistrement suivant
\item ajouter un appel effectif à la liste des appel avec les informations des deux enregistrements
\item retirer le début d’appel de la liste des débuts d’appels,
\end{itemize}
\item si l’enregistrement est de type \texttt{Failed} :
\begin{itemize}
\item ajouter un appel avorté à la liste des appel avec les informations de l’enregistrement
\item signaler un appel avorté dans la liste des débuts d’appels,
\end{itemize}
\item si l’enregistrement est d’un autre type, lever une exception ;
\end{itemize}
\item s’il reste des débuts d’appels non avortés, lever une exception ;
\item retourner la liste des appels.
\end{itemize}
\vspace{1em}
Il s’agit d’une seconde version de l’algorithme : la première n’ajoutait pas d’information à propos des appels avortés dans la liste des débuts d’appels, mais nous avons été confrontés à un cas où, pour un même appel, deux enregistrements \texttt{Failed} et \texttt{Stop} se suivaient. Nous n’avons pas pu reproduire le cas et ne savons donc pas s’il s’agit d’un cas normal ou dû aux manipulations inhabituelles que nous avons effectuées durant la phase de développement : nous étions effectivement dans une phase où nous avons pulsieurs fois de suite redémarré les serveurs pour tenter de régler des problèmes de communications.