GIAO THỨC KADEMLIA

Một phần của tài liệu đồ án công nghệ thông tin Tìm hiểu và xây dựng ứng dụng P P theo kién trúc Kademlia (Trang 41)

Giao thức Kademlia gồm 4 RPC: PING, STORE, FIND_NODE, FIND_VALUE.

• Giao thức PING để thăm dò một node xem node đó có trên mạng hay không.

• Giao thứ STORE cung cấp một node để lưu trữ cặp <khóa, giá trị> cho lần trả về sau.

• Giao thức FIND_NODE đưa vào tham số ID 160 bit. Node nhận của một RPC trả về các thông tin bộ ba <đại chỉ IP, cổng UDP, node ID> của k node gần với tham số ID đưa vào nhất Các bộ ba có thể lấy từ một danh sách k- bucket đơn, hoặc từ các danh sách k-bucket nếu k-bucket gần nhất vẫn chưa đầy. Trong bất cứ trường hợp nào, node nhận RPC cũng phải trả về k nhóm. Nếu tổ hợp tất cả các danh sách k-bucket mà vẫn ít hơn k node thì nó sẽ trả về tất cả các node mà nó biết.

• Giao thức FIND_VALUE có tính chất như FIND_NODE. FIND_VALUE cũng trả về trả về các bộ ba <địa chỉ IP, cổng UDP, node IP> nhưng có một

ngoại lệ. Nếu node nhận RPC đã nhận được một RPC STORE thì nó chỉ việc trả về giá trị được lưu trữ.

Trong tất cả các giao thức RPC, các node nhận trả về một ID RPC 160 bit ngẫu nhiên để chống lại các địa chỉ giả mạo. Các giao thức PING cũng có thể được mạng theo trên các đáp trả RPC cho các node nhận RPC để tăng thêm tính đảm bảo của địa chỉ mạng của người gửi.

Thủ tục quan trọng nhất mà một cá nhân Kademlia phải thực thi là định vị k node gần với node ID được đưa ra nhất. Tạm gọi thủ tục đó là tìm kiếm node (node lookup). Kademlia sử dụng một thuật toán đệ quy để tìm kiếm node. Khởi tạo một tìm kiếm bằng cách chọn σ node từ k-bucket không rỗng gần nhất (nếu k-bucket có ít hơn σ liên lạc thì nó sẽ lấy σ node gần nhất mà nó biết). Sau đó, bộ khởi tạo sẽ gửi song song, không đồng bộ các giao thức FIND_NODE tới σ node đã lựa chọn, σ là một tham số dùng chung cho toàn bộ hệ thống (giá trị khoảng 3,4).

Trong bước đệ quy, bộ khởi tạo gửi lại giao thức FIND_NODE tới những node mà nó biết được từ các giao thức RPC trước. Trong k node, bộ khởi tạo lựa chọn ra σ node gần với node ID cần tìm kiếm nhất. Các node không đáp trả nhanh chóng bị bỏ qua cho đến khi chúng có đáp trả. Nếu một một chu kỳ FIND_NODE không trả về được bất kỳ node nào gần hơn so với node đã đáp trả gần nhất, bộ khởi tạo gửi lại giao thức FIND_NODE tới tất cả k node gần nhất mà nó vẫn chưa yêu cầu truy vấn. Quá trình tìm kiếm kết thúc khi bộ khởi tạo đã yêu cầu truy vấn và nhận đáp trả từ k node gần nhất mà nó đã quan sát được. Khi σ = 1 thì thuật toán tìm kiếm tương tự Chord khi tìm kiếm các node lỗi. Tuy nhiên, Kademlia có thể định tuyến với nguy cơ tiềm tang thấp hơn bởi vì nó tính linh hoạt trong việc lựa chọn bất cứ node nào trong k node để chuyển tiếp một yêu cầu.

