Comparison

plugins/mod_s2s/s2sout.lib.lua @ 6054:7a5ddbaf758d

Merge 0.9->0.10
author Matthew Wild <mwild1@gmail.com>
date Wed, 02 Apr 2014 17:41:38 +0100
parent 6017:ac0879a8190a
child 6256:d05627c89c99
comparison
equal deleted inserted replaced
6053:2f93a04564b2 6054:7a5ddbaf758d
1 -- Prosody IM 1 -- Prosody IM
2 -- Copyright (C) 2008-2010 Matthew Wild 2 -- Copyright (C) 2008-2010 Matthew Wild
3 -- Copyright (C) 2008-2010 Waqas Hussain 3 -- Copyright (C) 2008-2010 Waqas Hussain
4 -- 4 --
5 -- This project is MIT/X11 licensed. Please see the 5 -- This project is MIT/X11 licensed. Please see the
6 -- COPYING file in the source package for more information. 6 -- COPYING file in the source package for more information.
7 -- 7 --
8 8
9 --- Module containing all the logic for connecting to a remote server 9 --- Module containing all the logic for connecting to a remote server
45 end 45 end
46 46
47 function s2sout.initiate_connection(host_session) 47 function s2sout.initiate_connection(host_session)
48 initialize_filters(host_session); 48 initialize_filters(host_session);
49 host_session.version = 1; 49 host_session.version = 1;
50 50
51 -- Kick the connection attempting machine into life 51 -- Kick the connection attempting machine into life
52 if not s2sout.attempt_connection(host_session) then 52 if not s2sout.attempt_connection(host_session) then
53 -- Intentionally not returning here, the 53 -- Intentionally not returning here, the
54 -- session is needed, connected or not 54 -- session is needed, connected or not
55 s2s_destroy_session(host_session); 55 s2s_destroy_session(host_session);
56 end 56 end
57 57
58 if not host_session.sends2s then 58 if not host_session.sends2s then
59 -- A sends2s which buffers data (until the stream is opened) 59 -- A sends2s which buffers data (until the stream is opened)
60 -- note that data in this buffer will be sent before the stream is authed 60 -- note that data in this buffer will be sent before the stream is authed
61 -- and will not be ack'd in any way, successful or otherwise 61 -- and will not be ack'd in any way, successful or otherwise
62 local buffer; 62 local buffer;
73 end 73 end
74 74
75 function s2sout.attempt_connection(host_session, err) 75 function s2sout.attempt_connection(host_session, err)
76 local to_host = host_session.to_host; 76 local to_host = host_session.to_host;
77 local connect_host, connect_port = to_host and idna_to_ascii(to_host), 5269; 77 local connect_host, connect_port = to_host and idna_to_ascii(to_host), 5269;
78 78
79 if not connect_host then 79 if not connect_host then
80 return false; 80 return false;
81 end 81 end
82 82
83 if not err then -- This is our first attempt 83 if not err then -- This is our first attempt
84 log("debug", "First attempt to connect to %s, starting with SRV lookup...", to_host); 84 log("debug", "First attempt to connect to %s, starting with SRV lookup...", to_host);
85 host_session.connecting = true; 85 host_session.connecting = true;
86 local handle; 86 local handle;
87 handle = adns.lookup(function (answer) 87 handle = adns.lookup(function (answer)
98 log("debug", "%s does not provide a XMPP service", to_host); 98 log("debug", "%s does not provide a XMPP service", to_host);
99 s2s_destroy_session(host_session, err); -- Nothing to see here 99 s2s_destroy_session(host_session, err); -- Nothing to see here
100 return; 100 return;
101 end 101 end
102 t_sort(srv_hosts, compare_srv_priorities); 102 t_sort(srv_hosts, compare_srv_priorities);
103 103
104 local srv_choice = srv_hosts[1]; 104 local srv_choice = srv_hosts[1];
105 host_session.srv_choice = 1; 105 host_session.srv_choice = 1;
106 if srv_choice then 106 if srv_choice then
107 connect_host, connect_port = srv_choice.target or to_host, srv_choice.port or connect_port; 107 connect_host, connect_port = srv_choice.target or to_host, srv_choice.port or connect_port;
108 log("debug", "Best record found, will connect to %s:%d", connect_host, connect_port); 108 log("debug", "Best record found, will connect to %s:%d", connect_host, connect_port);
117 -- No more attempts will be made 117 -- No more attempts will be made
118 s2s_destroy_session(host_session, err); 118 s2s_destroy_session(host_session, err);
119 end 119 end
120 end 120 end
121 end, "_xmpp-server._tcp."..connect_host..".", "SRV"); 121 end, "_xmpp-server._tcp."..connect_host..".", "SRV");
122 122
123 return true; -- Attempt in progress 123 return true; -- Attempt in progress
124 elseif host_session.ip_hosts then 124 elseif host_session.ip_hosts then
125 return s2sout.try_connect(host_session, connect_host, connect_port, err); 125 return s2sout.try_connect(host_session, connect_host, connect_port, err);
126 elseif host_session.srv_hosts and #host_session.srv_hosts > host_session.srv_choice then -- Not our first attempt, and we also have SRV 126 elseif host_session.srv_hosts and #host_session.srv_hosts > host_session.srv_choice then -- Not our first attempt, and we also have SRV
127 host_session.srv_choice = host_session.srv_choice + 1; 127 host_session.srv_choice = host_session.srv_choice + 1;
128 local srv_choice = host_session.srv_hosts[host_session.srv_choice]; 128 local srv_choice = host_session.srv_hosts[host_session.srv_choice];
129 connect_host, connect_port = srv_choice.target or to_host, srv_choice.port or connect_port; 129 connect_host, connect_port = srv_choice.target or to_host, srv_choice.port or connect_port;
130 host_session.log("info", "Connection failed (%s). Attempt #%d: This time to %s:%d", tostring(err), host_session.srv_choice, connect_host, connect_port); 130 host_session.log("info", "Connection failed (%s). Attempt #%d: This time to %s:%d", tostring(err), host_session.srv_choice, connect_host, connect_port);
131 else 131 else
132 host_session.log("info", "Out of connection options, can't connect to %s", tostring(host_session.to_host)); 132 host_session.log("info", "Failed in all attempts to connect to %s", tostring(host_session.to_host));
133 -- We're out of options 133 -- We're out of options
134 return false; 134 return false;
135 end 135 end
136 136
137 if not (connect_host and connect_port) then 137 if not (connect_host and connect_port) then
138 -- Likely we couldn't resolve DNS 138 -- Likely we couldn't resolve DNS
139 log("warn", "Hmm, we're without a host (%s) and port (%s) to connect to for %s, giving up :(", tostring(connect_host), tostring(connect_port), tostring(to_host)); 139 log("warn", "Hmm, we're without a host (%s) and port (%s) to connect to for %s, giving up :(", tostring(connect_host), tostring(connect_port), tostring(to_host));
140 return false; 140 return false;
141 end 141 end
263 263
264 return true; 264 return true;
265 end 265 end
266 266
267 function s2sout.make_connect(host_session, connect_host, connect_port) 267 function s2sout.make_connect(host_session, connect_host, connect_port)
268 (host_session.log or log)("info", "Beginning new connection attempt to %s ([%s]:%d)", host_session.to_host, connect_host.addr, connect_port); 268 (host_session.log or log)("debug", "Beginning new connection attempt to %s ([%s]:%d)", host_session.to_host, connect_host.addr, connect_port);
269 269
270 -- Reset secure flag in case this is another 270 -- Reset secure flag in case this is another
271 -- connection attempt after a failed STARTTLS 271 -- connection attempt after a failed STARTTLS
272 host_session.secure = nil; 272 host_session.secure = nil;
273 host_session.encrypted = nil;
273 274
274 local conn, handler; 275 local conn, handler;
275 local proto = connect_host.proto; 276 local proto = connect_host.proto;
276 if proto == "IPv4" then 277 if proto == "IPv4" then
277 conn, handler = socket.tcp(); 278 conn, handler = socket.tcp();
278 elseif proto == "IPv6" and socket.tcp6 then 279 elseif proto == "IPv6" and socket.tcp6 then
279 conn, handler = socket.tcp6(); 280 conn, handler = socket.tcp6();
280 else 281 else
281 handler = "Unsupported protocol: "..tostring(proto); 282 handler = "Unsupported protocol: "..tostring(proto);
282 end 283 end
283 284
284 if not conn then 285 if not conn then
285 log("warn", "Failed to create outgoing connection, system error: %s", handler); 286 log("warn", "Failed to create outgoing connection, system error: %s", handler);
286 return false, handler; 287 return false, handler;
287 end 288 end
288 289
290 local success, err = conn:connect(connect_host.addr, connect_port); 291 local success, err = conn:connect(connect_host.addr, connect_port);
291 if not success and err ~= "timeout" then 292 if not success and err ~= "timeout" then
292 log("warn", "s2s connect() to %s (%s:%d) failed: %s", host_session.to_host, connect_host.addr, connect_port, err); 293 log("warn", "s2s connect() to %s (%s:%d) failed: %s", host_session.to_host, connect_host.addr, connect_port, err);
293 return false, err; 294 return false, err;
294 end 295 end
295 296
296 conn = wrapclient(conn, connect_host.addr, connect_port, s2s_listener, "*a"); 297 conn = wrapclient(conn, connect_host.addr, connect_port, s2s_listener, "*a");
297 host_session.conn = conn; 298 host_session.conn = conn;
298 299
299 local filter = initialize_filters(host_session); 300 local filter = initialize_filters(host_session);
300 local w, log = conn.write, host_session.log; 301 local w, log = conn.write, host_session.log;
301 host_session.sends2s = function (t) 302 host_session.sends2s = function (t)
302 log("debug", "sending: %s", (t.top_tag and t:top_tag()) or t:match("^[^>]*>?")); 303 log("debug", "sending: %s", (t.top_tag and t:top_tag()) or t:match("^[^>]*>?"));
303 if t.name then 304 if t.name then
308 if t then 309 if t then
309 return w(conn, tostring(t)); 310 return w(conn, tostring(t));
310 end 311 end
311 end 312 end
312 end 313 end
313 314
314 -- Register this outgoing connection so that xmppserver_listener knows about it 315 -- Register this outgoing connection so that xmppserver_listener knows about it
315 -- otherwise it will assume it is a new incoming connection 316 -- otherwise it will assume it is a new incoming connection
316 s2s_listener.register_outgoing(conn, host_session); 317 s2s_listener.register_outgoing(conn, host_session);
317 318
318 log("debug", "Connection attempt in progress..."); 319 log("debug", "Connection attempt in progress...");
319 return true; 320 return true;
320 end 321 end
321 322
322 module:hook_global("service-added", function (event) 323 module:hook_global("service-added", function (event)