发布时间 : 星期五 文章Emule Kad 网络分析更新完毕开始阅读
3.2.1 GetInfo相关协议:
KADEMLIA_SEARCH_REQ KADEMLIA_SEARCH_NOTES_REQ KADEMLIA2_SEARCH_KEY_REQ KADEMLIA2_SEARCH_SOURCE_REQ KADEMLIA2_SEARCH_NOTES_REQ
KADEMLIA_SEARCH_RES KADEMLIA_SEARCH_NOTES_RES KADEMLIA2_SEARCH_RES
//UnUsed(老的协议)
3.2.2 Publish 相关协议:
KADEMLIA_PUBLISH_REQ //UnUsed(老的协议) KADEMLIA_PUBLISH_NOTES_REQ KADEMLIA2_PUBLISH_KEY_REQ KADEMLIA2_PUBLISH_SOURCE_REQ KADEMLIA2_PUBLISH_NOTES_REQ
KADEMLIA_PUBLISH_RES KADEMLIA_PUBLISH_NOTES_RES KADEMLIA2_PUBLISH_RES
四、Emule Buddy机制分析
Emule 中的Buddy 机制是为了增进Emule中HihgId-LowId/LowId-LowId的通信,使得一个公网的Peer可以和处于NAT内的Peer之间相互通信,同时加上适当的策略,也可以让两个处于NAT内的Peer之间相互通信。下面是关于Emule Buddy的一些分析结论:
? LowId 发现自己处于NAT内时,则主动开始在Kad网络内寻找Buddy,如果一个
HighId没有为别的LowId做Buddy,则可以成为该LowId的Buddy。 ? LowId 的Buddy 必须是 HighId,反之,HighId的Buddy必须是LowId。 ? 目前,0.47c 版本的Buddy 机制还是一对一。 ? LowId不是在自己的KadId周围附近找Buddy,是在KadId~方向找自己的Buddy,
这样可以增进Kad网络的交互,不会引起小范围内的信息孤岛现象。
? 一个LowId 拿到HighId的Buddy后就可以向Kad网络内发布自己的Peer信息了。 〔发布信息包含: 自己的KadId~,Buddy IP,Buddy Udp Port〕
第一次的FINDBUDY 必须是在程序启动后的五分钟之后,因为之后的FINDBUDDY 是在丢失了 BUDDY 之后进行(但同时)
4.1 网络协议包序列图:
4.2 FindBuddy 过程状态图
4.3 Buddy实现框架代码List:
# LowId(A)
① 发送 KADEMLIA_FINDBUDDY_REQ
CSearch::StorePacket( ) {
Case FINDBUDDY:
//packet param: <128bit Target(Low.A KadId~)>
② 接收 KADEMLIA_FINDBUDDY_RES
CKademliaUDPListener::Process_KADEMLIA_FINDBUDDY_RES (const byte *pbyPacketData, uint32 uLenPacket, uint32 uIP, uint16 uUDPPort) {
theApp.clientlist->RequestBuddy(&contact); // now Peer.B Kad State is KS_QUEUED_BUDDY }
③ Low.A TryToConnect to High.B CClietList::Process( ... ) {
cur_client->SetKadState(KS_CONNECTING_BUDDY);// Peer.B KadState Changed to KS_CONNECTING_BUDDY cur_client->TryToConnect(true); // Low.A TryToConnect to High.B }
④ Low.A 连接 High.B 成功
CUpDownClient::ConnectionEstablished() { …
case KS_CONNECTING_BUDDY: SetKadState(KS_CONNECTED_BUDDY); //Peer.B Kad State changed to KS_CONNECTED_BUDDY }
# HighId(B)
① 接收 KADEMLIA_FINDBUDDY_REQ
CKademliaUDPListener::Process_KADEMLIA_FINDBUDDY_REQ (const byte *pbyPacketData, uint32 uLenPacket, uint32 uIP, uint16 uUDPPort) { theApp.clientlist->IncomingBuddy(&contact, &BuddyID); //Peer.A Kad State is KS_INCOMING_BUDDY //回发 KADEMLIA_FINDBUDDY_RES packet //packet param:
CUpDownClient::ConectionEstablished( ) { case KS_INCOMING_BUDDY: SetKadState(KS_CONNECTED_BUDDY); //Peer.A Kad State changed to KS_CONNECTED_BUDDY }
五、Emule Kad 数据结构分析
附录1( OPCode List):
关于KAD的Opcodes,Kad1.0个2.0相互对应
// KADEMLIA (opcodes) (udp) #define KADEMLIA_BOOTSTRAP_REQ #define KADEMLIA2_BOOTSTRAP_REQ
#define KADEMLIA_BOOTSTRAP_RES #define KADEMLIA2_BOOTSTRAP_RES
#define KADEMLIA_HELLO_REQ #define KADEMLIA2_HELLO_REQ
#define KADEMLIA_HELLO_RES #define KADEMLIA2_HELLO_RES
#define KADEMLIA_REQ (receiver) 16>
#define KADEMLIA2_REQ
#define KADEMLIA_RES
#define KADEMLIA_SEARCH_REQ
0x31 // Old Opcode, don't use. 0x32 //
0x38 // 0x3A // 0x40 // 0x42 // #define KADEMLIA_SEARCH_NOTES_REQ #define KADEMLIA2_SEARCH_KEY_REQ #define KADEMLIA2_SEARCH_NOTES_REQ #define KADEMLIA_SEARCH_RES //#define UNUSED [16]> #define KADEMLIA_PUBLISH_REQ //#define UNUSED [16]> 0x30 // 0x28 // #define KADEMLIA2_RES 0x21 // 0x20 // 0x18 // 0x10 // 0x08 // 0x00 // 0x33 // #define KADEMLIA2_SEARCH_SOURCE_REQ [16]>