Class: Torrenter::Tracker::UDPTracker

Inherits:
Torrenter::Tracker show all
Defined in:
lib/torrenter/tracker/udp_tracker.rb

Instance Attribute Summary collapse

Attributes inherited from Torrenter::Tracker

#address

Instance Method Summary collapse

Methods inherited from Torrenter::Tracker

#format_peers

Constructor Details

#initialize(tracker, params) ⇒ UDPTracker

Returns a new instance of UDPTracker.



7
8
9
10
11
12
13
# File 'lib/torrenter/tracker/udp_tracker.rb', line 7

def initialize(tracker, params)
  @url           = tracker[/(?<=udp\:\/\/).+(?=\:\d+)/]
  @port          = tracker[/\d+$/].to_i
  @socket        = UDPSocket.new
  @connection_id = [0x41727101980].pack("Q>")
  @params        = params
end

Instance Attribute Details

#intervalObject (readonly)

Returns the value of attribute interval.



5
6
7
# File 'lib/torrenter/tracker/udp_tracker.rb', line 5

def interval
  @interval
end

#responseObject (readonly)

Returns the value of attribute response.



5
6
7
# File 'lib/torrenter/tracker/udp_tracker.rb', line 5

def response
  @response
end

#socketObject (readonly)

Returns the value of attribute socket.



5
6
7
# File 'lib/torrenter/tracker/udp_tracker.rb', line 5

def socket
  @socket
end

Instance Method Details

#announce_inputObject



94
95
96
# File 'lib/torrenter/tracker/udp_tracker.rb', line 94

def announce_input
  @connection_id + segment(1) + @transaction_id + @params[:info_hash] + PEER_ID
end

#announce_msgObject



102
103
104
# File 'lib/torrenter/tracker/udp_tracker.rb', line 102

def announce_msg
  announce_input + (segment(0, "Q>") * 3) + (segment(0) * 3) + segment(-1) + segment(@socket.addr[1], ">S")
end

#bound_peersObject



52
53
54
55
56
57
58
59
60
# File 'lib/torrenter/tracker/udp_tracker.rb', line 52

def bound_peers
  @connection_id = @response[-8..-1]
  @transaction_id = [rand(10000)].pack("I>")
  send_msg(announce_msg)

  read_response

  parse_announce if @response[0..3] == segment(1)
end

#connectObject



23
24
25
26
27
28
29
30
31
32
33
34
# File 'lib/torrenter/tracker/udp_tracker.rb', line 23

def connect
  @transaction_id = segment(rand(10000), "I>")
  @socket.connect(ip_addr, @port)
  begin
    send_msg(connect_msg)
    read_response
    bound_peers
  rescue
    false
  end
  return self
end

#connect_match?Boolean

Returns:

  • (Boolean)


90
91
92
# File 'lib/torrenter/tracker/udp_tracker.rb', line 90

def connect_match?
  data[0] == (segment(0) + @transaction_id + @connection_id)
end

#connect_msgObject



98
99
100
# File 'lib/torrenter/tracker/udp_tracker.rb', line 98

def connect_msg
  @connection_id + segment(0) + @transaction_id
end

#connected?Boolean

Returns:

  • (Boolean)


44
45
46
# File 'lib/torrenter/tracker/udp_tracker.rb', line 44

def connected?
  @response
end

#interval?Boolean

Returns:

  • (Boolean)


15
16
17
# File 'lib/torrenter/tracker/udp_tracker.rb', line 15

def interval?
  interval % Time.now.to_i == 0
end

#ip_addrObject



48
49
50
# File 'lib/torrenter/tracker/udp_tracker.rb', line 48

def ip_addr
  Socket.getaddrinfo(@url, @port)[0][3]
end

#parse_announceObject



66
67
68
69
70
71
72
73
# File 'lib/torrenter/tracker/udp_tracker.rb', line 66

def parse_announce
  if @response[4..7] == @transaction_id
    @interval = @response[8..11].unpack("I>").first
    res = @response.slice!(0..11)
    @leechers = @response.slice!(0..3).unpack("I>").first
    @seeders  = @response.slice!(0..3).unpack("I>").first
  end
end

#peer_listObject



62
63
64
# File 'lib/torrenter/tracker/udp_tracker.rb', line 62

def peer_list
  format_peers(@response)
end

#read_responseObject



82
83
84
85
86
87
88
# File 'lib/torrenter/tracker/udp_tracker.rb', line 82

def read_response
  begin
    @response = @socket.recv(1028)
  rescue Exception => e
    e
  end
end

#segment(e, enc = "I>") ⇒ Object



19
20
21
# File 'lib/torrenter/tracker/udp_tracker.rb', line 19

def segment(e, enc="I>")
  [e].pack(enc)
end

#send_messageObject



75
76
77
78
79
80
# File 'lib/torrenter/tracker/udp_tracker.rb', line 75

def send_message
  begin
    @socket.send(@msg, 0)
  rescue *EXCEPTIONS
  end
end

#send_msg(msg) ⇒ Object



36
37
38
39
40
41
42
# File 'lib/torrenter/tracker/udp_tracker.rb', line 36

def send_msg(msg)
  begin
    @socket.send(msg, 0)
  rescue
    false
  end
end