Class: Vines::Stream::Server
- Inherits:
-
Vines::Stream
- Object
- EventMachine::Connection
- Vines::Stream
- Vines::Stream::Server
show all
- Defined in:
- lib/vines/stream/server.rb,
lib/vines/stream/server/auth.rb,
lib/vines/stream/server/ready.rb,
lib/vines/stream/server/start.rb,
lib/vines/stream/server/auth_method.rb,
lib/vines/stream/server/auth_restart.rb,
lib/vines/stream/server/final_restart.rb,
lib/vines/stream/server/outbound/auth.rb,
lib/vines/stream/server/outbound/start.rb,
lib/vines/stream/server/outbound/tls_result.rb,
lib/vines/stream/server/outbound/auth_restart.rb,
lib/vines/stream/server/outbound/auth_external.rb,
lib/vines/stream/server/outbound/authoritative.rb,
lib/vines/stream/server/outbound/final_restart.rb,
lib/vines/stream/server/outbound/final_features.rb,
lib/vines/stream/server/outbound/auth_dialback_result.rb,
lib/vines/stream/server/outbound/auth_external_result.rb
Overview
Implements the XMPP protocol for server-to-server (s2s) streams. This serves connected streams using the jabber:server namespace. This handles both accepting incoming s2s streams and initiating outbound s2s streams to other servers.
Defined Under Namespace
Classes: Auth, AuthMethod, AuthRestart, FinalRestart, Outbound, Ready, Start
Constant Summary
collapse
- MECHANISMS =
%w[EXTERNAL].freeze
ERROR, PAD, STREAM
Instance Attribute Summary collapse
#config, #id, #state, #user
Class Method Summary
collapse
Instance Method Summary
collapse
#advance, #available_resources, #cert_domain_matches?, #close_connection, #connected_resources, #create_parser, #encrypt, #encrypt?, #error, #interested_resources, #receive_data, #reset, #router, #storage, #update_user_streams, #vhost, #write
Methods included from Log
#log, set_log_file
Constructor Details
#initialize(config, options = {}) ⇒ Server
Returns a new instance of Server.
54
55
56
57
58
59
60
61
62
63
64
65
66
67
|
# File 'lib/vines/stream/server.rb', line 54
def initialize(config, options={})
super(config)
@outbound_tls_required = false
@peer_trusted = nil
@connected = false
@remote_domain = options[:to]
@domain = options[:from]
@srv = options[:srv]
@dialback_verify_key = options[:dialback_verify_key]
@callback = options[:callback]
@outbound = @remote_domain && @domain
start = @outbound ? Outbound::Start.new(self) : Start.new(self)
advance(start)
end
|
Instance Attribute Details
#domain ⇒ Object
Returns the value of attribute domain.
51
52
53
|
# File 'lib/vines/stream/server.rb', line 51
def domain
@domain
end
|
#remote_domain ⇒ Object
Returns the value of attribute remote_domain.
52
53
54
|
# File 'lib/vines/stream/server.rb', line 52
def remote_domain
@remote_domain
end
|
Class Method Details
.connect(config, to, from, srv, dialback_verify_key = false, callback) ⇒ Object
36
37
38
39
40
41
42
43
44
45
46
47
48
49
|
# File 'lib/vines/stream/server.rb', line 36
def self.connect(config, to, from, srv, dialback_verify_key = false, callback)
if srv.empty?
Fiber.new { callback.call(nil) }.resume
else
begin
rr = srv.shift
opts = {to: to, from: from, srv: srv, dialback_verify_key: dialback_verify_key, callback: callback}
EM.connect(rr.target.to_s, rr.port, Server, config, opts)
rescue => e
connect(config, to, from, srv, dialback_verify_key, callback)
end
end
end
|
.start(config, to, from, dialback_verify_key = false, &callback) ⇒ Object
Starts the connection to the remote server. When the stream is connected and ready to send stanzas it will yield to the callback block. The callback is run on the EventMachine reactor thread. The yielded stream will be nil if the remote connection failed. We need to use a background thread to avoid blocking the server on DNS SRV lookups.
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
|
# File 'lib/vines/stream/server.rb', line 18
def self.start(config, to, from, dialback_verify_key = false, &callback)
op = proc do
Resolv::DNS.open do |dns|
dns.getresources("_xmpp-server._tcp.#{to}", Resolv::DNS::Resource::IN::SRV)
end.sort! {|a,b| a.priority == b.priority ? b.weight <=> a.weight : a.priority <=> b.priority }
end
cb = proc do |srv|
if srv.empty?
srv << {target: to, port: 5269}
class << srv.first
def method_missing(name); self[name]; end
end
end
Server.connect(config, to, from, srv, dialback_verify_key, callback)
end
EM.defer(proc { op.call rescue [] }, cb)
end
|
Instance Method Details
#authentication_mechanisms ⇒ Object
Return an array of allowed authentication mechanisms advertised as server stream features.
106
107
108
|
# File 'lib/vines/stream/server.rb', line 106
def authentication_mechanisms
MECHANISMS
end
|
#callback! ⇒ Object
131
132
133
|
# File 'lib/vines/stream/server.rb', line 131
def callback!
@callback.call(self) if @callback
end
|
#dialback_retry? ⇒ Boolean
87
88
89
90
|
# File 'lib/vines/stream/server.rb', line 87
def dialback_retry?
return false if @peer_trusted.nil? || @peer_trusted
true
end
|
#dialback_verify_key? ⇒ Boolean
135
136
137
|
# File 'lib/vines/stream/server.rb', line 135
def dialback_verify_key?
@dialback_verify_key
end
|
#max_stanza_size ⇒ Object
74
75
76
|
# File 'lib/vines/stream/server.rb', line 74
def max_stanza_size
config[:server].max_stanza_size
end
|
#notify_connected ⇒ Object
125
126
127
128
129
|
# File 'lib/vines/stream/server.rb', line 125
def notify_connected
@connected = true
self.callback!
@callback = nil
end
|
#outbound_tls_required(required) ⇒ Object
100
101
102
|
# File 'lib/vines/stream/server.rb', line 100
def outbound_tls_required(required)
@outbound_tls_required = required
end
|
#outbound_tls_required? ⇒ Boolean
96
97
98
|
# File 'lib/vines/stream/server.rb', line 96
def outbound_tls_required?
@outbound_tls_required
end
|
#peer_trusted? ⇒ Boolean
83
84
85
|
# File 'lib/vines/stream/server.rb', line 83
def peer_trusted?
!@peer_trusted.nil? && @peer_trusted
end
|
#post_init ⇒ Object
69
70
71
72
|
# File 'lib/vines/stream/server.rb', line 69
def post_init
super
if @outbound
end
|
#ready? ⇒ Boolean
139
140
141
|
# File 'lib/vines/stream/server.rb', line 139
def ready?
state.class == Server::Ready
end
|
#ssl_handshake_completed ⇒ Object
92
93
94
|
# File 'lib/vines/stream/server.rb', line 92
def ssl_handshake_completed
@peer_trusted = cert_domain_matches?(@remote_domain) && peer_trusted?
end
|
#ssl_verify_peer(pem) ⇒ Object
78
79
80
81
|
# File 'lib/vines/stream/server.rb', line 78
def ssl_verify_peer(pem)
@peer_trusted = @store.trusted?(pem)
true
end
|
#start(node) ⇒ Object
143
144
145
146
147
148
149
150
151
152
153
154
|
# File 'lib/vines/stream/server.rb', line 143
def start(node)
if @outbound then ; return end
to, from = %w[to from].map {|a| node[a] }
@domain, @remote_domain = to, from unless @domain
raise StreamErrors::NotAuthorized if domain_change?(to, from)
raise StreamErrors::ImproperAddressing unless valid_address?(@domain) && valid_address?(@remote_domain)
raise StreamErrors::HostUnknown unless config.vhost?(@domain) || config.pubsub?(@domain) || config.component?(@domain)
raise StreamErrors::NotAuthorized unless config.s2s?(@remote_domain) && config.allowed?(@domain, @remote_domain)
raise StreamErrors::InvalidNamespace unless node.namespaces['xmlns'] == NAMESPACES[:server]
raise StreamErrors::InvalidNamespace unless node.namespaces['xmlns:stream'] == NAMESPACES[:stream]
end
|
#stream_type ⇒ Object
110
111
112
|
# File 'lib/vines/stream/server.rb', line 110
def stream_type
:server
end
|
#unbind ⇒ Object
114
115
116
117
118
119
|
# File 'lib/vines/stream/server.rb', line 114
def unbind
super
if @outbound && !@connected
Server.connect(config, @remote_domain, @domain, @srv, @callback)
end
end
|
#vhost?(domain) ⇒ Boolean
121
122
123
|
# File 'lib/vines/stream/server.rb', line 121
def vhost?(domain)
config.vhost?(domain)
end
|