1 local verse = require "verse"; |
1 local verse = require "verse"; |
2 local stream = verse.stream_mt; |
2 local stream = verse.stream_mt; |
3 |
3 |
4 local jid_split = require "util.jid".split; |
4 local jid_split = require "util.jid".split; |
|
5 local adns = require "net.adns"; |
5 local lxp = require "lxp"; |
6 local lxp = require "lxp"; |
6 local st = require "util.stanza"; |
7 local st = require "util.stanza"; |
7 |
8 |
8 -- Shortcuts to save having to load util.stanza |
9 -- Shortcuts to save having to load util.stanza |
9 verse.message, verse.presence, verse.iq, verse.stanza, verse.reply, verse.error_reply = |
10 verse.message, verse.presence, verse.iq, verse.stanza, verse.reply, verse.error_reply = |
10 st.message, st.presence, st.iq, st.stanza, st.reply, st.error_reply; |
11 st.message, st.presence, st.iq, st.stanza, st.reply, st.error_reply; |
11 |
12 |
12 local init_xmlhandlers = require "core.xmlhandlers"; |
13 local init_xmlhandlers = require "core.xmlhandlers"; |
13 |
14 |
14 local xmlns_stream = "http://etherx.jabber.org/streams"; |
15 local xmlns_stream = "http://etherx.jabber.org/streams"; |
|
16 |
|
17 local function compare_srv_priorities(a,b) |
|
18 return a.priority < b.priority or (a.priority == b.priority and a.weight > b.weight); |
|
19 end |
15 |
20 |
16 local stream_callbacks = { |
21 local stream_callbacks = { |
17 stream_ns = xmlns_stream, |
22 stream_ns = xmlns_stream, |
18 stream_tag = "stream", |
23 stream_tag = "stream", |
19 default_ns = "jabber:client" }; |
24 default_ns = "jabber:client" }; |
114 self:send("</stream:stream>"); |
119 self:send("</stream:stream>"); |
115 end |
120 end |
116 return _base_close(self); |
121 return _base_close(self); |
117 end |
122 end |
118 |
123 |
119 -- Initialise connection |
124 local function start_connect() |
120 self:connect(self.connect_host or self.host, self.connect_port or 5222); |
125 -- Initialise connection |
121 self:reopen(); |
126 self:connect(self.connect_host or self.host, self.connect_port or 5222); |
|
127 self:reopen(); |
|
128 end |
|
129 |
|
130 if not (self.connect_host or self.connect_port) then |
|
131 -- Look up SRV records |
|
132 adns.lookup(function (answer) |
|
133 if answer then |
|
134 local srv_hosts = {}; |
|
135 self.srv_hosts = srv_hosts; |
|
136 for _, record in ipairs(answer) do |
|
137 table.insert(srv_hosts, record.srv); |
|
138 end |
|
139 table.sort(srv_hosts, compare_srv_priorities); |
|
140 |
|
141 local srv_choice = srv_hosts[1]; |
|
142 self.srv_choice = 1; |
|
143 if srv_choice then |
|
144 self.connect_host, self.connect_port = srv_choice.target, srv_choice.port; |
|
145 self:debug("Best record found, will connect to %s:%d", self.connect_host or self.host, self.connect_port or 5222); |
|
146 end |
|
147 |
|
148 self:hook("disconnected", function () |
|
149 if self.srv_hosts and self.srv_choice < #self.srv_hosts then |
|
150 self.srv_choice = self.srv_choice + 1; |
|
151 local srv_choice = srv_hosts[self.srv_choice]; |
|
152 self.connect_host, self.connect_port = srv_choice.target, srv_choice.port; |
|
153 start_connect(); |
|
154 return true; |
|
155 end |
|
156 end, 1000); |
|
157 |
|
158 self:hook("connected", function () |
|
159 self.srv_hosts = nil; |
|
160 end, 1000); |
|
161 end |
|
162 start_connect(); |
|
163 end, "_xmpp-client._tcp."..(self.host)..".", "SRV"); |
|
164 else |
|
165 start_connect(); |
|
166 end |
122 end |
167 end |
123 |
168 |
124 function stream:reopen() |
169 function stream:reopen() |
125 self:reset(); |
170 self:reset(); |
126 self:send(st.stanza("stream:stream", { to = self.host, ["xmlns:stream"]='http://etherx.jabber.org/streams', |
171 self:send(st.stanza("stream:stream", { to = self.host, ["xmlns:stream"]='http://etherx.jabber.org/streams', |