E D R , A S I H C RSS

Gnutella-More Free


파일 곡유 ν”„λ‘œν† μ½œμΈ Gnutella 에 λŒ€ν•œ 뢄석글

1. Gnutella-More Free


1.1. μ‹œμž‘μ— μ•žμ„œμ„œ

늦게 이 글을 올린 것에 λŒ€ν•΄ λΈμ•ˆν•˜λ‹€.
이 λ¬Έμ„œλŠ” λ‚΄κ°€ μ•„λ₯΄λ°”μ΄νŠΈλΌ ν•˜λ©΄μ„œ λ²ˆμ—­κ³Ό μž‘μ„±ν•œ λ¬Έμ„œμ΄λ‹€.
μ§€κΈˆμ˜ μŠ€νŽ™μ—μ„œλŠ” λΌμš°νŒ… λΆ€λΆ„μ˜ 맴과 캐쉬와 μ‰μ–΄μ—μ„œ λ§Žμ€ λΆ€λΆ„ μˆ˜μ •μ΄ κ°€ν•΄μ‘Œλ‹€.
λŒ€λΆ€λΆ„μ˜ P2P ν”„λ‘œκ·Έλž¨λ“€μ΄ λˆ„ν…”λΌμ˜ 방법을 기본으둜 μž‘μ„± λ˜μ—ˆμœΌλ©° μ§€κΈˆμ˜ μœ λ™μ 
IPλΌ κ°–λŠ” ν™˜κ²½μ—μ„œλŠ” μ΄λΌ λ›°μ–΄ λ„˜λŠ” 방법은 없을 κ²ƒμœΌλ‘œ 보여진닀.
후에 IPv6κ°€ λ‚˜μ˜¨λ‹€λ©΄ 각각의 μ‹œμŠ€ν…œμ΄ μ•„λ‹Œ μ–΄ν”Œλ¦¬μΌ€μ΄μ…˜μ— IPλΌ λΆ™μΌ 수 있게 λ˜μ–΄μ§„λ‹€κ³ 
읽은 적이 μžˆλ‹€. 이 λ•Œ 되면 보닀 획기적인 P2P ν”„λ‘œκ·Έλž¨μ΄ λ‚˜μ˜¬ κ²ƒμœΌλ‘œ 보인닀.

μ•„λž˜μ˜ 글은 κ°€λ³κ²Œ 읽어 μ£Όμ‹œκΈΈ....

1.2. 주인μž₯이 μƒκ°ν•˜λŠ” κ°€μž₯ 이상적인 P2Pλž€

κ·Έλˆ„ν…”λΌλŠ” ν™•μ‹€νžˆ 맀λ ₯적이고 λ˜ν•œ 이상적인 순수 P2PλΌλŠ” 생각이 λ“ λ‹€. ν•˜μ§€λ§Œ P2Pλž€ λ§Žμ€ λΆ€λΆ„
희생(?)이 ν•„μš”ν•˜λ‹€. μ—¬κΈ°μ„œ ν¬μƒμ΄λž€ λΆˆν•„μš”ν•˜μ§€λ§Œ μ“Έ 수 밖이 μ—†λŠ” λŒ€μ—­ν­μ„ λ§ν•œλ‹€.
λ‚΄κ°€ 찾고자 ν•˜λŠ” 파일이 λˆ„κ°€ 가지고 μžˆλŠ” 지 μ•Œκ³  μžˆλ‹€λ©΄ ꡳ이 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λΌ κΈ°λ°˜μœΌλ‘œ
μ΄μš©ν•˜μ—¬ 톡신이 이루어진닀.
- λ„€νŠΈμ›Œν¬λ§ 초기 μ§„μž… -
~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λŠ” νκΈ°λœλ‹€.

DescriptorID Payload Descriptor TTL hops PayloadLength
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 λͺ…λ Ήμ–΄ λΌμš°νŒ…
  1. Pong 은 Ping이 μ™”λ˜ 같은 길을 따라 μ „μ†‘λœλ‹€. λ§Œμ•½ DescriptorIDκ°€ n
    인 Pong을 λ°›μ•˜λŠ” 데 Descriptor IDκ°€ n인 Ping 보지 λͺ»ν–ˆλ‹€λ©΄ Ping을 보
    λ‚Έ ServentλŠ” λ„€νŠΈμ›Œν¬ μƒμ—μ„œ 제거된 것을 의λΈν•œλ‹€.
  2. QueryHit와 Query -
  3. Push/QueryHit -
  4. 전달 λ˜μ—ˆλ˜ Pingκ³Ό QueryλΌ μ œμ™Έν•˜κ³  λͺ¨λ“  Pingκ³Ό QueryλŠ” μ—°κ²° 된
    λͺ¨λ“  Servent에 μ „μ†‘λœλ‹€.
  5. TTL/Hop은 λ‹€λ₯Έ Servent둜 μ „μ†‘λ˜κΈ° 전에 λ³€κ²½λ˜λ©° 후에 TTL이
    0이면 λ‹€λ₯Έ Servent둜 μ „μ†‘λ˜μ§€ μ•ŠλŠ”λ‹€.
  6. 전에 μ „μ†‘λœ 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 연결이 생긴
  7. λ‹€.
    μƒˆλ‘­κ²Œ μ—°κ²° 된 ν›„
    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. Gnutella Core Code
