torchat 0.0.1.rc.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|