1.1. ์์์ ์์์ ¶
๋ฆ๊ฒ ์ด ๊ธ์ ์ฌ๋ฆฐ ๊ฒ์ ๋ํด ๋ฏธ์ํ๋ค.
์ด ๋ฌธ์๋ ๋ด๊ฐ ์๋ฅด๋ฐ์ดํธ๋ฅผ ํ๋ฉด์ ๋ฒ์ญ๊ณผ ์์ฑํ ๋ฌธ์์ด๋ค.
์ง๊ธ์ ์คํ์์๋ ๋ผ์ฐํ ๋ถ๋ถ์ ๋งด๊ณผ ์บ์ฌ์ ์์ด์์ ๋ง์ ๋ถ๋ถ ์์ ์ด ๊ฐํด์ก๋ค.
๋๋ถ๋ถ์ P2P ํ๋ก๊ทธ๋จ๋ค์ด ๋ํ ๋ผ์ ๋ฐฉ๋ฒ์ ๊ธฐ๋ณธ์ผ๋ก ์์ฑ ๋์์ผ๋ฉฐ ์ง๊ธ์ ์ ๋์
IP๋ฅผ ๊ฐ๋ ํ๊ฒฝ์์๋ ์ด๋ฅผ ๋ฐ์ด ๋๋ ๋ฐฉ๋ฒ์ ์์ ๊ฒ์ผ๋ก ๋ณด์ฌ์ง๋ค.
ํ์ IPv6๊ฐ ๋์จ๋ค๋ฉด ๊ฐ๊ฐ์ ์์คํ ์ด ์๋ ์ดํ๋ฆฌ์ผ์ด์ ์ IP๋ฅผ ๋ถ์ผ ์ ์๊ฒ ๋์ด์ง๋ค๊ณ
์ฝ์ ์ ์ด ์๋ค. ์ด ๋ ๋๋ฉด ๋ณด๋ค ํ๊ธฐ์ ์ธ P2P ํ๋ก๊ทธ๋จ์ด ๋์ฌ ๊ฒ์ผ๋ก ๋ณด์ธ๋ค.
์ด ๋ฌธ์๋ ๋ด๊ฐ ์๋ฅด๋ฐ์ดํธ๋ฅผ ํ๋ฉด์ ๋ฒ์ญ๊ณผ ์์ฑํ ๋ฌธ์์ด๋ค.
์ง๊ธ์ ์คํ์์๋ ๋ผ์ฐํ ๋ถ๋ถ์ ๋งด๊ณผ ์บ์ฌ์ ์์ด์์ ๋ง์ ๋ถ๋ถ ์์ ์ด ๊ฐํด์ก๋ค.
๋๋ถ๋ถ์ P2P ํ๋ก๊ทธ๋จ๋ค์ด ๋ํ ๋ผ์ ๋ฐฉ๋ฒ์ ๊ธฐ๋ณธ์ผ๋ก ์์ฑ ๋์์ผ๋ฉฐ ์ง๊ธ์ ์ ๋์
IP๋ฅผ ๊ฐ๋ ํ๊ฒฝ์์๋ ์ด๋ฅผ ๋ฐ์ด ๋๋ ๋ฐฉ๋ฒ์ ์์ ๊ฒ์ผ๋ก ๋ณด์ฌ์ง๋ค.
ํ์ IPv6๊ฐ ๋์จ๋ค๋ฉด ๊ฐ๊ฐ์ ์์คํ ์ด ์๋ ์ดํ๋ฆฌ์ผ์ด์ ์ IP๋ฅผ ๋ถ์ผ ์ ์๊ฒ ๋์ด์ง๋ค๊ณ
์ฝ์ ์ ์ด ์๋ค. ์ด ๋ ๋๋ฉด ๋ณด๋ค ํ๊ธฐ์ ์ธ P2P ํ๋ก๊ทธ๋จ์ด ๋์ฌ ๊ฒ์ผ๋ก ๋ณด์ธ๋ค.
์๋์ ๊ธ์ ๊ฐ๋ณ๊ฒ ์ฝ์ด ์ฃผ์๊ธธ....
1.2. ์ฃผ์ธ์ฅ์ด ์๊ฐํ๋ ๊ฐ์ฅ ์ด์์ ์ธ P2P๋ ¶
๊ทธ๋ํ
๋ผ๋ ํ์คํ ๋งค๋ ฅ์ ์ด๊ณ ๋ํ ์ด์์ ์ธ ์์ P2P๋ผ๋ ์๊ฐ์ด ๋ ๋ค. ํ์ง๋ง P2P๋ ๋ง์ ๋ถ๋ถ
ํฌ์(?)์ด ํ์ํ๋ค. ์ฌ๊ธฐ์ ํฌ์์ด๋ ๋ถํ์ํ์ง๋ง ์ธ ์ ๋ฐ์ด ์๋ ๋์ญํญ์ ๋งํ๋ค.
๋ด๊ฐ ์ฐพ๊ณ ์ ํ๋ ํ์ผ์ด ๋๊ฐ ๊ฐ์ง๊ณ ์๋ ์ง ์๊ณ ์๋ค๋ฉด ๊ตณ์ด P2P๋ ํ์ํ์ง ์์ ๊ฒ์ด๋ค.
ํฌ์(?)์ด ํ์ํ๋ค. ์ฌ๊ธฐ์ ํฌ์์ด๋ ๋ถํ์ํ์ง๋ง ์ธ ์ ๋ฐ์ด ์๋ ๋์ญํญ์ ๋งํ๋ค.
๋ด๊ฐ ์ฐพ๊ณ ์ ํ๋ ํ์ผ์ด ๋๊ฐ ๊ฐ์ง๊ณ ์๋ ์ง ์๊ณ ์๋ค๋ฉด ๊ตณ์ด P2P๋ ํ์ํ์ง ์์ ๊ฒ์ด๋ค.
ํ์ง๋ง ์ด๋ฌํ ํฌ์์ ์ค์ด๋ ๊ฒ์ด ๋ณด๋ค ์ข์ ๊ฒ์ด๋ผ๋ ์๊ฐ์ด ๋ ๋ค. ๊ทธ๋ฐ ์ ์์ ๋ด๊ฐ ์๊ฐํ๋ ๊ฐ์ฅ
์ด์์ ์ธ P2P๋ e-Donkey๋ผ๊ณ ์๊ฐ ๋์ด์ง๋ค. ๋ฌผ๋ก ์ง๊ธ์ e-Donkey๋ ์๋๋ค. ๋ด๊ฐ ์๊ฐํ๋ ๋ถ๋ถ์ผ๋ก
๊ณ ์ณ์ ธ์ผ ๊ฒ ์ง. ํ์ง๋ง ์ง๊ธ์ e-Donkey์ฒ๋ผ ๊ฐ์ธ์ด ์๋ฒ๋ฅผ ๊ฐ์ง ์ ์๊ณ ๋ํ ์ด ์๋ฒ๋ฅผ ๊ฐ์ง๊ณ ์ฐพ๋
๋ค๋ฉด ๋ถํ์ํ ๋์ญํญ์ ์ค์ด๋ค ๊ฒ์ด๊ณ ๋ถ์ฐ๋ ์๋ฒ๋ฅผ ํ๋์ ์์ P2P๋ก ๋ฌถ๊ณ ์๋ฒ์์ ํด๋ผ์ด์ธํธ์
๋ ธ๋๋ค์ ์์ ํด ์ค๋ค๋ฉด ๊ฐ์ฅ ์ด์์ ์ด์ง ์์๊น? ๋ผ๊ณ ํ ๋ ๋ฌด์ ํ ๊ณ ๋ฏผํ๋ค. ์ก์๋ฆฌ ์ด์ ๊ทธ๋ง!!!!
์ด์์ ์ธ P2P๋ e-Donkey๋ผ๊ณ ์๊ฐ ๋์ด์ง๋ค. ๋ฌผ๋ก ์ง๊ธ์ e-Donkey๋ ์๋๋ค. ๋ด๊ฐ ์๊ฐํ๋ ๋ถ๋ถ์ผ๋ก
๊ณ ์ณ์ ธ์ผ ๊ฒ ์ง. ํ์ง๋ง ์ง๊ธ์ e-Donkey์ฒ๋ผ ๊ฐ์ธ์ด ์๋ฒ๋ฅผ ๊ฐ์ง ์ ์๊ณ ๋ํ ์ด ์๋ฒ๋ฅผ ๊ฐ์ง๊ณ ์ฐพ๋
๋ค๋ฉด ๋ถํ์ํ ๋์ญํญ์ ์ค์ด๋ค ๊ฒ์ด๊ณ ๋ถ์ฐ๋ ์๋ฒ๋ฅผ ํ๋์ ์์ P2P๋ก ๋ฌถ๊ณ ์๋ฒ์์ ํด๋ผ์ด์ธํธ์
๋ ธ๋๋ค์ ์์ ํด ์ค๋ค๋ฉด ๊ฐ์ฅ ์ด์์ ์ด์ง ์์๊น? ๋ผ๊ณ ํ ๋ ๋ฌด์ ํ ๊ณ ๋ฏผํ๋ค. ์ก์๋ฆฌ ์ด์ ๊ทธ๋ง!!!!
1.3. The Gnutella Protocol Document ¶
The Gnutella Protocol Document
1. Protocol Specification
1.1 Gnutella๋ Peer to Peer ์ ๋ถ์ฐ ๋ชจ๋ธ๋ก์ Mesh๊ตฌ์กฐ์ ๋คํธ์ํฌ๋ง์ ๊ฐ์ง๋ฉฐ
Query์ ์ก์ ํตํด ๋คํธ์ํฌ๋ด ํ์ผ์ ๊ฒ์๊ณผ ๋ค์ด๋ก๋๋ฅผ ๊ฐ๋ฅํ๊ฒ ํ๋ค.
1.2 ํ๋กํ ์ฝ ์ ์5๊ฐ์ Descriptor๋ฅผ ์ฌ์ฉํ๊ณ TCP/IP ํ๋กํ ์ฝ๊ณผ ASCII Code๋ฅผ ๊ธฐ๋ฐ์ผ๋ก
์ด์ฉํ์ฌ ํต์ ์ด ์ด๋ฃจ์ด์ง๋ค.
- ๋คํธ์ํฌ๋ง ์ด๊ธฐ ์ง์ -
- Note
Note 1 : ๋ชจ๋ ๋ฐ์ดํฐ ํ๋๋ ํน๋ณํ ๋ง์ด ์์ผ๋ฉด ๋ฆฌํ ์๋์ธ
Note 2 : IP ์ฃผ์๋ IPv4 ํ์์ผ๋ก ์ฐ์ธ๋ค.
Note 3 : Protocol์ Header์ Payload๋ก ๊ตฌ์ฑ
- ํค๋
Descriptor ID (16 byte): ๋คํธ์ํฌ ์์ ๊ณ ์ ์๋ณ์
Payload Descriptor (2 byte): ๋ช ๋ น์ด์ ์๋ณ์
TTL (1 byte): ๋คํธ์ํฌ์ Servent๋ฅผ ์ง๋ ๋๋ง๋ค ๊ฐ์ํ๋ ์ /
Payload Length (4 byte): Header ๋ค์์ ๋ฐ๋ผ์ค๋ Descriptor ์ ๊ธธ์ด
์ด์ฉํ์ฌ ํต์ ์ด ์ด๋ฃจ์ด์ง๋ค.
- ๋คํธ์ํฌ๋ง ์ด๊ธฐ ์ง์ -
~cpp Connection String : GNUTELLA CONNECTION/<version>/nn
~cpp Response Connection : GNUTELLA OKnn
- Note
Note 1 : ๋ชจ๋ ๋ฐ์ดํฐ ํ๋๋ ํน๋ณํ ๋ง์ด ์์ผ๋ฉด ๋ฆฌํ ์๋์ธ
Note 2 : IP ์ฃผ์๋ IPv4 ํ์์ผ๋ก ์ฐ์ธ๋ค.
Note 3 : Protocol์ Header์ Payload๋ก ๊ตฌ์ฑ
- ํค๋
Descriptor ID (16 byte): ๋คํธ์ํฌ ์์ ๊ณ ์ ์๋ณ์
Payload Descriptor (2 byte): ๋ช ๋ น์ด์ ์๋ณ์
TTL (1 byte): ๋คํธ์ํฌ์ Servent๋ฅผ ์ง๋ ๋๋ง๋ค ๊ฐ์ํ๋ ์ /
๋คํธ์ํฌ ๋ถํ๋ฅผ ์ค์ด๊ธฐ ์ํด ์ฐ์
Hops (1 byte): ์ง๋๊ฐ Servent์ Payload Length (4 byte): Header ๋ค์์ ๋ฐ๋ผ์ค๋ Descriptor ์ ๊ธธ์ด
Data๊ฐ ์คํธ๋ฆผ์ด๊ธฐ ๋๋ฌธ์ ๊ณต๋ฐฑ์ด๋ Pad Byte๊ฐ ๋ฐ๋ผ์ค์ง์๋๋ค.
Gnutella ํ๋กํ ์ฝ์ ๊ฒฝ์ฐ synch๋ฅผ ๋ง์ถ๋ ํน๋ณํ byte๊ฐ ์กด์ฌํ์ง ์์
ํ์์ ํ๋ฆฐ Descriptor๋ ํ๊ธฐ๋๋ค.0 15 16 17 18 19 22
- ๋์คํฌ๋ฆฝํฐ (Descriptor)
ํ1)
์์ธ | ์ค๋ช |
ping | ๋คํธ์ํฌ์์ ํธ์คํธ๋ฅผ ์ฐพ์ ๋ ์ฐ์ธ๋ค. Payload๊ฐ ์๊ธฐ ๋๋ฌธ์ header์ Payload_Length = 0x00000000 ๋ก ์ค์ ๋๋ค. |
pong | Ping์ ๋ฐ์ผ๋ฉด ์ฃผ์์ ๊ธฐํ ์ ๋ณด๋ฅผ ํฌํจํด ์๋ตํ๋ค.Port / IP_Address / Num Of Files Shared / Num of KB Shared** IP_Address - Big endian |
query | ๋คํธ์ํฌ์์์ ๊ฒ์์ ์ฐ์ด๊ณ ๊ฒ์ Minimum Speed ( ์๋ต์ ์ต์ ์๋ ), Search Criteria ๊ฒ์ ์กฐ๊ฑด |
queryHit | ๊ฒ์ Query ์กฐ๊ฑด๊ณผ ์ผ์นํ ๊ฒฝ์ฐ QueryHit๋ก ์๋ตํ๋ค. Num Of Hits ์กฐ๊ฑด์ ์ผ์นํ๋ Query์ ๊ฒฐ๊ณผ ์ Port / IP_Address (Big-endian) / Speed / Result Set File Index ( ํ์ผ ๋ฒํธ ) File Size ( ํ์ผ ํฌ๊ธฐ )File Name ( ํ์ผ ์ด / ๋๋ธ ๋๋ก ๋๋จ ) Servent Identifier ์๋ตํ๋ Servent์ ๊ณ ์ ์๋ณ์ Push ์ ์ฐ์ธ๋ค. |
push | ๋ฐฉํ๋ฒฝ์ด ์ค์น๋ Servent์์ ํต์ ์ ์ํ DescriptorServent Identifier / File Index / IP_Address(Big-endian)/Port |
1.3 ๋ช
๋ น์ด ๋ผ์ฐํ
- Pong ์ Ping์ด ์๋ ๊ฐ์ ๊ธธ์ ๋ฐ๋ผ ์ ์ก๋๋ค. ๋ง์ฝ DescriptorID๊ฐ n
์ธ Pong์ ๋ฐ์๋ ๋ฐ Descriptor ID๊ฐ n์ธ Ping ๋ณด์ง ๋ชปํ๋ค๋ฉด Ping์ ๋ณด
๋ธ Servent๋ ๋คํธ์ํฌ ์์์ ์ ๊ฑฐ๋ ๊ฒ์ ์๋ฏธํ๋ค.
- QueryHit์ Query -
- Push/QueryHit -
- ์ ๋ฌ ๋์๋ Ping๊ณผ Query๋ฅผ ์ ์ธํ๊ณ ๋ชจ๋ Ping๊ณผ Query๋ ์ฐ๊ฒฐ ๋
๋ชจ๋ Servent์ ์ ์ก๋๋ค.
- TTL/Hop์ ๋ค๋ฅธ Servent๋ก ์ ์ก๋๊ธฐ ์ ์ ๋ณ๊ฒฝ๋๋ฉฐ ํ์ TTL์ด
0์ด๋ฉด ๋ค๋ฅธ Servent๋ก ์ ์ก๋์ง ์๋๋ค.
- ์ ์ ์ ์ก๋ Descriptor๋ ๋ค์ ์ ์ก๋์ง ์๋๋ค. ๋คํธ์ํฌ ๋ถํ ์ค์
1.4 ํ์ผ ๋ค์ด๋ก๋
QueryHit ๋ช ๋ น์ด๋ฅผ ๋ฐ์ผ๋ฉด ํ์ผ์ ์ด๊ธฐํ ํ๊ณ ๋ค์ด๋ก๋๋ฅผ ์์ํ๋ค.
์ด๋ Gnutella ๋คํธ์ํฌ๋ฅผ ์ด์ฉํ๋ ๊ฒ์ด ์๋๋ผ ๊ธฐ์กด์ HTTP ํ๋กํ ์ฝ
์ ์ด์ฉํ์ฌ ์ง์ ํ์ผ์ด ์ ์ก๋๋ค.
GET/get/<File Index>/<File Name>/HTTP/1.0rn
Connection:Keep-Alivern
Range:bytes=0-rn
User-Agent:Gnutellarn3
rn
Range๊ฐ ํ์ผ์ ์ด์ด๋ฐ๊ธฐ๊ฐ ๊ฐ๋ฅํ๊ฒ ํจ.
<File Index>๋ ํ์ผ ๋ฒํธ์ด๊ณ ์ด๋ QueryHit Result์ ํฌํจ๋ ๋ด์ฉ์ด๋ค.
์ด์๊ฐ์ HTTP ํค๋๋ฅผ ๋ฐ์ผ๋ฉด ์๋ฒ๋ ๋ค์๊ณผ ๊ฐ์ ํค๋๋ฅผ ๋ณด๋ด์ค๋ค.
HTTP 200 OKrn
Server:Gnutellarn
Content-type:application/binaryrn
Content-length:435678rn
rn
๋ฐ๋ก ๋ค์์ ๋ฐ์ดํฐ๊ฐ Content-length๋งํผ ๋ฐ๋ผ์ค๊ฒ ๋๋ค.
1.5 ๋ฐฉํ๋ฒฝ์ด ์ค์น๋ Servents
๋ฐฉํ๋ฒฝ์ผ๋ก ์ธํด ์ง์ ์ฐ๊ฒฐ์ด ๋ถ๊ฐ๋ฅํ ๊ฒฝ์ฐ Push Descriptor๋ฅผ ๋ณด๋ด๊ณ ๋ผ์ฐํ ์ ํตํด ๋ฐ์
QueryHit์ ๋ํ ์๋ต์ผ๋ก ์๋ก์ด TCP/IP ์ฐ๊ฒฐ์ด ์๊ธด
๋ค.
์๋กญ๊ฒ ์ฐ๊ฒฐ ๋ ํ
GIV<File Index>:<Severnt Identifier>/<File Name>nn ๋ฅผ ๋ณด๋ด ํ์ผ
์ ์์ฒญํ๋ฉด
GET/get/<File Index>/<File Name>/HTTP1.0rn
Connection:Keep-Alivern
Range:bytes=0-rn
User-Agent:Gnutellarn3
rn
๊ณผ ๊ฐ์ HTTP GET requestํ์์ผ๋ก ์๋ต์ ํ๋ฉฐ ํ์ผ์ ์ ์กํ๋ค.
๊ทธ๋ฌ๋ Push Descriptor์กฐ์ฐจ ๋ณด๋ด์ง ๋ชปํ๋ฉด ํ์ผ์ ์ก์ ๋ถ๊ฐ๋ฅํ๋ค.
1.6 ํ์ฅ๋ Gnutella ํ๋กํ ์ฝ
๊ธฐ์กด์ Gnutella๊ฐ ๋ค๋ฅธ ํ๋ก๊ทธ๋จ(BearShare) ์ ์ํด ์๋น์ค ๋๋ฉด์
ํ์ฅ๋ ํ๋กํ ์ฝ ์ด ํ์ํ๊ฒ ๋์๋ค. ์ด๋ฅผ Triler๋ผ๊ณ ํ๋ฉฐ QueryHit ์
ResultSet ๋ง์ง๋ง ๋๋ธ๋ ๊ณผ Servent ID์ฌ์ด์ ๋ค์ด๊ฐ๋ค.
- Trailer
VendorCode(3byte) OpenDataSize(1byte) OpenData(2byte) PrivateData(n)
2.1 Data Structure
3. Gnucleus Technical DescriptionFile Name : Packet.Cpp
Common IP / ExIP / Node / NodeEx
GnutellaPacket packet_Header / packet_Ping / packet_Pong
2.2 Class Hierarchal DiagramCommon IP / ExIP / Node / NodeEx
GnutellaPacket packet_Header / packet_Ping / packet_Pong
Gnuclues๋ Gnutella ํ๋ก์ ํธ ์ค OpenSoure๋ก ์ค์ ์ธํฐํ์ด์ค ๋ถ๋ถ์ด ์ด์
ํ๋ค.
ํ์ง๋ง Gnucleus์ Core ์ฝ๋ ๋ถ๋ถ์ Docunment๊ฐ ๊ฐ์ฅ ์ ๋์์๊ณ ์ค์ ๋ก
Compile / Execute ๊ฐ๋ฅํ Code๋ฅผ ์์ ์ป์ ์ ์๋ ํ๋ก๊ทธ๋จ์ด๋ค. ๋ฌผ๋ก
์ง๊ธ ์ํ๋ ๋ฒ์ ์ ํธํ์ฑ์ผ๋ก ์ธํด Gnucleus node์ ์ค์ ๋ ธ๋์ ์ ์ํ๋ ๊ฒ์ด
์ด๋ ต์ง๋ง ๊ฐ์ ๋ฒ์ ์ฌ์ด์ ์ ์์ ๊ฐ๋ฅํ๋ฏ๋ก ์ธํฐํ์ด์ค ๋ถ๋ถ์ ์์ ํ๋ค๋ฉด
๋ณด๋ค ์ข์ ํ๋ก๊ทธ๋จ์ผ๋ก ๋ณํํ ์ ์์ ๊ฒ ๊ฐ๋ค.
๋ํ Entica์์ ํ์๋กํ๋ Search / MultiThreadDownloader๋ฅผ ์ง์ํ๋ฉฐ
๋ํ ๊ฐ์ฅ ๊ธฐ๋ณธ์ ์ธ ๊ธฐ๋ฅ์ ๊ตฌํํ์ฌ ๋ถํ์ํ ์์ค์ฝ๋๊ฐ ์ ๋ค๋ ์ฅ์ ๋ ์๋ค.
์ด๋ฐ ์ด์ ๋ก ๋ค๋ฅธ ๋ช๋ช Gnutella ํ๋ก๊ทธ๋จ๋ Gnucleus๋ฅผ ๊ธฐ๋ฐ์ผ๋ก ์์ฑ ๋์ด์ก๋ค.
4. Noteํ์ง๋ง Gnucleus์ Core ์ฝ๋ ๋ถ๋ถ์ Docunment๊ฐ ๊ฐ์ฅ ์ ๋์์๊ณ ์ค์ ๋ก
Compile / Execute ๊ฐ๋ฅํ Code๋ฅผ ์์ ์ป์ ์ ์๋ ํ๋ก๊ทธ๋จ์ด๋ค. ๋ฌผ๋ก
์ง๊ธ ์ํ๋ ๋ฒ์ ์ ํธํ์ฑ์ผ๋ก ์ธํด Gnucleus node์ ์ค์ ๋ ธ๋์ ์ ์ํ๋ ๊ฒ์ด
์ด๋ ต์ง๋ง ๊ฐ์ ๋ฒ์ ์ฌ์ด์ ์ ์์ ๊ฐ๋ฅํ๋ฏ๋ก ์ธํฐํ์ด์ค ๋ถ๋ถ์ ์์ ํ๋ค๋ฉด
๋ณด๋ค ์ข์ ํ๋ก๊ทธ๋จ์ผ๋ก ๋ณํํ ์ ์์ ๊ฒ ๊ฐ๋ค.
๋ํ Entica์์ ํ์๋กํ๋ Search / MultiThreadDownloader๋ฅผ ์ง์ํ๋ฉฐ
๋ํ ๊ฐ์ฅ ๊ธฐ๋ณธ์ ์ธ ๊ธฐ๋ฅ์ ๊ตฌํํ์ฌ ๋ถํ์ํ ์์ค์ฝ๋๊ฐ ์ ๋ค๋ ์ฅ์ ๋ ์๋ค.
์ด๋ฐ ์ด์ ๋ก ๋ค๋ฅธ ๋ช๋ช Gnutella ํ๋ก๊ทธ๋จ๋ Gnucleus๋ฅผ ๊ธฐ๋ฐ์ผ๋ก ์์ฑ ๋์ด์ก๋ค.
servent : server ์ client ์ ํฉ์ฑ์ด
little endian byte : ์์ ์ชฝ (๋ฐ์ดํธ ์ด์์ ๊ฐ์ฅ ์์ ๊ฐ)์ด ๋จผ์ ์ ์ฅ๋๋ ์์
descriptor : ํจํท์ด ๊ฐ๋ ์๋ฏธ
payload : ํจํท ๊ฐ๋ ๋ฐ์ดํ
5. ์ฐธ๊ณ URL
http://www.gnucleus.com/ (Gnucleus ํ๋ก๊ทธ๋จ)
http://www.sourceforge.net/ (Gnutella Clone ํ๋ก๊ทธ๋จ)
http://www.gnutelladev.com/source/gnucleus0.html (์์ค์ฝ๋)
CVS// http://cvs.sourceforge.net/cgi-bin/viewcvs.cgi/gnucleus/(์ต๊ทผ์ ์์ค์ฝ๋)
1.4. ๊ธฐํ ์ฝ๋์ ๊ดํ ์ค๋ช ¶
Gnucleus์์ ๋ค์ด๋ก๋ ๋ฐ๋ ๋ฐฉ๋ฒ์ ๋ํ ์ค๋ช
ํ์ผ์ ์ ํํ๊ณ ๊ทธ ๊ทธ๋ฃน์ ๊ฒฐ๊ณผ๊ฐ์ RelayDownload ํจ์์ ์ ๋ฌ์ธ์๋ก ๋ณด๋ธ๋ค.
๊ทธ๋ฌ๋ฉด View ์ Download์ ๊ดํ ํ์ด์ง๋ฅผ ์ ๋ฐ์ดํธํ๊ณ DownloadShell์ ์์ฑ์๊ฐ ์คํ์ด ๋๋ค.
~cpp void CSearchResults::OnButtonDownload() { std::list<ResultGroup>::iterator itGroup; POSITION pos = m_lstResults.GetFirstSelectedItemPosition(); while(pos) { int nItem = m_lstResults.GetNextSelectedItem(pos); ResultGroup* pGroup = (ResultGroup*) m_lstResults.GetItem(nItem); if(pGroup) RelayDownload(*pGroup); } }์์ ๋ค์ด๋ก๋ ๋ฒํผ์ ๋๋ฅด๋ฉด ๊ฒฐ๊ณผ ๊ทธ๋ฃน์ค์์ pos๋ฅผ ๊ธฐ์ตํ๊ณ ์ด pos๋ฅผ ์ด์ฉํด ๋ค์ด๋ฐ์
ํ์ผ์ ์ ํํ๊ณ ๊ทธ ๊ทธ๋ฃน์ ๊ฒฐ๊ณผ๊ฐ์ RelayDownload ํจ์์ ์ ๋ฌ์ธ์๋ก ๋ณด๋ธ๋ค.
~cpp void CSearchResults::RelayDownload(ResultGroup &Item) ์์๋ CGnuDownloadShell* Download = new CGnuDownloadShell(m_pComm);์์์ ๊ฐ์ด ์๋ก์ด ๋ค์ด๋ก๋ ์์ ๋ง๋ค๊ณ
~cpp m_pComm->m_DownloadList.push_back(Download);์ ๊ฐ์ด m_DownloadList์ Download ๊ฐ์ฒด๋ฅผ ์ฝ์ ํ๊ณ CGnuControl์์ ์ ์ดํ๊ฒ ๋ง๋ ๋ค.
~cpp Download->m_Name = Item.Name; Download->m_Search = ReSearch; Download->m_FileLength = Item.Size; Download->m_AvgSpeed = Item.AvgSpeed;๊ฐ์ด ์ด๊ธฐํ๋ฅผ ํ๋ค.
~cpp // Add hosts to the download list for(int i = 0; i < Item.ResultList.size(); i++) Download->AddHost( Item.ResultList[i] );์ฒ๋ผ DownloadShell์ AddHostํจ์๋ฅผ ํตํด Item์ ๋ชจ๋ Host๋ฅผ ๋ค์ด๋ก๋ ์ ๋ฃ๋๋ค.
๊ทธ๋ฌ๋ฉด View ์ Download์ ๊ดํ ํ์ด์ง๋ฅผ ์ ๋ฐ์ดํธํ๊ณ DownloadShell์ ์์ฑ์๊ฐ ์คํ์ด ๋๋ค.
CGnuControl์์์ void CGnuControl::ManageDownloads()์ ์ํด ์ ์ด๋๋ค.
void CGnuDownloadShell::Start() ๋ก ๋ค์ด๋ก๋๊ฐ ์์์ด ๋๊ณ ์ค์ ์ ์ธ ๋ค์ด๋ก๋๋ CGnuDownload์์ ์ด๋ฃจ์ด์ง๋ฉด ์์์๋ Timer()์์ CheckCompletion()๋ก ์๋ฃ ๋์๋ ์ง ํ์ธ์ ํ๊ฒ ๋๊ณ AttachChunk2Chunk ์ AttachChunk2Partial๋ก ๋ถ๋ถ๋ถ๋ถ ์๋ฃ๋ Chunk๋ค์ ๊ฒฐํฉํด ์ฃผ๋ ์ญํ์ ํ๊ฒ ๋๋ค.
์ค์ ์ ์ผ๋ก ํ๋์ Host๋ง๋ค CGnuDownload ํด๋์ค๋ฅผ ๊ฐ๊ฒ ๋๋ฉฐ ๋ฐ์ดํ๋ฅผ ๋ฐ๋ ์์ผ์ด ๋๋คm_StartPos๊ฐ ๋ฐ๊ธฐ ์์ํ๋ Chunk์ ์์์ ๋ํ๋ด๋ฉฐ ReadyFile()์์๋ ์ ์ ๋ฐ๋ ํ์ผ์ด ์๋ ์ง ์กฐ์ฌํ์ File์ ์ฐ๋ค.
StartDownload() ํจ์์์ ๋ค์ด๋ก๋๋ฅผ ์์ํ๋ฉฐ GetStartPos() ๋ฅผ ํตํด Chunk๊ฐ ๋ค์ด๋ก๋๊ฐ ์์ํ m_pChunk->m_StartPos์ ์์น๋ฅผ ์๊ฒ ํ๋ค.
SendRequest() ์์ HTTP/GET ํ์์ผ๋ก ํค๋๋ฅผ ๋ณด๋ด ๋ฐ๊ณ ์ ํ๋ ๋ฐ์ดํ๋ฅผ ์์ฒญํ๋ค
OnReceive(int nErrorCode) ์์ Content-length ๋งํผ์ ๋ฒํผ ๋ฐ์ดํ๋ฅผ ๋ฐ์ ์ฒญํฌ์ ์ฐ๊ฒฐ ์ํจ๋ค.
์ด์ด ๋ฐ๊ธฐ๋ฅผ ํ ๋์๋ ํ์ผ์ ๋์์ -4096๋งํผ ์ป๊ณ m_Verification ๋ธ๋ญ์ 4096ํฌ๊ธฐ ๋งํผ ๋น๊ต๋ฅผ ํ ํ์ ์ด์ด๋ฐ๊ธฐ๋ฅผ ์์ํ๋ค.
์๋ก์ด ์ฒญํฌ๋ฅผ ๋ง๋๋ ์กฐ๊ฑด์ ์ด๋ฏธ ์๋ฃ๋ ์ฒญํฌ์ ๋จ์ ๋ถ๋ถ์ด EmptySize > 16384 ๋ณด๋ค ์ปค์ผ
ํ๋ค๋ ๊ฒ์ด๋ค.
์์ค๋ ๋ค์๊ณผ ๊ฐ๊ณ
์๊ฐํ๊ณ m_pChunk = NULL๋ก ๋ง๋ ๋ค
void CGnuDownloadShell::Start() ๋ก ๋ค์ด๋ก๋๊ฐ ์์์ด ๋๊ณ ์ค์ ์ ์ธ ๋ค์ด๋ก๋๋ CGnuDownload์์ ์ด๋ฃจ์ด์ง๋ฉด ์์์๋ Timer()์์ CheckCompletion()๋ก ์๋ฃ ๋์๋ ์ง ํ์ธ์ ํ๊ฒ ๋๊ณ AttachChunk2Chunk ์ AttachChunk2Partial๋ก ๋ถ๋ถ๋ถ๋ถ ์๋ฃ๋ Chunk๋ค์ ๊ฒฐํฉํด ์ฃผ๋ ์ญํ์ ํ๊ฒ ๋๋ค.
์ค์ ์ ์ผ๋ก ํ๋์ Host๋ง๋ค CGnuDownload ํด๋์ค๋ฅผ ๊ฐ๊ฒ ๋๋ฉฐ ๋ฐ์ดํ๋ฅผ ๋ฐ๋ ์์ผ์ด ๋๋คm_StartPos๊ฐ ๋ฐ๊ธฐ ์์ํ๋ Chunk์ ์์์ ๋ํ๋ด๋ฉฐ ReadyFile()์์๋ ์ ์ ๋ฐ๋ ํ์ผ์ด ์๋ ์ง ์กฐ์ฌํ์ File์ ์ฐ๋ค.
StartDownload() ํจ์์์ ๋ค์ด๋ก๋๋ฅผ ์์ํ๋ฉฐ GetStartPos() ๋ฅผ ํตํด Chunk๊ฐ ๋ค์ด๋ก๋๊ฐ ์์ํ m_pChunk->m_StartPos์ ์์น๋ฅผ ์๊ฒ ํ๋ค.
~cpp m_StartPos = m_pShell->m_BytesCompleted + ((m_pShell->m_FileLength - m_pShell->m_BytesCompleted) / 2); m_pChunk->StartPos = m_StartPos; m_pChunk->FileLength = m_pShell->m_FileLength - m_StartPos;๊ณต์์ผ๋ก Chunk์ ์์์์น๋ฅผ ๊ตฌํ๋ค.
SendRequest() ์์ HTTP/GET ํ์์ผ๋ก ํค๋๋ฅผ ๋ณด๋ด ๋ฐ๊ณ ์ ํ๋ ๋ฐ์ดํ๋ฅผ ์์ฒญํ๋ค
OnReceive(int nErrorCode) ์์ Content-length ๋งํผ์ ๋ฒํผ ๋ฐ์ดํ๋ฅผ ๋ฐ์ ์ฒญํฌ์ ์ฐ๊ฒฐ ์ํจ๋ค.
์ด์ด ๋ฐ๊ธฐ๋ฅผ ํ ๋์๋ ํ์ผ์ ๋์์ -4096๋งํผ ์ป๊ณ m_Verification ๋ธ๋ญ์ 4096ํฌ๊ธฐ ๋งํผ ๋น๊ต๋ฅผ ํ ํ์ ์ด์ด๋ฐ๊ธฐ๋ฅผ ์์ํ๋ค.
์๋ก์ด ์ฒญํฌ๋ฅผ ๋ง๋๋ ์กฐ๊ฑด์ ์ด๋ฏธ ์๋ฃ๋ ์ฒญํฌ์ ๋จ์ ๋ถ๋ถ์ด EmptySize > 16384 ๋ณด๋ค ์ปค์ผ
ํ๋ค๋ ๊ฒ์ด๋ค.
์์ค๋ ๋ค์๊ณผ ๊ฐ๊ณ
~cpp // Reset m_pChunk because this can be called multiple times if(m_pChunk) { bool destroy = true; for(int i = 0; i < m_pShell->m_ChunkList.size(); i++) if(m_pShell->m_ChunkList[i] == m_pChunk) destroy = false; if(destroy) delete m_pChunk; m_pChunk = NULL; }๋ถ๋ถ์ ์์ผ์ ์ฒญํฌ์ค์ ์ง๊ธ์ ์ฒญํฌ๊ฐ ์๋ค๋ฉด ์ง๊ธ ๋ฐ์ ์ฒญํฌ๋ ๋๋ง์น ๊ฒ์ผ๋ก
์๊ฐํ๊ณ m_pChunk = NULL๋ก ๋ง๋ ๋ค
Gnucleus์์ ํ๋กํ ์ฝ ํต์
GnuCreateGuid(&Guid) // DescriptorID ์์ฑ
๋ผ์ฐํ ์ ์ฐ๊ฒฐ๋ ๋ชจ๋ nodeList์์ key->Origin๋ฅผ ์ฐพ์๋ด์ด key->Origin๋ฅผ ์ ์ธํ ๋ชจ๋ node์ ๋ฐ์ pong ๋๋ queryHit๋ฅผ ์ ๋ฌ
- Search
๋ผ์ฐํ ์ ์ฐ๊ฒฐ๋ ๋ชจ๋ nodeList์์ key->Origin๋ฅผ ์ฐพ์๋ด์ด key->Origin๋ฅผ ์ ์ธํ ๋ชจ๋ node์ ๋ฐ์ pong ๋๋ queryHit๋ฅผ ์ ๋ฌ
- Search
~cpp int length = 25 + m_Search.GetLength() + 1; pNode->SendPacket(m_Packet, length, PACKET_QUERY, true);- Result Set
~cpp // Extract results from the packet while(HitsLeft > 0 && NextPos < Length - 16) { Result Item; memcpy(&TempX, &Packet[NextPos], 4); Item.FileIndex = makeD( flipX(TempX)); memcpy(&TempX, &Packet[NextPos + 4], 4); Item.Size = makeD( flipX(TempX)); Item.Host = QueryHit->Host; Item.Port = QueryHit->Port; Item.Speed = makeD( flipX(QueryHit->Speed)); Item.Firewall = Firewall; Item.Busy = Busy; Item.Stable = Stable; Item.ActualSpeed = ActualSpeed; if(ExtendedPacket) Item.Vendor = Vendor; Item.Origin = Log->Origin; memcpy(&Item.PushID, &Packet[Length - 16], 16); Item.Distance = Log->Header->Hops; // Get Filename for(i = NextPos + 8; Packet[i] != 0; i++) if(i < Length - 16) Item.Name += (char) Packet[i]; else break; // Pass any data between double null while(Packet[++i] != 0) if(i > Length - 16) break; Item.NameLower = Item.Name; Item.NameLower.MakeLower(); Item.Icon = m_pDoc->GetIconIndex(Item.NameLower); m_WholeList.push_back(Item); // Screen Item to user's preferences if(Inspect(Item)) { m_CurrentList.push_back(Item); m_tabResults->UpdateList( AddtoGroup(Item) ); } // Check for end of reply packet if(i + 1>= Length - 16) HitsLeft = 0; else { HitsLeft--; NextPos = i + 1; } }ํจํท์ packet_QueryHit ์์ ResultSet์ ์ถ์ถํ์ฌ Item Vector์ ๋ฃ์ด์ค๋ค.
~cpp void CGnuNode::Recieve_Ping(packet_Ping* Ping, int nLength) key_Value* key = m_pComm->m_TableRouting.FindValue(&Ping->Header.Guid);ํตํด ๋ฐ์๋ ํ์ธ์ง ๊ฒ์ฌํ๊ณ if(key == NULL) ๋ฐ์๋ ํ์ด ์๋๋ผ ์๋ก์ด ํ์ด๋ผ๋ฉด m_pComm->m_TableRouting.Insert(&Ping->Header.Guid, this) ์ฒ๋ผ ๋ผ์ฐํ ํ ์ด๋ธ์ ๋ฃ๊ณ Pong์ ๋ณด๋ด์ค๋ค.
๋ฐฉํ๋ฒฝ์ด ์ค์น๋ ๊ฒฝ์ฐ์ ์์ธํ ์ค๋ช
๊ทธ๋ฆฌ๊ณ PUSH๋ฅผ Route PUSH๋ฅผ ํตํด ๋ณด๋ด ๊ทธ๋ํ ๋ผ default ํฌํธ๊ฐ ์๋ ์ด ์ ์๋ ํฌํธ๋ก ์ง์ ์ฐ๊ฒฐ์ ํ๋ค.
๋ง์ฝ ์๋๋ฐฉ ์๋ฒ๊ฐ FireWall์ ์๋ค๋ฉด QueryHit์ค์ bool Firewall;ํ๋๊ฐ True๊ฐ ๋๋ฏ๋ก ์ด์ ๋ํ ์๋ต์ผ๋ก
~cpp UINT AttemptPort = pPrefs->m_ForcedPort ? pPrefs->m_ForcedPort : pPrefs->m_LocalPort; AttemptPort += rand() % 99 + 0;Firewall์ ์์ ๊ฒฝ์ฐ ์ด๋ฐ ๋ฐฉ๋ฒ์ผ๋ก ํฌํธ๋ฅผ ์ด์ง ๋ชปํ๋ฉด ๋๋คํ ํฌํธ๋ฅผ ๋ถ์ฌ ForcedPort๋ก ์ ์ Attempts < 3 ๋งํผ ์๋๋ฅผ ํ๋ค.
๊ทธ๋ฆฌ๊ณ PUSH๋ฅผ Route PUSH๋ฅผ ํตํด ๋ณด๋ด ๊ทธ๋ํ ๋ผ default ํฌํธ๊ฐ ์๋ ์ด ์ ์๋ ํฌํธ๋ก ์ง์ ์ฐ๊ฒฐ์ ํ๋ค.
๋ง์ฝ ์๋๋ฐฉ ์๋ฒ๊ฐ FireWall์ ์๋ค๋ฉด QueryHit์ค์ bool Firewall;ํ๋๊ฐ True๊ฐ ๋๋ฏ๋ก ์ด์ ๋ํ ์๋ต์ผ๋ก
~cpp Item.Host = QueryHit->Host; Item.Port = QueryHit->Port;
์ ํด๋นํ๋ Port๋ก Download๋ฅผ ํ๋ค.