2.1 Data Structure
File Name : Packet.Cpp
Common IP / ExIP / Node / NodeEx
GnutellaPacket packet_Header / packet_Ping / packet_Pong
packet_Push / packet_Query / packet_QueryHit

2.2 Class Hierarchal Diagram

3. Gnucleus Technical Description
GnucluesλŠ” Gnutella ν”„λ‘œμ νŠΈ 쀑 OpenSoure둜 μ‹€μ œ μΈν„°νŽ˜μ΄μŠ€ 뢀뢄이 μ—΄μ•…ν•˜λ‹€.
ν•˜μ§€λ§Œ Gnucleus의 Core μ½”λ“œ λΆ€λΆ„μ˜ Docunmentκ°€ κ°€μž₯ 잘 λ‚˜μ™€μžˆκ³  μ‹€μ œλ‘œ
Compile / Execute κ°€λŠ₯ν•œ CodeλΌ μ†μ— 얻을 수 μžˆλŠ” ν”„λ‘œκ·Έλž¨μ΄λ‹€. λ¬Όλ‘ 
μ§€κΈˆ μƒνƒœλŠ” λ²„μ „μ˜ ν˜Έν™˜μ„±μœΌλ‘œ 인해 Gnucleus node에 μ‹€μ œ λ…Έλ“œμ— μ ‘μ†ν•˜λŠ” 것이
μ–΄λ ΅μ§€λ§Œ 같은 버전 μ‚¬μ΄μ˜ 접속은 κ°€λŠ₯ν•˜λ€λ‘œ μΈν„°νŽ˜μ΄μŠ€ 뢀뢄을 μˆ˜μ •ν•œλ‹€λ©΄
보닀 쒋은 ν”„λ‘œκ·Έλž¨μœΌλ‘œ λ³€ν˜•ν•  수 μžˆμ„ 것 κ°™λ‹€.
λ˜ν•œ Enticaμ—μ„œ ν•„μš”λ‘œν•˜λŠ” Search / MultiThreadDownloaderλΌ μ§€μ›ν•˜λ©°
λ˜ν•œ κ°€μž₯ 기본적인 κΈ°λŠ₯을 κ΅¬ν˜„ν•˜μ—¬ λΆˆν•„μš”ν•œ μ†ŒμŠ€μ½”λ“œκ°€ μ λ‹€λŠ” μž₯점도 μžˆλ‹€.
이런 이유둜 λ‹€λ₯Έ λͺ‡λͺ‡ Gnutella ν”„λ‘œκ·Έλž¨λ„ GnucleusλΌ κΈ°λ°˜μœΌλ‘œ μž‘μ„± λ˜μ–΄μ‘Œλ‹€.

4. Note
servent : server 와 client 의 ν•©μ„±μ–΄
little endian byte : μž‘μ€ μͺ½ (λ°”μ΄νŠΈ μ—΄μ—μ„œ κ°€μž₯ μž‘μ€ κ°’)이 λ¨Όμ € μ €μž₯λ˜λŠ” μˆœμ„œ
descriptor : νŒ¨ν‚·μ΄ κ°–λŠ” 의λΈ
payload : νŒ¨ν‚· κ°–λŠ” 데이타

5. μ°Έκ³  URL

http://www.gnucleus.com/ (Gnucleus ν”„λ‘œκ·Έλž¨)

http://www.sourceforge.net/ (Gnutella Clone ν”„λ‘œκ·Έλž¨)




1.4. 기타 μ½”λ“œμ— κ΄€ν•œ μ„λͺ…



Gnucleusμ—μ„œ λ‹€μš΄λ‘œλ“œ λ°›λŠ” 방법에 λŒ€ν•œ μ„λͺ…
~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의 μœ„μΉ˜λΌ μ•Œκ²Œ ν•œλ‹€.
~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
~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을 보내μ€λ‹€.



방화벽이 μ„μΉ˜λœ 경우의 μžμ„Έν•œ μ„λͺ…
~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λΌ ν•œλ‹€.



1.5. Thread


1.6. 참고 링크

Valid XHTML 1.0! Valid CSS! powered by MoniWiki
last modified 2021-02-07 05:23:18
Processing time 0.0661 sec