torchat 0.0.1.rc.1
Sign up to get free protection for your applications and to get access to all the features.
- data/README.md +43 -0
- data/bin/torchatd +537 -0
- data/doc/protocol/broadcast.md +26 -0
- data/doc/protocol/groupchat.md +140 -0
- data/doc/protocol/latency.md +30 -0
- data/doc/protocol/standard.md +279 -0
- data/doc/protocol/typing.md +41 -0
- data/etc/torchat.yml +12 -0
- data/lib/torchat.rb +239 -0
- data/lib/torchat/protocol.rb +256 -0
- data/lib/torchat/protocol/broadcast.rb +40 -0
- data/lib/torchat/protocol/groupchat.rb +197 -0
- data/lib/torchat/protocol/latency.rb +44 -0
- data/lib/torchat/protocol/standard.rb +367 -0
- data/lib/torchat/protocol/typing.rb +36 -0
- data/lib/torchat/session.rb +603 -0
- data/lib/torchat/session/broadcast/message.rb +50 -0
- data/lib/torchat/session/broadcasts.rb +72 -0
- data/lib/torchat/session/buddies.rb +152 -0
- data/lib/torchat/session/buddy.rb +343 -0
- data/lib/torchat/session/buddy/joined_group_chat.rb +42 -0
- data/lib/torchat/session/buddy/joined_group_chats.rb +46 -0
- data/lib/torchat/session/buddy/latency.rb +54 -0
- data/lib/torchat/session/event.rb +79 -0
- data/lib/torchat/session/file_transfer.rb +173 -0
- data/lib/torchat/session/file_transfer/block.rb +51 -0
- data/lib/torchat/session/file_transfers.rb +89 -0
- data/lib/torchat/session/group_chat.rb +123 -0
- data/lib/torchat/session/group_chat/participant.rb +38 -0
- data/lib/torchat/session/group_chat/participants.rb +52 -0
- data/lib/torchat/session/group_chats.rb +74 -0
- data/lib/torchat/session/incoming.rb +187 -0
- data/lib/torchat/session/outgoing.rb +102 -0
- data/lib/torchat/tor.rb +107 -0
- data/lib/torchat/utils.rb +87 -0
- data/lib/torchat/version.rb +24 -0
- data/test/file_transfer/receiver.rb +41 -0
- data/test/file_transfer/sender.rb +45 -0
- data/test/group_chat/a.rb +37 -0
- data/test/group_chat/b.rb +37 -0
- data/test/group_chat/c.rb +57 -0
- data/torchat.gemspec +21 -0
- metadata +140 -0
@@ -0,0 +1,89 @@
|
|
1
|
+
#--
|
2
|
+
# Copyleft meh. [http://meh.paranoid.pk | meh@paranoici.org]
|
3
|
+
#
|
4
|
+
# This file is part of torchat for ruby.
|
5
|
+
#
|
6
|
+
# torchat for ruby is free software: you can redistribute it and/or modify
|
7
|
+
# it under the terms of the GNU Affero General Public License as published
|
8
|
+
# by the Free Software Foundation, either version 3 of the License, or
|
9
|
+
# (at your option) any later version.
|
10
|
+
#
|
11
|
+
# torchat for ruby is distributed in the hope that it will be useful,
|
12
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
13
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
14
|
+
# GNU Affero General Public License for more details.
|
15
|
+
#
|
16
|
+
# You should have received a copy of the GNU Affero General Public License
|
17
|
+
# along with torchat for ruby. If not, see <http://www.gnu.org/licenses/>.
|
18
|
+
#++
|
19
|
+
|
20
|
+
require 'stringio'
|
21
|
+
|
22
|
+
require 'torchat/session/file_transfer'
|
23
|
+
|
24
|
+
class Torchat; class Session
|
25
|
+
|
26
|
+
class FileTransfers < Hash
|
27
|
+
attr_reader :session
|
28
|
+
|
29
|
+
def initialize (session)
|
30
|
+
@session = session
|
31
|
+
end
|
32
|
+
|
33
|
+
def receive (id, name, size, sender = nil)
|
34
|
+
if has_key? id
|
35
|
+
raise ArgumentError, 'file transfer with same id already exists'
|
36
|
+
end
|
37
|
+
|
38
|
+
FileTransfer.new(id, name, size).tap {|ft|
|
39
|
+
ft.from = sender
|
40
|
+
|
41
|
+
self[ft.id] = ft
|
42
|
+
|
43
|
+
fire :file_transfer_start, file_transfer: ft
|
44
|
+
}
|
45
|
+
end
|
46
|
+
|
47
|
+
def send_file (buddy, path)
|
48
|
+
unless File.readable?(path)
|
49
|
+
raise ArgumentError, "#{path} is unreadable"
|
50
|
+
end
|
51
|
+
|
52
|
+
FileTransfer.new(self, File.basename(path), File.size(path)).tap {|ft|
|
53
|
+
ft.to = buddy
|
54
|
+
ft.input = File.open(path)
|
55
|
+
|
56
|
+
start_sending(self[ft.id] = ft)
|
57
|
+
}
|
58
|
+
end
|
59
|
+
|
60
|
+
def send_blob (buddy, data, name = Torchat.new_cookie)
|
61
|
+
self[id] = FileTransfer.new(self, name, data.size).tap {|ft|
|
62
|
+
ft.to = buddy
|
63
|
+
ft.input = StringIO.new(data)
|
64
|
+
|
65
|
+
start_sending(self[ft.id] = ft)
|
66
|
+
}
|
67
|
+
end
|
68
|
+
|
69
|
+
def stop (id)
|
70
|
+
unless file_transfer = self[id]
|
71
|
+
raise ArgumentError, 'unexistent file transfer'
|
72
|
+
end
|
73
|
+
|
74
|
+
delete(file_transfer.stop.id)
|
75
|
+
end
|
76
|
+
|
77
|
+
private
|
78
|
+
def start_sending (file_transfer)
|
79
|
+
session.fire :file_transfer_start, file_transfer: file_transfer
|
80
|
+
|
81
|
+
file_transfer.to.send_packet :filename, file_transfer.name, file_transfer.size, file_transfer.block_size, file_transfer.id
|
82
|
+
|
83
|
+
file_transfer.next_block.tap {|block|
|
84
|
+
file_transfer.to.send_packet :filedata, file_transfer.id, block.offset, block.data, block.md5
|
85
|
+
}
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
end; end
|
@@ -0,0 +1,123 @@
|
|
1
|
+
#--
|
2
|
+
# Copyleft meh. [http://meh.paranoid.pk | meh@paranoici.org]
|
3
|
+
#
|
4
|
+
# This file is part of torchat for ruby.
|
5
|
+
#
|
6
|
+
# torchat for ruby is free software: you can redistribute it and/or modify
|
7
|
+
# it under the terms of the GNU Affero General Public License as published
|
8
|
+
# by the Free Software Foundation, either version 3 of the License, or
|
9
|
+
# (at your option) any later version.
|
10
|
+
#
|
11
|
+
# torchat for ruby is distributed in the hope that it will be useful,
|
12
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
13
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
14
|
+
# GNU Affero General Public License for more details.
|
15
|
+
#
|
16
|
+
# You should have received a copy of the GNU Affero General Public License
|
17
|
+
# along with torchat for ruby. If not, see <http://www.gnu.org/licenses/>.
|
18
|
+
#++
|
19
|
+
|
20
|
+
require 'forwardable'
|
21
|
+
|
22
|
+
class Torchat; class Session
|
23
|
+
|
24
|
+
class GroupChat
|
25
|
+
attr_reader :session, :id, :modes, :participants
|
26
|
+
|
27
|
+
def initialize (session, id, *modes)
|
28
|
+
@session = session
|
29
|
+
@id = id
|
30
|
+
@modes = modes.flatten.uniq.compact.map(&:to_sym)
|
31
|
+
|
32
|
+
@participants = Participants.new(self)
|
33
|
+
@joining = true
|
34
|
+
end
|
35
|
+
|
36
|
+
def method_missing (id, *args, &block)
|
37
|
+
return @participants.__send__ id, *args, &block if @participants.respond_to? id
|
38
|
+
|
39
|
+
super
|
40
|
+
end
|
41
|
+
|
42
|
+
def respond_to_missing? (id, include_private = false)
|
43
|
+
@participants.respond_to? id, include_private
|
44
|
+
end
|
45
|
+
|
46
|
+
def joining?; @joining; end
|
47
|
+
def joined?; !joining?; end
|
48
|
+
|
49
|
+
def joined!
|
50
|
+
@joining = false
|
51
|
+
|
52
|
+
if invited_by
|
53
|
+
invited_by.send_packet [:groupchat, :join], id
|
54
|
+
|
55
|
+
session.fire :group_chat_join, group_chat: self, invited_by: invited_by
|
56
|
+
end
|
57
|
+
|
58
|
+
participants.each_value {|participant|
|
59
|
+
session.fire :group_chat_join, group_chat: self, buddy: ~participant
|
60
|
+
}
|
61
|
+
end
|
62
|
+
|
63
|
+
def on (what, &block)
|
64
|
+
session.on what do |e|
|
65
|
+
block.call e if e.group_chat == self
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
def invited_by (value = nil)
|
70
|
+
raise ArgumentError, 'cannot overwrite the invitor' if @invited_by && value
|
71
|
+
|
72
|
+
value ? @invited_by = value : @invited_by
|
73
|
+
end
|
74
|
+
|
75
|
+
def invited?
|
76
|
+
!!invited_by
|
77
|
+
end
|
78
|
+
|
79
|
+
def invite (buddy)
|
80
|
+
return unless buddy = session.buddies[buddy]
|
81
|
+
|
82
|
+
return unless buddy.online?
|
83
|
+
|
84
|
+
return if participants.has_key? buddy.id
|
85
|
+
|
86
|
+
unless buddy.supports? :groupchat
|
87
|
+
raise ArgumentError, "#{buddy.id} doesn't support groupchats"
|
88
|
+
end
|
89
|
+
|
90
|
+
buddy.send_packet [:groupchat, :invite], id, modes
|
91
|
+
buddy.send_packet [:groupchat, :participants], id, participants.keys
|
92
|
+
|
93
|
+
self
|
94
|
+
end
|
95
|
+
|
96
|
+
def left?; @left; end
|
97
|
+
|
98
|
+
def leave (reason = nil)
|
99
|
+
return if left?
|
100
|
+
|
101
|
+
@left = true
|
102
|
+
|
103
|
+
participants.each_value {|buddy|
|
104
|
+
buddy.send_packet [:groupchat, :leave], id, reason
|
105
|
+
}
|
106
|
+
|
107
|
+
session.group_chats.destroy id
|
108
|
+
end
|
109
|
+
|
110
|
+
def send_message (message)
|
111
|
+
participants.each_value {|buddy|
|
112
|
+
buddy.send_packet [:groupchat, :message], id, message
|
113
|
+
}
|
114
|
+
end
|
115
|
+
|
116
|
+
def inspect
|
117
|
+
"#<Torchat::GroupChat(#{id})#{"[#{modes.join ' '}]" unless modes.empty?}: #{empty? ? 'empty' : keys.join(' ')}>"
|
118
|
+
end
|
119
|
+
end
|
120
|
+
|
121
|
+
end; end
|
122
|
+
|
123
|
+
require 'torchat/session/group_chat/participants'
|
@@ -0,0 +1,38 @@
|
|
1
|
+
#--
|
2
|
+
# Copyleft meh. [http://meh.paranoid.pk | meh@paranoici.org]
|
3
|
+
#
|
4
|
+
# This file is part of torchat for ruby.
|
5
|
+
#
|
6
|
+
# torchat for ruby is free software: you can redistribute it and/or modify
|
7
|
+
# it under the terms of the GNU Affero General Public License as published
|
8
|
+
# by the Free Software Foundation, either version 3 of the License, or
|
9
|
+
# (at your option) any later version.
|
10
|
+
#
|
11
|
+
# torchat for ruby is distributed in the hope that it will be useful,
|
12
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
13
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
14
|
+
# GNU Affero General Public License for more details.
|
15
|
+
#
|
16
|
+
# You should have received a copy of the GNU Affero General Public License
|
17
|
+
# along with torchat for ruby. If not, see <http://www.gnu.org/licenses/>.
|
18
|
+
#++
|
19
|
+
|
20
|
+
require 'delegate'
|
21
|
+
|
22
|
+
require 'torchat/session/buddy'
|
23
|
+
|
24
|
+
class Torchat; class Session; class GroupChat
|
25
|
+
|
26
|
+
class Participant < DelegateClass(Buddy)
|
27
|
+
attr_reader :invited_by
|
28
|
+
|
29
|
+
def initialize (buddy, invited_by = nil)
|
30
|
+
super(buddy)
|
31
|
+
|
32
|
+
@invited_by = invited_by
|
33
|
+
end
|
34
|
+
|
35
|
+
alias ~ __getobj__
|
36
|
+
end
|
37
|
+
|
38
|
+
end; end; end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
#--
|
2
|
+
# Copyleft meh. [http://meh.paranoid.pk | meh@paranoici.org]
|
3
|
+
#
|
4
|
+
# This file is part of torchat for ruby.
|
5
|
+
#
|
6
|
+
# torchat for ruby is free software: you can redistribute it and/or modify
|
7
|
+
# it under the terms of the GNU Affero General Public License as published
|
8
|
+
# by the Free Software Foundation, either version 3 of the License, or
|
9
|
+
# (at your option) any later version.
|
10
|
+
#
|
11
|
+
# torchat for ruby is distributed in the hope that it will be useful,
|
12
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
13
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
14
|
+
# GNU Affero General Public License for more details.
|
15
|
+
#
|
16
|
+
# You should have received a copy of the GNU Affero General Public License
|
17
|
+
# along with torchat for ruby. If not, see <http://www.gnu.org/licenses/>.
|
18
|
+
#++
|
19
|
+
|
20
|
+
require 'torchat/session/group_chat/participant'
|
21
|
+
|
22
|
+
class Torchat; class Session; class GroupChat
|
23
|
+
|
24
|
+
class Participants < Hash
|
25
|
+
attr_reader :group_chat
|
26
|
+
|
27
|
+
def initialize (group_chat)
|
28
|
+
@group_chat = group_chat
|
29
|
+
end
|
30
|
+
|
31
|
+
def add (id, invited_by = nil)
|
32
|
+
return if has_key? Torchat.normalize_id(id)
|
33
|
+
|
34
|
+
if buddy = group_chat.session.buddies[id]
|
35
|
+
buddy.group_chats.add group_chat
|
36
|
+
|
37
|
+
self[buddy.id] = Participant.new(buddy, invited_by)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
def delete (id)
|
42
|
+
super(Torchat.normalize_id(id))
|
43
|
+
|
44
|
+
if buddy = group_chat.session.buddies[id]
|
45
|
+
buddy.group_chats.delete(group_chat)
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
private :[]=
|
50
|
+
end
|
51
|
+
|
52
|
+
end; end; end
|
@@ -0,0 +1,74 @@
|
|
1
|
+
#--
|
2
|
+
# Copyleft meh. [http://meh.paranoid.pk | meh@paranoici.org]
|
3
|
+
#
|
4
|
+
# This file is part of torchat for ruby.
|
5
|
+
#
|
6
|
+
# torchat for ruby is free software: you can redistribute it and/or modify
|
7
|
+
# it under the terms of the GNU Affero General Public License as published
|
8
|
+
# by the Free Software Foundation, either version 3 of the License, or
|
9
|
+
# (at your option) any later version.
|
10
|
+
#
|
11
|
+
# torchat for ruby is distributed in the hope that it will be useful,
|
12
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
13
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
14
|
+
# GNU Affero General Public License for more details.
|
15
|
+
#
|
16
|
+
# You should have received a copy of the GNU Affero General Public License
|
17
|
+
# along with torchat for ruby. If not, see <http://www.gnu.org/licenses/>.
|
18
|
+
#++
|
19
|
+
|
20
|
+
require 'torchat/session/group_chat'
|
21
|
+
|
22
|
+
class Torchat; class Session
|
23
|
+
|
24
|
+
class GroupChats < Hash
|
25
|
+
attr_reader :session
|
26
|
+
|
27
|
+
def initialize (session)
|
28
|
+
@session = session
|
29
|
+
end
|
30
|
+
|
31
|
+
def has_key? (name)
|
32
|
+
name = name.id if name.is_a? GroupChat
|
33
|
+
|
34
|
+
!!self[name]
|
35
|
+
end
|
36
|
+
|
37
|
+
def [] (name)
|
38
|
+
name = name.id if name.is_a? GroupChat
|
39
|
+
|
40
|
+
super(name)
|
41
|
+
end
|
42
|
+
|
43
|
+
private :[]=
|
44
|
+
|
45
|
+
def create (id = Torchat.new_cookie, joined = true)
|
46
|
+
if has_key? id
|
47
|
+
raise ArgumentError, "a groupchat named #{id} already exists"
|
48
|
+
end
|
49
|
+
|
50
|
+
GroupChat.new(session, id).tap {|group_chat|
|
51
|
+
group_chat.joined! if joined
|
52
|
+
|
53
|
+
self[id] = group_chat
|
54
|
+
|
55
|
+
session.fire :group_chat_create, group_chat: group_chat
|
56
|
+
}
|
57
|
+
end
|
58
|
+
|
59
|
+
def destroy (id)
|
60
|
+
unless has_key? id
|
61
|
+
raise ArgumentError, "a groupchat named #{id} doesn't exists"
|
62
|
+
end
|
63
|
+
|
64
|
+
self[id].tap {|group_chat|
|
65
|
+
delete group_chat.id
|
66
|
+
|
67
|
+
session.fire :group_chat_destroy, group_chat: group_chat
|
68
|
+
}
|
69
|
+
end
|
70
|
+
|
71
|
+
private :delete
|
72
|
+
end
|
73
|
+
|
74
|
+
end; end
|
@@ -0,0 +1,187 @@
|
|
1
|
+
#--
|
2
|
+
# Copyleft meh. [http://meh.paranoid.pk | meh@paranoici.org]
|
3
|
+
#
|
4
|
+
# This file is part of torchat for ruby.
|
5
|
+
#
|
6
|
+
# torchat for ruby is free software: you can redistribute it and/or modify
|
7
|
+
# it under the terms of the GNU Affero General Public License as published
|
8
|
+
# by the Free Software Foundation, either version 3 of the License, or
|
9
|
+
# (at your option) any later version.
|
10
|
+
#
|
11
|
+
# torchat for ruby is distributed in the hope that it will be useful,
|
12
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
13
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
14
|
+
# GNU Affero General Public License for more details.
|
15
|
+
#
|
16
|
+
# You should have received a copy of the GNU Affero General Public License
|
17
|
+
# along with torchat for ruby. If not, see <http://www.gnu.org/licenses/>.
|
18
|
+
#++
|
19
|
+
|
20
|
+
class Torchat; class Session
|
21
|
+
|
22
|
+
class Incoming < EventMachine::Protocols::LineAndTextProtocol
|
23
|
+
attr_accessor :owner
|
24
|
+
|
25
|
+
def post_init
|
26
|
+
@delayed = []
|
27
|
+
end
|
28
|
+
|
29
|
+
def receive_line (line)
|
30
|
+
packet = begin
|
31
|
+
Protocol.unpack(line.chomp, @owner)
|
32
|
+
rescue => e
|
33
|
+
if e.is_a?(ArgumentError) && e.message.end_with?('packet unknown')
|
34
|
+
@session.fire :unknown, line: line, buddy: @owner
|
35
|
+
else
|
36
|
+
Torchat.debug line.inspect
|
37
|
+
Torchat.debug e
|
38
|
+
end
|
39
|
+
|
40
|
+
return
|
41
|
+
end
|
42
|
+
|
43
|
+
if packet.type == :ping && !packet.extension
|
44
|
+
Torchat.debug "ping incoming from claimed #{packet.id}", level: 2
|
45
|
+
|
46
|
+
if @session.offline?
|
47
|
+
close_connection_after_writing
|
48
|
+
|
49
|
+
Torchat.debug 'we are offline, kill the connection'
|
50
|
+
|
51
|
+
return
|
52
|
+
end
|
53
|
+
|
54
|
+
if !packet.valid? || packet.id == @session.id || @last_ping && packet.id != @last_ping.id
|
55
|
+
close_connection_after_writing
|
56
|
+
|
57
|
+
Torchat.debug 'invalid packet or DoS attempt'
|
58
|
+
|
59
|
+
return
|
60
|
+
end
|
61
|
+
|
62
|
+
@last_ping = packet
|
63
|
+
|
64
|
+
if buddy = @session.buddies[packet.id]
|
65
|
+
if buddy.blocked?
|
66
|
+
close_connection_after_writing
|
67
|
+
|
68
|
+
Torchat.debug "#{buddy.id} is blocked"
|
69
|
+
|
70
|
+
return
|
71
|
+
end
|
72
|
+
|
73
|
+
if buddy.has_incoming? && buddy.instance_variable_get(:@incoming) != self
|
74
|
+
close_connection_after_writing
|
75
|
+
|
76
|
+
Torchat.debug "#{buddy.id} already has an incoming connection"
|
77
|
+
|
78
|
+
return
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
if @owner
|
83
|
+
@owner.send_packet :pong, packet.cookie
|
84
|
+
else
|
85
|
+
if buddy
|
86
|
+
buddy.last_received = packet
|
87
|
+
|
88
|
+
buddy.connect
|
89
|
+
|
90
|
+
if buddy.connected?
|
91
|
+
buddy.send_packet! :pong, packet.cookie
|
92
|
+
else
|
93
|
+
buddy.send_packet :pong, packet.cookie
|
94
|
+
end
|
95
|
+
else
|
96
|
+
@temp_buddy = Buddy.new(@session, packet.id, self)
|
97
|
+
|
98
|
+
@temp_buddy.last_received = packet
|
99
|
+
|
100
|
+
@temp_buddy.connect
|
101
|
+
@temp_buddy.send_packet :pong, packet.cookie
|
102
|
+
end
|
103
|
+
end
|
104
|
+
elsif packet.type == :pong && !packet.extension
|
105
|
+
unless buddy = (@session.buddies[(@last_ping.id rescue nil)] || @temp_buddy) || !buddy.pinged?
|
106
|
+
close_connection_after_writing
|
107
|
+
|
108
|
+
Torchat.debug 'pong received without a ping'
|
109
|
+
|
110
|
+
return
|
111
|
+
end
|
112
|
+
|
113
|
+
if buddy.blocked?
|
114
|
+
close_connection_after_writing
|
115
|
+
|
116
|
+
Torchat.debug "#{buddy.id} is blocked."
|
117
|
+
|
118
|
+
return
|
119
|
+
end
|
120
|
+
|
121
|
+
buddy.last_received = packet
|
122
|
+
|
123
|
+
return unless @last_ping
|
124
|
+
|
125
|
+
if packet.cookie != buddy.pinged?
|
126
|
+
close_connection_after_writing
|
127
|
+
|
128
|
+
Torchat.debug "#{"#{packet.from.id} sent " if packet.from}pong with wrong cookie, got #{packet.cookie.inspect} expected #{buddy.pinged?.inspect}"
|
129
|
+
|
130
|
+
return
|
131
|
+
end
|
132
|
+
|
133
|
+
unless buddy.verified?
|
134
|
+
buddy.verified self
|
135
|
+
end
|
136
|
+
|
137
|
+
buddy.pong!
|
138
|
+
else
|
139
|
+
unless @owner
|
140
|
+
if @last_ping
|
141
|
+
if @delayed.length > 23
|
142
|
+
close_connection_after_writing
|
143
|
+
|
144
|
+
Torchat.debug 'too many cached packets'
|
145
|
+
else
|
146
|
+
@delayed << packet
|
147
|
+
end
|
148
|
+
else
|
149
|
+
close_connection_after_writing
|
150
|
+
|
151
|
+
Torchat.debug 'someone sent a packet before the handshake'
|
152
|
+
Torchat.debug "the packet was #{packet.inspect}", level: 2
|
153
|
+
end
|
154
|
+
|
155
|
+
return
|
156
|
+
end
|
157
|
+
|
158
|
+
Torchat.debug "<< #{@owner ? @owner.id : 'unknown'} #{packet.inspect}", level: 2
|
159
|
+
|
160
|
+
@owner.last_received = packet
|
161
|
+
|
162
|
+
@owner.session.received_packet packet
|
163
|
+
end
|
164
|
+
rescue => e
|
165
|
+
Torchat.debug e
|
166
|
+
end
|
167
|
+
|
168
|
+
def verification_completed
|
169
|
+
@delayed.each {|packet|
|
170
|
+
packet.from = @owner
|
171
|
+
|
172
|
+
@owner.session.received_packet packet
|
173
|
+
}
|
174
|
+
|
175
|
+
@delayed = nil
|
176
|
+
end
|
177
|
+
|
178
|
+
def unbind
|
179
|
+
if error?
|
180
|
+
Torchat.debug "errno #{EM.report_connection_error_status(@signature)}", level: 2
|
181
|
+
end
|
182
|
+
|
183
|
+
@owner.disconnect if @owner
|
184
|
+
end
|
185
|
+
end
|
186
|
+
|
187
|
+
end; end
|