Software / code / prosody
Comparison
core/s2smanager.lua @ 974:82f7261c0482
Merge
| author | Matthew Wild <mwild1@gmail.com> |
|---|---|
| date | Fri, 10 Apr 2009 10:31:38 +0100 |
| parent | 963:43b140edfd84 |
| child | 976:17af9851c81d |
comparison
equal
deleted
inserted
replaced
| 973:b091a1a7273b | 974:82f7261c0482 |
|---|---|
| 34 | 34 |
| 35 local sha256_hash = require "util.hashes".sha256; | 35 local sha256_hash = require "util.hashes".sha256; |
| 36 | 36 |
| 37 local dialback_secret = sha256_hash(tostring{} .. math.random() .. socket.gettime(), true); | 37 local dialback_secret = sha256_hash(tostring{} .. math.random() .. socket.gettime(), true); |
| 38 | 38 |
| 39 local dns = require "net.dns"; | 39 local adns = require "net.adns"; |
| 40 | |
| 41 local debug = debug; | |
| 40 | 42 |
| 41 incoming_s2s = {}; | 43 incoming_s2s = {}; |
| 42 local incoming_s2s = incoming_s2s; | 44 local incoming_s2s = incoming_s2s; |
| 43 | 45 |
| 44 module "s2smanager" | 46 module "s2smanager" |
| 103 else | 105 else |
| 104 log("debug", "opening a new outgoing connection for this stanza"); | 106 log("debug", "opening a new outgoing connection for this stanza"); |
| 105 local host_session = new_outgoing(from_host, to_host); | 107 local host_session = new_outgoing(from_host, to_host); |
| 106 -- Store in buffer | 108 -- Store in buffer |
| 107 host_session.sendq = { {tostring(data), st.reply(data)} }; | 109 host_session.sendq = { {tostring(data), st.reply(data)} }; |
| 108 if not host_session.conn then destroy_session(host_session); end | 110 if (not host_session.connecting) and (not host_session.conn) then destroy_session(host_session); end |
| 109 end | 111 end |
| 110 end | 112 end |
| 111 | 113 |
| 112 local open_sessions = 0; | 114 local open_sessions = 0; |
| 113 | 115 |
| 141 end | 143 end |
| 142 | 144 |
| 143 | 145 |
| 144 function attempt_connection(host_session, err) | 146 function attempt_connection(host_session, err) |
| 145 local from_host, to_host = host_session.from_host, host_session.to_host; | 147 local from_host, to_host = host_session.from_host, host_session.to_host; |
| 146 local conn, handler = socket.tcp() | |
| 147 | |
| 148 local connect_host, connect_port = idna_to_ascii(to_host), 5269; | 148 local connect_host, connect_port = idna_to_ascii(to_host), 5269; |
| 149 | 149 |
| 150 if not err then -- This is our first attempt | 150 if not err then -- This is our first attempt |
| 151 local answer = dns.lookup("_xmpp-server._tcp."..connect_host..".", "SRV"); | 151 host_session.connecting = true; |
| 152 | 152 local answer = |
| 153 if answer then | 153 adns.lookup(function (answer) |
| 154 log("debug", to_host.." has SRV records, handling..."); | 154 host_session.connecting = nil; |
| 155 local srv_hosts = {}; | 155 if answer then |
| 156 host_session.srv_hosts = srv_hosts; | 156 log("debug", to_host.." has SRV records, handling..."); |
| 157 for _, record in ipairs(answer) do | 157 local srv_hosts = {}; |
| 158 t_insert(srv_hosts, record.srv); | 158 host_session.srv_hosts = srv_hosts; |
| 159 end | 159 for _, record in ipairs(answer) do |
| 160 t_sort(srv_hosts, compare_srv_priorities); | 160 t_insert(srv_hosts, record.srv); |
| 161 | 161 end |
| 162 local srv_choice = srv_hosts[1]; | 162 t_sort(srv_hosts, compare_srv_priorities); |
| 163 host_session.srv_choice = 1; | 163 |
| 164 if srv_choice then | 164 local srv_choice = srv_hosts[1]; |
| 165 connect_host, connect_port = srv_choice.target or to_host, srv_choice.port or connect_port; | 165 host_session.srv_choice = 1; |
| 166 log("debug", "Best record found, will connect to %s:%d", connect_host, connect_port); | 166 if srv_choice then |
| 167 end | 167 connect_host, connect_port = srv_choice.target or to_host, srv_choice.port or connect_port; |
| 168 end | 168 log("debug", "Best record found, will connect to %s:%d", connect_host, connect_port); |
| 169 end | |
| 170 else | |
| 171 log("debug", to_host.." has no SRV records, falling back to A"); | |
| 172 end | |
| 173 -- Try with SRV, or just the plain hostname if no SRV | |
| 174 return try_connect(host_session, connect_host, connect_port); | |
| 175 end, "_xmpp-server._tcp."..connect_host..".", "SRV"); | |
| 176 return true; -- Attempt in progress | |
| 169 elseif host_session.srv_hosts and #host_session.srv_hosts > host_session.srv_choice then -- Not our first attempt, and we also have SRV | 177 elseif host_session.srv_hosts and #host_session.srv_hosts > host_session.srv_choice then -- Not our first attempt, and we also have SRV |
| 170 host_session.srv_choice = host_session.srv_choice + 1; | 178 host_session.srv_choice = host_session.srv_choice + 1; |
| 171 local srv_choice = host_session.srv_hosts[host_session.srv_choice]; | 179 local srv_choice = host_session.srv_hosts[host_session.srv_choice]; |
| 172 connect_host, connect_port = srv_choice.target or to_host, srv_choice.port or connect_port; | 180 connect_host, connect_port = srv_choice.target or to_host, srv_choice.port or connect_port; |
| 173 host_session.log("debug", "Connection failed (%s). Attempt #%d: This time to %s:%d", tostring(err), host_session.srv_choice, connect_host, connect_port); | 181 host_session.log("debug", "Connection failed (%s). Attempt #%d: This time to %s:%d", tostring(err), host_session.srv_choice, connect_host, connect_port); |
| 180 if not (connect_host and connect_port) then | 188 if not (connect_host and connect_port) then |
| 181 -- Likely we couldn't resolve DNS | 189 -- Likely we couldn't resolve DNS |
| 182 return false; | 190 return false; |
| 183 end | 191 end |
| 184 | 192 |
| 193 return try_connect(host_session, connect_host, connect_port); | |
| 194 end | |
| 195 | |
| 196 function try_connect(host_session, connect_host, connect_port) | |
| 197 log("debug", "Beginning new connection attempt to %s (%s:%d)", host_session.to_host, connect_host, connect_port); | |
| 185 -- Ok, we're going to try to connect | 198 -- Ok, we're going to try to connect |
| 199 | |
| 200 local from_host, to_host = host_session.from_host, host_session.to_host; | |
| 201 | |
| 202 local conn, handler = socket.tcp() | |
| 203 | |
| 186 conn:settimeout(0); | 204 conn:settimeout(0); |
| 187 local success, err = conn:connect(connect_host, connect_port); | 205 local success, err = conn:connect(connect_host, connect_port); |
| 188 if not success and err ~= "timeout" then | 206 if not success and err ~= "timeout" then |
| 189 log("warn", "s2s connect() failed: %s", err); | 207 log("warn", "s2s connect() failed: %s", err); |
| 190 return false; | 208 return false; |
| 192 | 210 |
| 193 local cl = connlisteners_get("xmppserver"); | 211 local cl = connlisteners_get("xmppserver"); |
| 194 conn = wrapclient(conn, connect_host, connect_port, cl, cl.default_mode or 1, hosts[from_host].ssl_ctx, false ); | 212 conn = wrapclient(conn, connect_host, connect_port, cl, cl.default_mode or 1, hosts[from_host].ssl_ctx, false ); |
| 195 host_session.conn = conn; | 213 host_session.conn = conn; |
| 196 | 214 |
| 215 log("debug", "conn wrapped") | |
| 197 -- Register this outgoing connection so that xmppserver_listener knows about it | 216 -- Register this outgoing connection so that xmppserver_listener knows about it |
| 198 -- otherwise it will assume it is a new incoming connection | 217 -- otherwise it will assume it is a new incoming connection |
| 199 cl.register_outgoing(conn, host_session); | 218 cl.register_outgoing(conn, host_session); |
| 200 | 219 |
| 220 log("debug", "outgoing registered") | |
| 221 | |
| 201 local w = conn.write; | 222 local w = conn.write; |
| 202 host_session.sends2s = function (t) log("debug", "sending: %s", tostring(t)); w(tostring(t)); end | 223 host_session.sends2s = function (t) log("debug", "sending: %s", tostring(t)); w(tostring(t)); end |
| 203 | 224 |
| 204 conn.write(format([[<stream:stream xmlns='jabber:server' xmlns:db='jabber:server:dialback' xmlns:stream='http://etherx.jabber.org/streams' from='%s' to='%s' version='1.0'>]], from_host, to_host)); | 225 conn.write(format([[<stream:stream xmlns='jabber:server' xmlns:db='jabber:server:dialback' xmlns:stream='http://etherx.jabber.org/streams' from='%s' to='%s' version='1.0'>]], from_host, to_host)); |
| 226 log("debug", "Connection attempt in progress..."); | |
| 227 print("foo") | |
| 205 return true; | 228 return true; |
| 206 end | 229 end |
| 207 | 230 |
| 208 function streamopened(session, attr) | 231 function streamopened(session, attr) |
| 209 local send = session.sends2s; | 232 local send = session.sends2s; |
| 313 end | 336 end |
| 314 | 337 |
| 315 function destroy_session(session) | 338 function destroy_session(session) |
| 316 (session.log or log)("info", "Destroying "..tostring(session.direction).." session "..tostring(session.from_host).."->"..tostring(session.to_host)); | 339 (session.log or log)("info", "Destroying "..tostring(session.direction).." session "..tostring(session.from_host).."->"..tostring(session.to_host)); |
| 317 | 340 |
| 341 log("debug", debug.traceback()); | |
| 318 | 342 |
| 319 if session.direction == "outgoing" then | 343 if session.direction == "outgoing" then |
| 320 hosts[session.from_host].s2sout[session.to_host] = nil; | 344 hosts[session.from_host].s2sout[session.to_host] = nil; |
| 321 bounce_sendq(session); | 345 bounce_sendq(session); |
| 322 elseif session.direction == "incoming" then | 346 elseif session.direction == "incoming" then |