본문 바로가기

기타/토렌트

Extension for Peers to Send Metadata Files (BEP-0009)

bep_0009.rst_post (bittorrent.org)

 

bep_0009.rst_post

Post-History:14-Oct-2012: point out that unrecognized message types should be ignored 16-May-2016: added peer source parameter to magnets

www.bittorrent.org

개요

비트토렌트의 확장(Extension)으로 토렌트 파일을 없이도 네트워크 군(swarm)에 들어가고 다른 피어로부터 메타데이터를 다운로드할 수 있는 기능을 제공한다. 메타데이터는 토렌트 파일이 제공하는 데이터를 의미한다.

 

메타데이터

DHT를 통해서 피어간에 공유되는 메타데이터는 토렌트 파일의 "info-dictionary" 부분이다. 그 외에 토렌트 파일의 정보는 공유하지 않는다. 메타데이터 여러개의 조각으로 구성되어 있으며 16KiB 크기를 가지고 있다. 조각은 0번 인덱스부터 시작하며 만약 메타데이터 크기가 16KiB가 아니면 마지막 메타데이터의 조각으로 간주한다.

메타데이터를 모두 다운로드 받고 해시를 계산하면 infohash 값과 동일하다.

 

메타데이터가 50KiB의 크기를 가지고 있다면 다음과 같이 구분할 수 있다.

0번 조각 - 메타데이터 (16KiB)

1번 조각 - 메타데이터 (16KiB)

2번 조각 - 메타데이터 (16KiB)

3번 조각 - 메타데이터 (2KiB)

 

 

확장 헤더 (비트토렌트 확장 프로토콜에 메타데이터 확장 헤더를 추가)

메타데이터 확장 기능은 비트토렌트의 확장 프로토콜(BEP-0010)을 사용하여 작동한다.

비트토렌트 확장 프로토콜에 핸드쉐이크 과정에서 "ut_metadata", "m", "metadata_size" 키를 가지는 딕셔너리를 추가한다. 이를 통해 받은 확장 프로토콜 메세지에 "ut_metadata", "m", "metadata_size" 키가 있다면 메타데이터 확장 메시지임을 파악할 수 있다.

{'m': {'ut_metadata', 3}, 'metadata_size': 31235}

 

확장 메세지

확장 메세지는 기본적으로 bencode로 인코딩되어 있다.

메타데이터 확장 메세지의 유형은 다음과 같으며 메세지의 유형은 "msg_type" 이라는 키에 저장된다.

추가로 "piece" 키가 있으며 이 키는 메타데이터 부분 중 어디 부분인지를 알려준다.

 

0 = request

1 = data

2 = reject

 

request(msg_type=0)

메타데이터를 가지고 있는 피어에게 보낼때 추가되는 값은 없으며 피어에게 request를 보내면 data나 reject 중 하나를 응답한다. data 응답을 받을 때에는 request시 보낸 "piece"와 응답에서 받은 "piece"가 반드시 일치해야한다.

 

또한 자기가 메타데이터를 받고 있는 중간에 다른 피어로부터 동일한 infohash에 대한 메타데이터를 요청(request) 받았다면 거절(reject) 해야한다. 왜냐면 메타데이터를 이용해 해시를 구하면 infohash와 동일한 값이 나오는데 동일한 값이 나오려면 메타데이터를 모두 다운로드 받고 그때 해시를 계산해야하기 때문이다. 따라서 메타데이터를 모두 받지않았을때 해시를 계산하면 infohash와 다른 해시값이 나온다. 만약 검증을 안한다면 공격자가 마음먹고 다른 메타데이터를 넘겨줄 수 있게 되며 다운로드 중간에 들어오는 요청(request)을 거절(reject)하지 않는다면 공격자가 준 메타데이터를 넘기게되기 때문에 잘못된 데이터를 공유하게 된다.

 

request 데이터 예시

{'msg_type': 0, 'piece': 0}  # 딕셔너리
d8:msg_typei0e5:piecei0ee  # bencode로 인코딩된 딕셔너리

 

data(msg_type=1)

요청한 피어에게 보낼때 "total_size" 키를 추가해서 보내며 값은 정수형을 넣는다. "total_size"은 위에 핸드쉐이크 과정에서 추가하는 "metadata_size"와 동일한 형태를 가진다.

 

예시

{'msg_type': 1, 'piece': 0, 'total_size': 3425}  # 딕셔너리
d8:msg_typei1e5:piecei0e10:total_sizei34256eexxxxx...  # bencode로 인코딩된 딕셔너리 + 메타데이터(바이너리)

이런식으로 bencode + 메타데이터(바이너리)를 바로 붙여서 보내며 bencode의 마지막 부분을 표현하는 e 이후에 xxx.. 부분임을 확인할 수 있다.

 

 

reject(msg_type=2)

request 메세지와 동일하게 추가되는 값은 없으며 너무 많은 요청이 발생하거나 요청한 infohash에 해당하는 메타데이터가 없으면 보내는 메세지이다.

 

예시

{'msg_type': 2, 'piece': 0}  # 딕셔너리 형태
d8:msg_typei1e5:piecei0ee  # bencode로 인코딩된 딕셔너리

 

 

* BEP-0009에는 마그넷 URL 포맷도 정의되어 있지만 마그넷은 나중에 별도로 다룰 예정이다.

 

 

'기타 > 토렌트' 카테고리의 다른 글

Extension Protocol (BEP-0010)  (0) 2020.12.17
Mainline DHT Protocol (BEP-0005)  (0) 2020.11.30