rubtella 0.0.0

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore ADDED
@@ -0,0 +1,2 @@
1
+ .DS_Store
2
+ log
data/README ADDED
@@ -0,0 +1,5 @@
1
+ This is (will be) ruby client for gnutella network.
2
+
3
+ I'm doing it as my university project.
4
+
5
+ I haven't found any working ruby library for gnutella yet so I hope this one will be first :)
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.0.0
data/config/config.rb ADDED
@@ -0,0 +1,19 @@
1
+ module Rubtella
2
+ module Config
3
+
4
+ # generating guid
5
+ def self.generate_guid
6
+ guid = Array.new
7
+ 16.times { guid << rand(255)}
8
+
9
+ guid
10
+ end
11
+
12
+ IP_ADDRESS = "195.150.93.207"
13
+ PORT = 54321
14
+ GUID = generate_guid
15
+
16
+
17
+
18
+ end
19
+ end
data/lib/errors.rb ADDED
@@ -0,0 +1,4 @@
1
+ module Rubtella
2
+ class UnknownPayload < StandardError;end
3
+ class RubtellaError < StandardError;end
4
+ end
data/lib/http_data.rb ADDED
@@ -0,0 +1,53 @@
1
+ module Rubtella
2
+ module HTTPData
3
+ class Builder
4
+ attr_accessor :status, :headers, :data
5
+
6
+ def initialize status = "", headers = nil, data = ""
7
+ @status = String.new status
8
+ @headers = headers
9
+ @data = String.new data
10
+ end
11
+
12
+ def build
13
+ @http_data = Array.new
14
+ @http_data << @status
15
+ @http_data << "\r\n"
16
+ @headers.each {|k,v| @http_data << "#{k}: #{v}\r\n"}
17
+ @http_data << "\r\n"
18
+ @http_data << @data
19
+ @http_data.to_s
20
+ end
21
+ end
22
+
23
+ class Parser
24
+
25
+
26
+ attr_accessor :status, :headers, :data, :http_data, :peers
27
+
28
+ def initialize http_data
29
+ @http_data = http_data
30
+ parse
31
+ end
32
+
33
+ def parse
34
+ @headers = Hash.new
35
+ @peers = Array.new
36
+
37
+ headers, @data = @http_data.split("\r\n\r\n")
38
+ headers = headers.split("\r\n")
39
+ @status = headers.shift
40
+ headers.each {|h| k,v = h.split(": "); @headers[k] = v}
41
+ if up = @headers["X-Try-Ultrapeers"]
42
+ up.split(",").each {|u| ip,port = u.split(":"); @peers << Peer.new(ip,port)}
43
+
44
+ end
45
+
46
+ end
47
+
48
+ def ok?
49
+ @status =~ /200 OK/
50
+ end
51
+ end
52
+ end
53
+ end
data/lib/logger.rb ADDED
@@ -0,0 +1,36 @@
1
+ require 'rubygems'
2
+ require 'ruby-growl'
3
+ require 'logger'
4
+
5
+ class RubtellaLogger
6
+
7
+ def initialize
8
+ @rubylogger = init_logger
9
+ @growl = init_growl
10
+ end
11
+
12
+ def init_logger
13
+ log = Logger.new('log/rubtella.log')
14
+ log.level = Logger::INFO
15
+ log.formatter = proc{|s,t,p,m|"%5s [%s] (%s) %s :: %s\n" % [s, t.strftime("%Y-%m-%d %H:%M:%S"), $$, p, m]}
16
+ return log
17
+ end
18
+
19
+ def init_growl
20
+ g = Growl.new "localhost", "rubtela",
21
+ ["rubtella log"]
22
+ return g
23
+ end
24
+
25
+ def info(message)
26
+ begin
27
+ @rubylogger.info message
28
+ @growl.notify "rubtella log", "Rubtella", message
29
+ rescue
30
+ puts 'logger error'
31
+ end
32
+ end
33
+
34
+ end
35
+
36
+ @@logger = RubtellaLogger.new
data/lib/peer.rb ADDED
@@ -0,0 +1,11 @@
1
+ module Rubtella
2
+ class Peer
3
+ attr_accessor :ip, :port
4
+
5
+ def initialize(ip, port)
6
+ @ip = ip
7
+ @port = port.to_i
8
+ end
9
+
10
+ end
11
+ end
data/lib/rubtella.rb ADDED
@@ -0,0 +1,154 @@
1
+ #!/usr/bin/ruby
2
+ # ruby gnutella client
3
+
4
+ require 'socket'
5
+ require 'timeout'
6
+ require 'lib/logger'
7
+ require 'rubygems'
8
+ require 'ruby-debug'
9
+
10
+
11
+
12
+ module Rubtella
13
+
14
+ GNUTELLA_REQUEST = "GNUTELLA CONNECT/0.6"
15
+ GNUTELLA_RESPONSE_OK = "GNUTELLA/0.6 200 OK"
16
+
17
+
18
+
19
+ class Listener
20
+
21
+ include Socket::Constants
22
+
23
+ #listen for connection
24
+ def listen
25
+ server = TCPServer.new("0.0.0.0", PORT)
26
+
27
+
28
+ while (session = server.accept)
29
+
30
+
31
+ Thread.start do
32
+
33
+ begin
34
+ parse_request session
35
+ rescue => e
36
+ session.puts "Rubtella Server Error: " + e.to_s
37
+ puts "Rubtella Server Error: " + e.to_s
38
+ ensure
39
+ session.close
40
+ end
41
+
42
+ end
43
+ end #end loop
44
+
45
+ end
46
+
47
+ def parse_request request
48
+ req = request.recv 1000
49
+
50
+ puts req
51
+ request.send Sender.pong, 0
52
+ puts 'response send!'
53
+ req = request.recv 1000
54
+ puts 'received content:'
55
+
56
+ puts req
57
+ puts 'received!'
58
+ end
59
+
60
+ end
61
+
62
+ class Sender
63
+
64
+
65
+ attr_accessor :peer, :connected
66
+
67
+ def initialize peer
68
+ @peer = peer
69
+ @standard_headers = {"User-Agent" => "Rubtella",
70
+ "X-Ultrapeer" => "False",
71
+ "X-Query-Routing" => "0.1"}
72
+ end
73
+
74
+ def connect
75
+ begin
76
+ puts "connecting to: #{@peer.ip}:#{@peer.port}"
77
+ stream = TCPSocket.new @peer.ip, @peer.port
78
+ timeout(5) do
79
+ stream.send handshake_req, 0
80
+ end
81
+ @response = stream.recv 1000
82
+
83
+ resp = HTTPData::Parser.new @response
84
+ stream.send handshake_resp, 0
85
+
86
+ if resp.ok?
87
+ #connection established
88
+ puts 'connection established'
89
+ @connected = @peer
90
+ puts "Connected with #{@connected.ip} #{@connected.port}"
91
+ @@logger.info "Connected with #{@connected.ip} #{@connected.port}"
92
+
93
+ manage_connection stream
94
+ else
95
+ puts 'failed to connect'
96
+ @peer = resp.peers.shift
97
+ connect
98
+ end
99
+ rescue Timeout::Error
100
+ @peer = resp.peers.shift
101
+ connect
102
+ rescue => e
103
+ @@logger.info e.to_s
104
+ end
105
+ end
106
+
107
+ def handshake_req
108
+ req = HTTPData::Builder.new GNUTELLA_REQUEST, @standard_headers
109
+ req.build
110
+ end
111
+
112
+ def handshake_resp
113
+ resp = HTTPData::Builder.new GNUTELLA_RESPONSE_OK, @standard_headers
114
+ resp.build
115
+ end
116
+
117
+ def manage_connection stream
118
+ loop do
119
+ puts 'we\'re listening..'
120
+ resp = stream.recv 1000
121
+ if parse(resp) == "ping"
122
+ pong = TCPData::Builder::Pong.new
123
+ stream.send pong.build , 0
124
+ puts 'pong send..'
125
+ stream.close
126
+ puts 'connection closed'
127
+ break
128
+ end
129
+ end
130
+
131
+
132
+
133
+ end
134
+
135
+ def parse message
136
+ parsed = TCPData::Parser.new message
137
+ puts parsed.message
138
+
139
+ parsed.message
140
+
141
+ end
142
+
143
+ def send_query(text)
144
+ stream = TCPSocket.new @connected.ip, @connected.port
145
+ query = TCPData::Builder::Query.new(:criteria => text)
146
+ @@logger.info "sending query - #{text}"
147
+ stream.send query.build, 0
148
+ puts 'we\'re listening..'
149
+ resp = stream.recv 1000
150
+ parse(resp)
151
+ end
152
+ end
153
+
154
+ end
data/lib/tcp_data.rb ADDED
@@ -0,0 +1,155 @@
1
+ require 'config/config'
2
+
3
+ module Rubtella
4
+ module TCPData
5
+ class Base
6
+ include Rubtella::Config
7
+ attr_accessor :guid, :payload_type, :ttl, :hops, :payload_lenght, :binary_data, :messages, :messages_codes, :rest
8
+
9
+ @messages ={"\000" => "ping",
10
+ "\001" => "pong",
11
+ "\100" => "push",
12
+ "\200" => "query",
13
+ "\201" => "query_hit"}
14
+
15
+ @messages.default = "Unknown Payload Type"
16
+
17
+ @messages_codes = {"ping" => 0,
18
+ "pong" => 1,
19
+ "push" => 64,
20
+ "query" => 128,
21
+ "query_hit" =>129}
22
+
23
+ @messages_codes.default = "Unknown Payload Type"
24
+ end
25
+
26
+ class Builder < Base
27
+ def init_messages_codes
28
+ @messages_codes = {"ping" => 0,
29
+ "pong" => 1,
30
+ "push" => 64,
31
+ "query" => 128,
32
+ "query_hit" =>129}
33
+
34
+ @messages_codes.default = "Unknown Payload Type"
35
+ end
36
+
37
+
38
+ def initialize
39
+ #initailze all stuff
40
+ init_messages_codes
41
+
42
+ @guid = GUID
43
+ @ttl = 5
44
+ @hops = 0
45
+ @payload_length = 0
46
+ end
47
+
48
+ def build
49
+ @data = Array.new
50
+ @guid = GUID
51
+
52
+ build_message
53
+
54
+ @data = [@guid, @payload_type, @ttl, @hops, @payload_length, @payload]
55
+
56
+ @binary_data = @data.flatten.pack("C*")
57
+ @binary_data
58
+ end
59
+
60
+ def build_message
61
+ # this method needs to be implemented by a child class
62
+ @payload = []
63
+ end
64
+
65
+
66
+ class Ping < Builder
67
+ def initialize args = nil
68
+ super()
69
+
70
+ @payload_type = @messages_codes["ping"]
71
+ end
72
+ end
73
+
74
+ class Pong < Builder
75
+
76
+ attr_accessor :ip_address , :port
77
+
78
+ def initialize args = nil
79
+ super()
80
+
81
+ @payload_type = @messages_codes["pong"]
82
+ @port = build_port PORT
83
+ @ip_address = build_ip IP_ADDRESS
84
+ @files_amount = [0,0,0]
85
+ @files_size = [0,0,0]
86
+
87
+ end
88
+
89
+ def build_message
90
+ @payload = [@port, @ip_address, @files_amount, @files_size]
91
+ end
92
+
93
+ def build_port(port)
94
+ [port%256, port/256]# .pack("C*")
95
+ end
96
+
97
+ def build_ip(ip_address)
98
+ ip_address.split(".").collect {|b| b.to_i} # .pack("C*")
99
+ end
100
+ end
101
+
102
+ class Query < Builder
103
+
104
+ def initialize args = nil
105
+
106
+ super()
107
+
108
+ @payload_type = @messages_codes["query"]
109
+ @speed = 0
110
+ @criteria = args.is_a?(Hash) ? args[:criteria] : ""
111
+
112
+ end
113
+
114
+ def build_message
115
+ @payload = [@speed, @criteria.unpack("C*")]
116
+ end
117
+
118
+ end
119
+
120
+ end
121
+ class Parser < Base
122
+
123
+ def initialize data
124
+ @binary_data = data
125
+ parse
126
+ end
127
+
128
+ def parse
129
+ @guid = @binary_data[0..15]
130
+ @payload_type = @binary_data[16..16]
131
+ @ttl = @binary_data[17..17]
132
+ @hops = @binary_data[18..18]
133
+ @payload_lenght = @binary_data[19..22]
134
+ @payload = @binary_data[23..-1]
135
+ end
136
+
137
+ def message
138
+ case @payload_type
139
+ when "\000"
140
+ "ping"
141
+ when "\001"
142
+ "pong"
143
+ when "\100"
144
+ "push"
145
+ when "\200"
146
+ "query"
147
+ when "\201"
148
+ "query"
149
+ else
150
+ raise "Unknown Payload Type"
151
+ end
152
+ end
153
+ end
154
+ end
155
+ end
data/rubtella.rb ADDED
@@ -0,0 +1,6 @@
1
+ require 'config/config'
2
+ require 'lib/errors'
3
+ require 'lib/peer'
4
+ require 'lib/tcp_data'
5
+ require 'lib/http_data'
6
+ require 'lib/rubtella'
data/rubtellad.rb ADDED
@@ -0,0 +1,24 @@
1
+ require 'rubtella'
2
+
3
+ $0 = 'rubtella-base'
4
+
5
+ @p = fork do
6
+ $0 = 'rubtella'
7
+ Thread.new do
8
+ server = Rubtella::Listener.new
9
+ server.listen
10
+ end
11
+
12
+ Thread.new do
13
+ gnutella = Rubtella::Sender.new Rubtella::Peer.new("70.188.16.73",38093)
14
+ gnutella.connect
15
+ gnutella.send_query("doors")
16
+ end
17
+
18
+ while true
19
+ sleep 100
20
+ end
21
+ end
22
+
23
+ Process.detach(@p)
24
+
metadata ADDED
@@ -0,0 +1,66 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: rubtella
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.0
5
+ platform: ruby
6
+ authors:
7
+ - Mateusz Zawisza
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2010-01-10 00:00:00 +01:00
13
+ default_executable:
14
+ dependencies: []
15
+
16
+ description: Library for Gnuttale in Ruby
17
+ email: mateusz.zawisza@gmail.com
18
+ executables: []
19
+
20
+ extensions: []
21
+
22
+ extra_rdoc_files:
23
+ - README
24
+ files:
25
+ - .gitignore
26
+ - README
27
+ - VERSION
28
+ - config/config.rb
29
+ - lib/errors.rb
30
+ - lib/http_data.rb
31
+ - lib/logger.rb
32
+ - lib/peer.rb
33
+ - lib/rubtella.rb
34
+ - lib/tcp_data.rb
35
+ - rubtella.rb
36
+ - rubtellad.rb
37
+ has_rdoc: true
38
+ homepage: http://github.com/mateuszzawisza/rubtella/
39
+ licenses: []
40
+
41
+ post_install_message:
42
+ rdoc_options:
43
+ - --charset=UTF-8
44
+ require_paths:
45
+ - lib
46
+ required_ruby_version: !ruby/object:Gem::Requirement
47
+ requirements:
48
+ - - ">="
49
+ - !ruby/object:Gem::Version
50
+ version: "0"
51
+ version:
52
+ required_rubygems_version: !ruby/object:Gem::Requirement
53
+ requirements:
54
+ - - ">="
55
+ - !ruby/object:Gem::Version
56
+ version: "0"
57
+ version:
58
+ requirements: []
59
+
60
+ rubyforge_project:
61
+ rubygems_version: 1.3.5
62
+ signing_key:
63
+ specification_version: 3
64
+ summary: Library for Gnuttale in Ruby
65
+ test_files: []
66
+