0. Règle éditoriale pour la suite du projet
À partir de ce dossier, nous séparons strictement deux choses.
Couche publique
Les pages pédagogiques expliquent :
ce qu'est eMule
comment fonctionne eD2K
comment fonctionne Kad
les choix historiques
les limites observées dans le protocole et les implémentations
Elles ne présentent pas une amélioration future comme si elle appartenait déjà au client.
Couche interne
Les rapports de travail peuvent contenir :
hypothèses
pistes
expériences
instrumentation
correctifs candidats
comparaisons avec les Mods
Ces éléments restent internes jusqu’à :
implémentation
test
validation
absence de régression
Publication ultérieure
La logique éditoriale retenue est :
« Après ces études, voici le fruit de notre travail. »
Une future version du logiciel sera donc présentée après validation comme résultat du travail, et non introduite par anticipation dans chaque fiche historique.
Les dossiers publics 01–09 pourront être harmonisés selon cette règle lors d’une passe éditoriale ultérieure.
1. Corpus de référence
Historique
edonkey-protocol.txt, v0.6, 2002.
Valeur :
surface protocolaire ancienne
opcodes
formats client↔serveur
UDP
server.met
Limite :
document communautaire / reverse-engineered
pas une spécification normative officielle exhaustive
Client
eMule Community 0.72a :
tag eMule_v0.72a-community
SHA ac3d52eafd88e9f6d9e0c2204c6dbead18db750b
Fichiers majeurs :
ServerConnect.cpp
ServerSocket.cpp
ServerList.cpp
UDPSocket.cpp
SharedFileList.cpp
DownloadQueue.cpp
Opcodes.h
Serveur indépendant
eNode, petermrg/eNode.
Utilité :
observer le côté serveur
rejouer en laboratoire
corroborer Login / OfferFiles / Search / GetSources / Callback
Ne pas prendre eNode comme norme de tous les serveurs historiques.
2. Surface protocolaire historique
Client → serveur :
0x01 Login
0x14 Get Server List
0x15 Offer Files
0x16 Search
0x19 Get Sources
0x1C Callback Request
0x21 More Results
Serveur → client :
0x32 Server List
0x33 Search Result
0x34 Server Status
0x35 Callback Requested
0x36 Callback Failed
0x38 Server Message
0x40 ID Change
0x41 Server Ident
0x42 Found Sources
UDP historique :
0x96 Status Request
0x97 Status Result
0x98 Search
0x99 Search Result
0x9A Get Sources
0x9B Found Sources
0x9C Callback
0x9E Callback Fail
0xA1 Server List
0xA2 Server Desc Request
0xA3 Server Desc
3. Control plane / data plane
Le serveur appartient principalement au :
CONTROL PLANE
Il aide à :
identifier
indexer
rechercher
découvrir
rendre joignable
Le contenu reste dans le :
DATA PLANE
client ↔ client
Cette distinction sera utile pour tous les dossiers suivants.
4. Modèle de connexion serveur
Le client possède un connectedsocket courant.
Plusieurs essais peuvent exister pendant la connexion, mais une fois l’un d’eux établi :
un seul serveur TCP principal
reste actif.
En parallèle :
plusieurs serveurs UDP
peuvent être consultés.
5. Login moderne
CServerConnect::ConnectionEstablished() construit :
UserHash
ClientID
TCP port
TagCount = 4
Tags :
CT_NAME
CT_VERSION
CT_SERVER_FLAGS
CT_EMULE_VERSION
Puis :
OP_LOGINREQUEST
6. Capabilities du client
CT_SERVER_FLAGS annonce :
ZLIB
NEWTAGS
LARGEFILES
UNICODE
SUPPORTCRYPT
REQUESTCRYPT
REQUIRECRYPT
Le login est donc également une négociation de capacités.
7. IDCHANGE
ServerSocket.cpp traite OP_IDCHANGE.
Le paquet moderne peut contenir :
ClientID
server TCP flags
public IP rapportée
Le client :
enregistre l'ID
déduit l'IP depuis le HighID
ou conserve l'IP rapportée si LowID
8. Confirmation indépendante par eNode
eNode :
loginRequest
→ isFirewalled
→ LowID si firewalled
→ IPv4 comme ID si joignable
Le modèle est cohérent avec la lecture côté client.
Les détails précis du test de firewall ne doivent pas être généralisés à tous les serveurs sans source supplémentaire.
9. Après connexion : remise à zéro de la publication
Une fois connecté :
ClearED2KPublishInfo();
SendListToServer();Une nouvelle session serveur repart donc avec un nouvel état de publication.
10. SendListToServer()
La fonction sélectionne les fichiers :
non encore publiés
et
compatibles avec les capacités du serveur
Puis les trie selon la priorité d’upload.
11. Limite de publication
Le client calcule :
limit = SoftFiles
puis force :
si 0 ou > 200
→ 200
Il faut rester prudent sur la sémantique serveur exacte de SoftFiles.
Le fait solide est :
le client l'utilise pour borner son lot
12. Publication progressive
Les fichiers envoyés deviennent :
PublishedED2K = true
Les suivants attendent un autre cycle.
Constante :
ED2KREPUBLISHTIME = 1 minute
13. Compression
Si le serveur annonce :
SRV_TCPFLG_COMPRESSION
OP_OFFERFILES peut être compressé.
Le code essaie la compression et garde le paquet compressé seulement si elle est avantageuse.
14. KeepAlive
KeepConnectionAlive() envoie :
OP_OFFERFILES
count = 0
comme paquet de maintien de connexion.
C’est une curiosité historique documentable.
15. Publication côté serveur
eNode :
offerFiles()
→ db.files.addSource(file, client.info)
Le modèle serveur est donc :
FileHash / FileMetadata
↔
Client source
et non stockage du contenu.
16. Recherche serveur
Historique :
OP_SEARCHREQUEST
→ OP_SEARCHRESULT
eNode :
db.files.find(query)
La recherche porte sur l’index serveur.
17. Limite de la recherche
L’index d’un serveur n’est pas :
l'intégralité du réseau eD2K
Les recherches UDP globales et Kad complètent cette vue.
18. GetSources TCP
Historique :
OP_GETSOURCES
→ OP_FOUNDSOURCES
La requête moderne du client ajoute la taille du fichier.
Grand fichier :
Hash
0 marker
uint64 size
Fichier classique :
Hash
uint32 size
19. Variante obfuscation
Si possible :
OP_GETSOURCES_OBFU
→ OP_FOUNDSOURCES_OBFU
La réponse enrichie peut fournir des données de connexion supplémentaires, dont un UserHash selon les options.
20. Réception FoundSources
Le client fait :
FileHash
→ CPartFile
→ AddSources()
Le serveur alimente donc le même pipeline de source admission que les autres canaux.
21. Queue locale des demandes serveur
m_localServerReqQueue
La sélection tient compte de :
LastSearchTime
DownloadPriority
afin de choisir quels fichiers interroger en premier.
22. Batch TCP
Valeur actuelle :
iMaxFilesPerTcpFrame = 15
Le client concatène jusqu’à 15 requêtes dans une même frame.
23. Cadence du batch TCP
Après le frame :
15 * (16 + 4) secondssoit environ :
300 s = 5 min
avant le batch suivant.
Ce timer est distinct de la constante historique :
SERVERREASKTIME = 15 min
Ne pas les confondre dans la documentation.
24. UDP GetSources multi-serveurs
Le client peut interroger successivement les serveurs de server.met.
Il saute :
serveur TCP courant
serveurs trop défaillants
et vérifie :
source limit
LargeFiles support
UDP flags
25. Cadence UDP
Constante :
UDPSERVERREASKTIME = 30 min
Le mécanisme n’est donc pas permanent.
26. Limites de la requête UDP
Constantes/logique :
MAX_UDP_PACKET_DATA = 510
MAX_REQUESTS_PER_SERVER = 35
Plusieurs hashes peuvent être groupés.
La taille de la requête varie avec :
GetSources1
GetSources2
LargeFiles
28. ServerStats
Le client sonde périodiquement les serveurs.
Cadence nominale :
≈ 4,5 h
avec randomisation historique et minimum de 20 min pour certains repings.
29. Challenge UDP
Requête :
challenge uint32
Réponse attendue :
même challenge
Si différent :
ignore
Niveau de confiance :
corrélation
pas authentification forte.
30. Informations apprises par UDP
Selon taille/version :
users
files
max users
soft files
hard files
UDP flags
LowID users
UDP obfuscation port
TCP obfuscation port
server UDP key
31. Capacités UDP
Bits connus dans la branche :
ExtGetSources
ExtGetSources2
ExtGetFiles
NewTags
Unicode
LargeFiles
UDP obfuscation
TCP obfuscation
32. Server Description
Ancien format :
name
description
Nouveau format :
challenge
tag list
Le client rejette une nouvelle réponse au challenge inattendu.
33. Callback serveur
Historique :
OP_CALLBACKREQUEST <LowID>
→ serveur
→ OP_CALLBACKREQUESTED vers LowID
→ LowID connecte le demandeur
eNode possède exactement ce modèle dans son code.
34. Échec callback
Si le LowID ciblé n’est plus dans la table du serveur :
CALLBACKFAILED
Le serveur ne peut pas joindre un client qu’il n’a plus en session.
35. Extension callback moderne
OP_CALLBACKREQUESTED peut contenir :
IP
port
crypt options
UserHash
Si le UserHash reçu contredit celui déjà associé au client :
le client ne fait pas confiance aux options crypt
Bonne pratique historique à retenir dans le Trust Model.
36. server.met historique
Document 2002 :
0x0E
DWORD count
IP
port
Meta list
Le document mentionne même l’existence possible de données de queue/tail non interprétées.
37. server.met moderne
Lecture :
0xE0 ou 0x0E
Écriture :
0xE0
38. Métadonnées modernes conservées
Le writer peut stocker :
name
dynIP
description
fail count
preference
users
files
ping
last ping
max users
soft files
hard files
version
UDP flags
LowID users
UDP key
UDP key IP
TCP/UDP obfuscation ports
39. Sauvegarde transactionnelle simple
Séquence :
écrire server.met.new
ancien server.met → server_met.old
server.met.new → server.met
C’est une protection utile contre une écriture directe détruisant le fichier courant.
40. Sauvegarde périodique
CServerList::Process() :
≈ 17 min
pour persister les informations apprises.
41. AutoUpdate
Sources possibles :
URL configurée
server.met local
server_met.download
staticservers.dat
Lors d’un update, une ancienne liste est conservée en backup.
43. Server list fournie par un serveur
OP_SERVERLIST
Les nouvelles entrées sont créées :
SRV_PR_LOW
Une liste reçue d’un serveur n’est donc pas promue directement.
44. Admission d’un serveur
AddServer() vérifie :
GoodIP
IPFilter
duplicate address:port
duplicate IP/TCP
DynIP
45. Trust boundary serveur
Mesuré localement
TCP connect
UDP response
ping
callback abouti
source connectée
fichier confirmé
Déclaré par serveur
name
description
version
users
files
LowID users
source list
search results
capability flags
Corrélé
UDP challenge response
description challenge
Ne pas confondre les trois niveaux.
46. Fake content vs corruption
Un fichier peut être :
parfaitement cohérent avec son ED2K hash
tout en étant :
mal nommé ou trompeur
AICH protège :
l'intégrité du contenu associé au hash
pas :
la vérité du nom affiché
47. Première campagne interne : rendement des canaux de sources
Pour un ensemble de FileHash :
server TCP
server UDP
Kad
SX
Tracer :
announced
new
duplicate
filtered
connected
file-confirmed
payload
hash-valid
Aucune décision automatique dans la première phase.
48. Impact du réglage Crypt Required
Comparer sur périodes/fichiers comparables :
Crypt Required OFF
Crypt Required ON
Mesures :
UDP server sources
time-to-first-source
time-to-first-transfer
sources utiles totales
But :
comprendre l’impact réel du chemin désactivé.
Pas recommander un réglage avant résultats.
49. Evidence par serveur
Structure conceptuelle :
ServerEvidence
Reachability
SourceYield
SearchYield
CallbackReliability
CapabilityConsistency
Ne pas créer un score unique 0–100.
50. Callback evidence
Tracer séparément :
server TCP callback
server UDP callback
Kad Buddy callback
Direct UDP callback
Mesures :
attempt
instruction received
connection
fail
latency
51. Publication coverage
Pour une grosse bibliothèque :
local file count
published flag count
server SoftFiles
OfferFiles packet count
time since connect
Question à tester :
temps réel pour publier l'ensemble
Le client montre ce qu’il envoie ; seul un test côté serveur peut confirmer ce qui est conservé.
52. eNode comme serveur laboratoire
Intérêt majeur :
contrôler les deux extrémités
Tests possibles :
HighID
LowID
OfferFiles
GetSources
Search
Callback
UDP
Permet captures et assertions précises sans dépendre d’un serveur public.
53. Limite eNode
Le projet contient encore des TODO et ne couvre pas nécessairement toutes les extensions modernes.
Règle :
absence dans eNode
≠
absence dans le protocole
54. Wireshark comme troisième témoin
Pour les futurs layouts binaires :
eMule writer
eMule reader
eNode/aMule
Wireshark
capture réelle
Trianguler avant de publier une spécification octet-par-octet.
55. server.met provenance
Le format ne porte pas une signature d’auteur.
Première instrumentation potentielle :
origin URL/manual/server
imported count
filtered count
duplicates
DNS success
UDP response
TCP success
Pas de nouveau format nécessaire pour mesurer.
56. Fuzzing local server.met
Cibles :
AddServerMetToList
AddTagFromFile
Cas :
version invalide
count énorme
troncature
tag inconnu
string length excessive
DynIP malformé
Objectif :
pas de crash
pas d'allocation aberrante
pas d'état partiellement créé
57. Fuzzing TCP serveur
Cibles :
OP_IDCHANGE
OP_SERVERSTATUS
OP_SERVERIDENT
OP_SERVERLIST
OP_FOUNDSOURCES
OP_CALLBACKREQUESTED
OP_SEARCHRESULT
58. Fuzzing UDP serveur
Cibles :
GLOBSEARCHRES
GLOBFOUNDSOURCES
GLOBSERVSTATRES
SERVER_DESC_RES
Les challenges/taille doivent être testés aux frontières.
59. Performance : ne pas optimiser le CPU au mauvais endroit
Sur une machine moderne, parser quelques dizaines de records serveur coûte peu.
Le coût pratique peut plutôt venir de :
mauvaises connexions déclenchées
pollution de listes
timeouts
recherches inutiles
callbacks ratés
Les métriques doivent donc mesurer le résultat réseau, pas seulement les microsecondes CPU.
60. Ne pas classer les serveurs uniquement par taille
Un gros serveur peut fournir :
beaucoup de résultats
simplement parce qu’il indexe davantage de clients.
Un plus petit peut apporter :
des hashes uniques
des sources différentes
Mesurer aussi :
diversité
nouveauté
utilité
61. Search diversity
Comparer :
hashes uniques par serveur
duplications
temps de réponse
résultats recoupés avec Kad
Une divergence entre index n’est pas automatiquement frauduleuse.
Les populations indexées sont différentes.
62. Source diversity
Même principe :
10 nouvelles sources
peuvent être plus utiles que :
100 doublons
Le rendement doit distinguer quantité et information réellement nouvelle.
63. Failed count
Les serveurs accumulent un compteur d’échecs.
Ils peuvent être retirés après le seuil configuré.
À tester sur :
DNS dynamique
coupure temporaire
VPN
réseau mobile
avant toute modification de politique.
64. Challenge pseudo-aléatoire
Les challenges serveur utilisent encore des générateurs historiques.
Ce n’est pas équivalent au problème SecureIdent.
Ici le challenge sert essentiellement à :
corréler requête/réponse
et non à protéger une identité cryptographique.
Priorité de modernisation faible.
67. Conclusion
Le serveur eD2K assure principalement :
session / Client ID
indexation
recherche
discovery de sources
callback LowID
La branche moderne ajoute :
multi-server UDP
capability flags
compression
LargeFiles
obfuscation
server health
server.met enrichi
L’étude ne justifie pas de « refaire » le protocole serveur.
Le travail interne pertinent est plutôt de mesurer, sur le réseau actuel, la valeur réelle de chaque fonction et de chaque canal.
Les conclusions applicables au futur client devront être publiées seulement après expérimentation et validation.