Software /
code /
prosody
Comparison
plugins/mod_s2s/s2sout.lib.lua @ 5024:d25e1b9332cc
Merge with Florob
author | Matthew Wild <mwild1@gmail.com> |
---|---|
date | Sat, 28 Jul 2012 01:14:31 +0100 |
parent | 4987:d37f2abac72c |
child | 5112:8b94a8d92cf3 |
comparison
equal
deleted
inserted
replaced
5023:dcc8e789df36 | 5024:d25e1b9332cc |
---|---|
93 local handle; | 93 local handle; |
94 handle = adns.lookup(function (answer) | 94 handle = adns.lookup(function (answer) |
95 handle = nil; | 95 handle = nil; |
96 host_session.connecting = nil; | 96 host_session.connecting = nil; |
97 if answer then | 97 if answer then |
98 log("debug", to_host.." has SRV records, handling..."); | 98 log("debug", "%s has SRV records, handling...", to_host); |
99 local srv_hosts = {}; | 99 local srv_hosts = {}; |
100 host_session.srv_hosts = srv_hosts; | 100 host_session.srv_hosts = srv_hosts; |
101 for _, record in ipairs(answer) do | 101 for _, record in ipairs(answer) do |
102 t_insert(srv_hosts, record.srv); | 102 t_insert(srv_hosts, record.srv); |
103 end | 103 end |
104 if #srv_hosts == 1 and srv_hosts[1].target == "." then | 104 if #srv_hosts == 1 and srv_hosts[1].target == "." then |
105 log("debug", to_host.." does not provide a XMPP service"); | 105 log("debug", "%s does not provide a XMPP service", to_host); |
106 s2s_destroy_session(host_session, err); -- Nothing to see here | 106 s2s_destroy_session(host_session, err); -- Nothing to see here |
107 return; | 107 return; |
108 end | 108 end |
109 t_sort(srv_hosts, compare_srv_priorities); | 109 t_sort(srv_hosts, compare_srv_priorities); |
110 | 110 |
113 if srv_choice then | 113 if srv_choice then |
114 connect_host, connect_port = srv_choice.target or to_host, srv_choice.port or connect_port; | 114 connect_host, connect_port = srv_choice.target or to_host, srv_choice.port or connect_port; |
115 log("debug", "Best record found, will connect to %s:%d", connect_host, connect_port); | 115 log("debug", "Best record found, will connect to %s:%d", connect_host, connect_port); |
116 end | 116 end |
117 else | 117 else |
118 log("debug", to_host.." has no SRV records, falling back to A/AAAA"); | 118 log("debug", "%s has no SRV records, falling back to A/AAAA", to_host); |
119 end | 119 end |
120 -- Try with SRV, or just the plain hostname if no SRV | 120 -- Try with SRV, or just the plain hostname if no SRV |
121 local ok, err = s2sout.try_connect(host_session, connect_host, connect_port); | 121 local ok, err = s2sout.try_connect(host_session, connect_host, connect_port); |
122 if not ok then | 122 if not ok then |
123 if not s2sout.attempt_connection(host_session, err) then | 123 if not s2sout.attempt_connection(host_session, err) then |
168 | 168 |
169 if not err then | 169 if not err then |
170 local IPs = {}; | 170 local IPs = {}; |
171 host_session.ip_hosts = IPs; | 171 host_session.ip_hosts = IPs; |
172 local handle4, handle6; | 172 local handle4, handle6; |
173 local has_other = false; | 173 local have_other_result = not(has_ipv4) or not(has_ipv6) or false; |
174 | 174 |
175 if has_ipv4 then | 175 if has_ipv4 then |
176 handle4 = adns.lookup(function (reply, err) | 176 handle4 = adns.lookup(function (reply, err) |
177 handle4 = nil; | 177 handle4 = nil; |
178 | 178 |
179 -- COMPAT: This is a compromise for all you CNAME-(ab)users :) | 179 -- COMPAT: This is a compromise for all you CNAME-(ab)users :) |
180 if not (reply and reply[#reply] and reply[#reply].a) then | 180 if not (reply and reply[#reply] and reply[#reply].a) then |
181 local count = max_dns_depth; | 181 local count = max_dns_depth; |
182 reply = dns.peek(connect_host, "CNAME", "IN"); | 182 reply = dns.peek(connect_host, "CNAME", "IN"); |
183 while count > 0 and reply and reply[#reply] and not reply[#reply].a and reply[#reply].cname do | 183 while count > 0 and reply and reply[#reply] and not reply[#reply].a and reply[#reply].cname do |
184 log("debug", "Looking up %s (DNS depth is %d)", tostring(reply[#reply].cname), count); | 184 log("debug", "Looking up %s (DNS depth is %d)", tostring(reply[#reply].cname), count); |
185 reply = dns.peek(reply[#reply].cname, "A", "IN") or dns.peek(reply[#reply].cname, "CNAME", "IN"); | 185 reply = dns.peek(reply[#reply].cname, "A", "IN") or dns.peek(reply[#reply].cname, "CNAME", "IN"); |
186 count = count - 1; | 186 count = count - 1; |
187 end | 187 end |
188 end | 188 end |
189 -- end of CNAME resolving | 189 -- end of CNAME resolving |
190 | 190 |
191 if reply and reply[#reply] and reply[#reply].a then | 191 if reply and reply[#reply] and reply[#reply].a then |
192 for _, ip in ipairs(reply) do | 192 for _, ip in ipairs(reply) do |
193 log("debug", "DNS reply for %s gives us %s", connect_host, ip.a); | 193 log("debug", "DNS reply for %s gives us %s", connect_host, ip.a); |
194 IPs[#IPs+1] = new_ip(ip.a, "IPv4"); | 194 IPs[#IPs+1] = new_ip(ip.a, "IPv4"); |
195 end | 195 end |
196 end | 196 end |
197 | 197 |
198 if has_other then | 198 if have_other_result then |
199 if #IPs > 0 then | 199 if #IPs > 0 then |
200 rfc3484_dest(host_session.ip_hosts, sources); | 200 rfc3484_dest(host_session.ip_hosts, sources); |
201 for i = 1, #IPs do | 201 for i = 1, #IPs do |
202 IPs[i] = {ip = IPs[i], port = connect_port}; | 202 IPs[i] = {ip = IPs[i], port = connect_port}; |
203 end | 203 end |
204 host_session.ip_choice = 0; | 204 host_session.ip_choice = 0; |
205 s2sout.try_next_ip(host_session); | 205 s2sout.try_next_ip(host_session); |
206 else | |
207 log("debug", "DNS lookup failed to get a response for %s", connect_host); | |
208 host_session.ip_hosts = nil; | |
209 if not s2sout.attempt_connection(host_session, "name resolution failed") then -- Retry if we can | |
210 log("debug", "No other records to try for %s - destroying", host_session.to_host); | |
211 err = err and (": "..err) or ""; | |
212 s2s_destroy_session(host_session, "DNS resolution failed"..err); -- End of the line, we can't | |
213 end | |
214 end | |
206 else | 215 else |
207 log("debug", "DNS lookup failed to get a response for %s", connect_host); | 216 have_other_result = true; |
208 host_session.ip_hosts = nil; | 217 end |
209 if not s2sout.attempt_connection(host_session, "name resolution failed") then -- Retry if we can | 218 end, connect_host, "A", "IN"); |
210 log("debug", "No other records to try for %s - destroying", host_session.to_host); | |
211 err = err and (": "..err) or ""; | |
212 s2s_destroy_session(host_session, "DNS resolution failed"..err); -- End of the line, we can't | |
213 end | |
214 end | |
215 else | |
216 has_other = true; | |
217 end | |
218 end, connect_host, "A", "IN"); | |
219 else | 219 else |
220 has_other = true; | 220 have_other_result = true; |
221 end | 221 end |
222 | 222 |
223 if has_ipv6 then | 223 if has_ipv6 then |
224 handle6 = adns.lookup(function (reply, err) | 224 handle6 = adns.lookup(function (reply, err) |
225 handle6 = nil; | 225 handle6 = nil; |
226 | 226 |
227 if reply and reply[#reply] and reply[#reply].aaaa then | 227 if reply and reply[#reply] and reply[#reply].aaaa then |
228 for _, ip in ipairs(reply) do | 228 for _, ip in ipairs(reply) do |
229 log("debug", "DNS reply for %s gives us %s", connect_host, ip.aaaa); | 229 log("debug", "DNS reply for %s gives us %s", connect_host, ip.aaaa); |
230 IPs[#IPs+1] = new_ip(ip.aaaa, "IPv6"); | 230 IPs[#IPs+1] = new_ip(ip.aaaa, "IPv6"); |
231 end | 231 end |
232 end | 232 end |
233 | 233 |
234 if has_other then | 234 if have_other_result then |
235 if #IPs > 0 then | 235 if #IPs > 0 then |
236 rfc3484_dest(host_session.ip_hosts, sources); | 236 rfc3484_dest(host_session.ip_hosts, sources); |
237 for i = 1, #IPs do | 237 for i = 1, #IPs do |
238 IPs[i] = {ip = IPs[i], port = connect_port}; | 238 IPs[i] = {ip = IPs[i], port = connect_port}; |
239 end | 239 end |
240 host_session.ip_choice = 0; | 240 host_session.ip_choice = 0; |
241 s2sout.try_next_ip(host_session); | 241 s2sout.try_next_ip(host_session); |
242 else | |
243 log("debug", "DNS lookup failed to get a response for %s", connect_host); | |
244 host_session.ip_hosts = nil; | |
245 if not s2sout.attempt_connection(host_session, "name resolution failed") then -- Retry if we can | |
246 log("debug", "No other records to try for %s - destroying", host_session.to_host); | |
247 err = err and (": "..err) or ""; | |
248 s2s_destroy_session(host_session, "DNS resolution failed"..err); -- End of the line, we can't | |
249 end | |
250 end | |
242 else | 251 else |
243 log("debug", "DNS lookup failed to get a response for %s", connect_host); | 252 have_other_result = true; |
244 host_session.ip_hosts = nil; | 253 end |
245 if not s2sout.attempt_connection(host_session, "name resolution failed") then -- Retry if we can | 254 end, connect_host, "AAAA", "IN"); |
246 log("debug", "No other records to try for %s - destroying", host_session.to_host); | |
247 err = err and (": "..err) or ""; | |
248 s2s_destroy_session(host_session, "DNS resolution failed"..err); -- End of the line, we can't | |
249 end | |
250 end | |
251 else | |
252 has_other = true; | |
253 end | |
254 end, connect_host, "AAAA", "IN"); | |
255 else | 255 else |
256 has_other = true; | 256 have_other_result = true; |
257 end | 257 end |
258 | |
259 return true; | 258 return true; |
260 elseif host_session.ip_hosts and #host_session.ip_hosts > host_session.ip_choice then -- Not our first attempt, and we also have IPs left to try | 259 elseif host_session.ip_hosts and #host_session.ip_hosts > host_session.ip_choice then -- Not our first attempt, and we also have IPs left to try |
261 s2sout.try_next_ip(host_session); | 260 s2sout.try_next_ip(host_session); |
262 else | 261 else |
263 host_session.ip_hosts = nil; | 262 host_session.ip_hosts = nil; |