16 local rfc6724_dest = require "util.rfc6724".destination; |
16 local rfc6724_dest = require "util.rfc6724".destination; |
17 local socket = require "socket"; |
17 local socket = require "socket"; |
18 local adns = require "net.adns"; |
18 local adns = require "net.adns"; |
19 local dns = require "net.dns"; |
19 local dns = require "net.dns"; |
20 local t_insert, t_sort, ipairs = table.insert, table.sort, ipairs; |
20 local t_insert, t_sort, ipairs = table.insert, table.sort, ipairs; |
21 local local_addresses = require "util.net".local_addresses; |
|
22 |
21 |
23 local s2s_destroy_session = require "core.s2smanager".destroy_session; |
22 local s2s_destroy_session = require "core.s2smanager".destroy_session; |
24 |
23 |
25 local log = module._log; |
24 local log = module._log; |
26 |
25 |
27 local sources = {}; |
26 local anysource = { IPv4 = "0.0.0.0", IPv6 = "::" }; |
|
27 local function get_sources(addrs) |
|
28 local sources = {}; |
|
29 for _, IP in ipairs(addrs) do |
|
30 local sock; |
|
31 if IP.proto == "IPv4" then |
|
32 sock = socket.udp(); |
|
33 elseif IP.proto == "IPv6" then |
|
34 sock = socket.udp6(); |
|
35 end |
|
36 sock:setpeername(IP.addr, 9); |
|
37 local localaddr = sock:getsockname() or anysource[IP.proto]; |
|
38 sock:close(); |
|
39 if not sources[localaddr] then |
|
40 sources[localaddr] = true; |
|
41 t_insert(sources, new_ip(localaddr, IP.proto)); |
|
42 end |
|
43 end |
|
44 return sources; |
|
45 end |
28 local has_ipv4, has_ipv6; |
46 local has_ipv4, has_ipv6; |
29 |
47 |
30 local dns_timeout = module:get_option_number("dns_timeout", 15); |
48 local dns_timeout = module:get_option_number("dns_timeout", 15); |
31 dns.settimeout(dns_timeout); |
49 dns.settimeout(dns_timeout); |
32 |
50 |
175 end |
193 end |
176 end |
194 end |
177 |
195 |
178 if have_other_result then |
196 if have_other_result then |
179 if #IPs > 0 then |
197 if #IPs > 0 then |
180 rfc6724_dest(host_session.ip_hosts, sources); |
198 rfc6724_dest(host_session.ip_hosts, get_sources(host_session.ip_hosts)); |
181 for i = 1, #IPs do |
199 for i = 1, #IPs do |
182 IPs[i] = {ip = IPs[i], port = connect_port}; |
200 IPs[i] = {ip = IPs[i], port = connect_port}; |
183 end |
201 end |
184 host_session.ip_choice = 0; |
202 host_session.ip_choice = 0; |
185 s2sout.try_next_ip(host_session); |
203 s2sout.try_next_ip(host_session); |
211 end |
229 end |
212 end |
230 end |
213 |
231 |
214 if have_other_result then |
232 if have_other_result then |
215 if #IPs > 0 then |
233 if #IPs > 0 then |
216 rfc6724_dest(host_session.ip_hosts, sources); |
234 rfc6724_dest(host_session.ip_hosts, get_sources(host_session.ip_hosts)); |
217 for i = 1, #IPs do |
235 for i = 1, #IPs do |
218 IPs[i] = {ip = IPs[i], port = connect_port}; |
236 IPs[i] = {ip = IPs[i], port = connect_port}; |
219 end |
237 end |
220 host_session.ip_choice = 0; |
238 host_session.ip_choice = 0; |
221 s2sout.try_next_ip(host_session); |
239 s2sout.try_next_ip(host_session); |
313 if not s2s_sources then |
331 if not s2s_sources then |
314 module:log("warn", "s2s not listening on any ports, outgoing connections may fail"); |
332 module:log("warn", "s2s not listening on any ports, outgoing connections may fail"); |
315 return; |
333 return; |
316 end |
334 end |
317 for source, _ in pairs(s2s_sources) do |
335 for source, _ in pairs(s2s_sources) do |
318 if source == "*" or source == "0.0.0.0" then |
336 if source:find(":") then |
319 for _, addr in ipairs(local_addresses("ipv4", true)) do |
337 has_ipv6 = true; |
320 sources[#sources + 1] = new_ip(addr, "IPv4"); |
|
321 end |
|
322 elseif source == "::" then |
|
323 for _, addr in ipairs(local_addresses("ipv6", true)) do |
|
324 sources[#sources + 1] = new_ip(addr, "IPv6"); |
|
325 end |
|
326 else |
338 else |
327 sources[#sources + 1] = new_ip(source, (source:find(":") and "IPv6") or "IPv4"); |
|
328 end |
|
329 end |
|
330 for i = 1,#sources do |
|
331 if sources[i].proto == "IPv6" then |
|
332 has_ipv6 = true; |
|
333 elseif sources[i].proto == "IPv4" then |
|
334 has_ipv4 = true; |
339 has_ipv4 = true; |
335 end |
340 end |
336 end |
341 end |
337 if not (has_ipv4 or has_ipv6) then |
|
338 module:log("warn", "No local IPv4 or IPv6 addresses detected, outgoing connections may fail"); |
|
339 end |
|
340 end); |
342 end); |
341 |
343 |
342 return s2sout; |
344 return s2sout; |