Hầu hết các thao tác được thực thi trong các nhóm của thủ tục tìm kiếm trên. Để lưu trữ một cặp <khóa, giá trị>, một cá nhân đinh vị k node gần khóa nhất và gửi cho chúng các giao thức STORE. Hơn nữa, sau mỗi giờ mỗi node thiết lập lại các cặp <khóa, giá trị> nó có. Điều đó để duy trì khả năng bề bỉ của một cặp <khóa, giá trị> với mức cho phép cao nhất. Thông thường cứ 24 giờ, hệ thống cũng yêu cầu các node thiết lập cặp <khóa, giá trị> ban đầu phải thiết lập lại cặp đó. Mặt khác, tất

cả các cặp <khóa, giá trị> có thời hạn 24 giờ sau khi được thiết lập lần đầu tiên để giới hạn lượng thông tin cũ trong hệ thống.

Cuối cùng, để duy trì tính bất biến trong việc thiết lập vòng đời tìm kiếm của một cặp <khóa, giá trị>, hệ thống yêu cầu bất cứ khi nào một node w quan sát thấy một node mới u gần với một vài cặp <khóa, giá trị> của w nhất thì w tạo một bản sao các cặp <khóa, giá trị> đó cho u, đồng thời xóa các cặp đó ra khỏi cơ sở dữ liệu của nó

Để tìm kiếm một cặp <khóa, giá trị>, một node bắt đầu bằng việc thực thi một tìm kiếm để tìm ra k node có node ID gần với khóa cần tìm nhất. Tuy nhiên, sử dụng giao thức FIND_VALUE để tìm kiếm giá trị tốt hơn dùng giao thức FIND_NODE. Hơn nữa, thủ tục đó dừng lại ngay tức thì khi có bất cứ node nào trả về giá trị cần tìm. Để làm được điều đó, một khi một tìm kiếm thành công, node yêu cầu lưu trữ cặp <khóa, giá trị> tại node quan sát được gần với khóa cần tìm nhất mà không trả về giá trị.

Do tính đơn hướng của cấu trúc, những tìm kiếm trong tương lai để tìm kiếm cùng khóa khá giống với việc khai thác các danh sách lưu giữ trước khi truy vấn node gần nhất. Trong suốt thời gian phổ biến cho một khóa nào đó, hệ thống phải lưu giữ nó trên một số node. Để tránh trường hợp tràn lưu giữ, hệ thống lấy thời gian hết hạn của cặp <khóa, giá trị> trong cơ sở dữ liệu của bất cứ node nào tỉ lệ nghịch hàm mũ với số lượng node giữa node hiện tại và node có node ID gần với key ID (ID của khóa) nhất.

Các danh sách bucket sẽ được tái tạo lại theo định kỳ cố định, tùy thuộc vào lưu lượng của các yêu cầu chuyền qua các node. Để tránh trường hợp không tồn tại một chuyển giao nào, cứ sau một giờ, mỗi node tái tạo lại một danh sách bucket trong khoảng nó chưa thực thi tìm kiếm node. Tái tạo bằng cách lựa chọn một ID ngẫu nhiên trong các khoảng của danh sách bucket và thực hiện một tìm kiếm node có node ID là ID được lựa chọn.

Để tham gia vào mạng, một node u phải có một liên lạc với một node các nhân w. u thêm w vào danh sách k-bucket tương ứng. Sau đó u thực hiện một tìm kiếm node cho node ID của nó. Cuối cùng, u tái tạo lại tất cả các danh sách k-

bucket. Trong suốt quá trình tái tạo lại, u thông báo về các danh sách k-bucket của nó đồng thời tự thêm nó vào các danh sách k-bucket của các node khác khi cần đến.

Chương 3: Xây dựng ứng dụng P2PKad 3.1. Mục đích

Xây dựng một thư viện C để thiết lập và nhận bản ghi trong một Kademlia- based DHT (Các bảng phân phối hàm băm Kademlia cơ sở – Distributed Hash Tables). Có thể dùng để thiết lập một địa chỉ IP của máy client để các peer khác kết nối vào các mạng như Internet phone, các chương trình IM không có server; công cụ tìm kiếm cho các máy client BitTorrent; …

