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;