'''
Created by Martin Vaško
part of BT library which should implement handshake methods.
'''
import socket
import time
import select
from random import randrange
from torrent_dht import get_myip
class TorrentHandshake:
'''
Torrent handshake class to process initial handshake with peer to prove
its connectivity and filter it from peer pool if non respondend.
'''
def __init__(self, port):
self.bt_socket = socket.socket(socket.AF_INET,
socket.SOCK_DGRAM,
socket.IPPROTO_UDP)
self.micro_socket = socket.socket(socket.AF_INET,
socket.SOCK_STREAM,
socket.IPPROTO_TCP)
self.bt_socket.bind(get_myip(), port)
def send_handshake(self, peer):
'''
send handshake message for bitTorrent connection
'''
FIXME split to create handshake message
def _int_to_bytes(data, bytes_len):
return data.to_bytes(bytes_len, "big")
message = bytes()
value = 4
ver = 1
message += _int_to_bytes(value << 4 | ver, 1)
message += _int_to_bytes(0, 1)
message += _int_to_bytes(randrange(0xffff), 2)
message += _int_to_bytes(int(time.time()), 4)
message += _int_to_bytes(0, 4)
message += _int_to_bytes(0xf000, 4)
message += _int_to_bytes(randrange(0xffff), 2)
message += _int_to_bytes(0, 2)
just to establish connection to get result of this, but handshake should be good to get positive or negative acknowledgment TODO hole punch, those messages are mostly filtered because of firewall
print("Connecting")
try:
self.bt_socket.sendto(message, (peer[1], peer[2]))
except OSError:
return True
try:
ready = select.select([self.bt_socket], [], [], 0.4)
except (OSError, ValueError, KeyboardInterrupt):
self.bt_socket.close()
return False
if ready[0]:
msg = self.bt_socket.recvfrom(1024)
else:
try:
self.micro_socket = socket.create_connection((peer[1],
peer[2]),
timeout=0.4)
except socket.error:
self.micro_socket.close()
return False
self.micro_socket.close()
return True
if msg:
self.bt_socket.close()
return True
self.bt_socket.close()
return False
Announce peers that we want to download torrent query_sock = self.init_socket(port[1] + 3200) for value in self.peer_announce.values(): self.torrent.query_announce_peer(value[0], self.infohash, (port[1] + 3200), query_sock) try: ready = select.select([query_sock], [], [], 0.1) except (OSError, ValueError): continue msg = None if ready[0]: msg, _ = query_sock.recvfrom(2048) else: continue
if not msg:
continue
msg = decode_krpc(msg)
if msg is None:
continue