Trên cơ sở nền tảng thư viện đã xây dựng, có thể phát triển các ứng dụng P2P theo cấu trúc Kademlia. Do đó, hệ thông được xây dựng lên có thể kết nối với các hệ thống P2P có cấu trúc Kademlia hiện tại.

3.2. Kiến trúc P2PKad

Thư viện P2PKad cho phép ứng dụng truy nhập một mạng Kademlia đã tồn tại để thiết lập và trả về cặp <khóa, dữ liệu>. Ở đây có 3 mạng Kademlia được đưa ra thử nghiệp bao gồm: Overnet; Emule-KAD; RevConnect-KAD. Các thực thi trên cả 3 mạng đều sử dụng một giao thức mạng cơ sở địa chỉ gói UDP. Mỗi gói UDP bắt đầu với 1 byte được gọi là ID để xác nhân mạng Kademlia:

 Overnet: 0x0E3.

#define OP_EDONKEYHEADER 0xE3  eMule-KAD: 0xE4 và 0xE5.

#define OP_KADEMLIAHEADER 0xE4

#define OP_KADEMLIAPACKEDPROT 0xE5  RevConnect: 0xD0 và 0xD1.

#define OP_REVCONNHEADER 0xD0

Bắt đầu từ byte thứ 3 trở đi của các gói nén được nén zlib. Các byte thêm vào sau một byte gọi là “opcode” để xác định nội dung của các tham số chuyền vào; một vài opcode xác định yêu cầu và một vài opcode khác xác định đáp trả. Một vài opcode không có tham số chuyền vào; một yêu cầu cá nhân luôn luôn suy ra một thiết lập xác nhận của các đáp trả có thể.

3.2.1. Các phiên làm việc giữa các peer

Mỗi dữ liệu trao đổi được dựa trên các phiên làm việc ngắn giữa các cặp của các peer, một bộ khởi tạo sẽ khởi tạo các phiên làm việc đó. Với một gói yêu cầu, một node đáp trả sẽ trả về một hoặc nhiêu hơn các gói đáp trả. Các phiên làm việc đó có cũng có thể bị bỏ qua bởi timeout nếu các đáp trả được mong muốn không được trả về sau một vài giây. Từ quan điểm của mỗi peer, một phiên làm việc được xác nhận đơn lẻ bởi bộ ba <flavour, IP_address, port_number> của peer (Session ID); giao thức đó không giống với SSRC của RTP trong việc hỗ trợ nhận dạng các gói tin thuộc cùng phiên làm việc. Bằng việc tích hợp thêm thông tin của node khởi tạo phiên vào Session ID khiến cho giữa mỗi cặp peer có thể có tồn tại phiên làm việc độc lập cùng lúc. Ví dụ tiêu biểu là sự chồng lấp trong eMuleKAD giữa một KADEMLIA_FIREWALLED_REQ và một KADEMLIA_BOOTSTRAP_REQ được khởi tạo bởi các peer trao đổi thông tin trước khi hoàn thành phiên làm việc đầu tiên.

Hình 3.2.1.1: Phiên làm việc trong eMuleKAD (adsbygoogle = window.adsbygoogle || []).push({});

KADEMLIA_FIREWALLED_REQ (tran=1)

KADEMLIA_FIREWALLED_RES (tran=1)

KADEMLIA_BOOTSTRAP_REQ (tran=2)

KADEMLIA_FIREWALLED_ACK (tran=1)

KADEMLIA_BOOTSTRAP_RES (tran=2) open TCP connection; if OK:

Node

Trong Overnet thì hơi khác:

Hình 3.2.1.2: Phiên làm việc trong Overnet

Để lấy được logic của giao thức trên, trong P2PKad, ta sử dụng các đối tượng session để lưu vết trạng thái phiên làm việc. Một đối tượng session (SO) được tạo ra khi bắt đầu một phiên làm việcm, và được hủy khi kết thúc phiên làm việc, và chứa các trường như:

- Kademlia flavour, địa chỉ IP của peer và cổng UDP, và cờ isServerSession (tập hợp các thành phần lại tạo nên “Session ID”). - Một con trỏ trỏ tới một danh sách hàng đợi FIFO.

- Một Pthreads để quản lý các thành phần sửa đổi trong SO. - Một đối tượng pthread_t.

- Một con trỏ trỏ tới một tệp thi hành phiên dịch vụ. Các đối tượng session gồm 2 loại:

1. Client Session Objects (CSO’s). 2. Server Session Objects (SSO’s).

Cờ isServerSession được dùng để phân biệt 2 loại đối tượng session trên. CSO’s được tạo ra bởi các ứng dụng triệu gọi để bắt đầu một phiên làm việc ở phía client. Máy client triệu gọi hàm newSession(KF, peerIP, peerport), hàm này sẽ trả về một con trỏ trỏ tới một đối tượng SO mới, và cho phép một hàm đợi FIFO

OVERNET_IP_QUERY (REQ) (tran=1)

OVERNET _IP_QUERY_ANSWER (tran=1)

OVERNET _IDENTIFY (REQ) (tran=2)

OVERNET_IDENTIFY_REPLY (tran=2)

OVERNET_IP_QUERY_END (tran=1) open TCP connection; if OK, NOT always: Node

A Node B

của node triệu gọi có thể đọc các gói tin UDP đến có liên quan tới phiên làm việc đó. Các đáp trả sẽ được gửi về bằng việc gọi một tệp thực thi thực hiện gửi trả trên cùng socket UDP trên (sendbuf() và các dẫn xuất của nó). Đối tượng pthread_t và con trỏ trỏ tới tệp thực thi phiên dịch vụ đó không được sử dụng thường xuyên trong các phiên làm việc phía client.

Mặt khác, SSO’s tự động được tạo ra khi P2PKad nhận các gói UDP về. Với bộ ba <flavour, IP_address, port_number> không tương ứng với một phiên làm việc phía server đang tồn tại. Nếu flavour đó được hỗ trợ, và nếu opcode đó phù hợp với một trong các nhóm REQuest, một SO được đưa ra và một luồng được bắt đầu để chạy tệp thực thi phiên làm việc phía server (SSR-Session Server Routine); gói tin đến cũng được đưa vào hàng đợi FIFO để SSR sử dụng cho đầu vào UDP

Nếu bộ ba <flavour, IP_address, port_number> nhận về tương ứng với một SSO đang tồn tại thì UDP nhận trả được đưa vào hàng đợi của SSO. Các gói tin không nằm trong nhóm REQuest và nhận về mà phiên làm việc phía client không mở đều được bỏ qua.

Lưồng triệu gọi (cho các phiên làm việc phía client) hay SSP (cho các phiên làm việc phía server) được đưa ra để nhận biết các điều kiện kết thúc của phiên làm việc (đã hoàn thành hoặc timeout trên đầu vào) và phân chia định vị đối tượng session.

3.2.2. Giao thức overnet

Xử lý thiết lập là một xử lý đơn được sử dụng để thêm dữ liệu vào DHT; ngược lại, tìm kiếm là xử lý thu hồi những dữ liệu đó từ DHT. Một bản ghi logic để thiết lập được tạo ra từ 2 phần, thứ tự được lưu trữ kề nhau trong bộ nhớ (tạm gọi là “k-object”): một khóa 16 byte và 16 byte dữ liệu nằm theo sau dữ liệu tổng hợp danh sách các thẻ meta. Đặc thù khóa và dữ liệu 16 byte đó là các hàm băm MD4 của một vài thông tin (ví dụ như: tên người sở hữu file,…).

Danh sách các thẻ meta là tập hợp của các thẻ meta, mỗi một thành phần là một cặp <tên, giá trị>. Tên có thể là một nstring tùy ý hoặc 3 byte nstring. Giá trị của một thẻ meta có thể là một nstring hoặc trong một vài trường hợp (filesize, bitrate, availability) thì là 4-byte unsigned long. k-object là một mã hóa nhị phân

của danh sách được tạo ra bởi 2 hàm băm và một biến số của dictionaries và intergers (dictionaries và intergers là 2 kiểu cơ bản trong BitTorrent).

Chú ý: “nstring” ở đây được định nghĩa như thứ tự của các byte trong bảng mã ASCII, tiền tố là một unsigned short int trong định dạng little-endian để mô tả chiều dài của chuỗi.

Ví dụ: chuỗi “abc” được mã hóa sang dạng nstring như sau. 0x03, 0x00, ‘a’, ‘b’, ‘c’ (adsbygoogle = window.adsbygoogle || []).push({});

Danh sách của các thẻ meta được thêm vào trước một số unsigned long int trong định dạng little-endian cho biết số lượng thẻ meta trong danh sách. Tóm lại, cấu trúc của một k-object là: key-hash[16], related-hash[16], số lượng thẻ meta [4], meta1, meta2, …, metaN.

Peer nhận một yêu cầu thiết lập (PUBLISH) được hỗ trợ để thực hiện theo và lưu trữ k-object vào một cơ sở dữ liệu nội bộ được đánh chỉ định bởi key-hash của nó (hàm băm đầu tiên trong 2 hàm băm); việc đánh chỉ định giúp cho việc tìm kiếm dễ dàng hơn. Thủ tục đệ quy được dùng để tìm kiếm dựa trên tìm kiếm node của Kademlia. Trong Overnet, tìm kiếm được thực thi theo thứ tự của các phiên làm việc “OVERNET_SEARCH / OVERNET_SEARCH_NEXT”.

Chú ý: từ tính chất của các client cho thấy lưu trữ nội bộ điều khiển tái thiết lập theo cách: tái tạo các khóa (ví dụ như với các bản ghi khác nhau có cùng hàm băm thứ nhất) được phép, miễn là hàm băm thứ hai khác nhau. Nếu hàm băm thứ hai cũng giống nhau thì bản ghi được lưu trữ trước sẽ bị xóa đi trước khi thêm một bản ghi mới. Danh sách các thẻ meta không ảnh hưởng gì trong trường hợp này.

3.2.3. Xử lý thiết lập

Overnet không phải là mục đích tổng quan của Kademlia overlay network mà chỉ là một thiết kế đặc biệt để thiết lập thông tin về định vị để tải các file được xác định bởi các thông tin các nhân (hàm băm của nội dung file, tên file, kích cỡ của file, kiểu file, định dạng file, …). Để thực hiện yêu cầu đó, thiết lập được cấu trúc hóa theo 2 bước xử lý sau:

Đầu tiên, các từ khóa thu được từ tên file bằng việc chuyển nó thành chữ thường, thay tất cả các ký tự không phải chữ cái, con số thành các ô trống và cắt chuỗi thành các chuỗi con sao cho không còn ô trống. Sau đó, lấy hàm băm MD4 của một vài từ khóa đầu tiên và mỗi một hàm băm như vậy được sử dụng làm các khóa, k-object lưu trữ hàm băm khóa. Hàm băm MD4 của nội dung file và thiết lập của các thẻ meta mô tả tên file, kiểu, định dạng, kích cỡ,.. được lưu trữ trong thư mục phân tán thông qua giao thức đệ quy OVERNET_SEARCH (chính xác là tìm kiếm node) theo sau các yêu cầu OVERNET_PUBLISH. Như đã nói ở trên, các từ khóa không được lưu trữ trong các thẻ meta hoặc bất cứ đâu trong k-object mà chúng được gửi đi với các OVERNET_PUBLISH_REQUEST, chỉ có các hàm băm của chúng được sử dụng như các khóa (một sao chép của các khóa được đặt ở đầu k-object). Các thẻ meta đã sử dụng trong bước này chỉ bao gồm các thành phần của file (tên file, độ dài của file, định dạng file, kiểu file,…).

3.2.3.2. Tìm kiếm nguồn

Sử dụng hàm băm của nội dung file như là khóa. Hàm băm của peer đang

Một phần của tài liệu đồ án công nghệ thông tin Tìm hiểu và xây dựng ứng dụng P P theo kién trúc Kademlia (Trang 41)