17 -- Fill list with available proxies |
17 -- Fill list with available proxies |
18 if service.type == "bytestreams" then |
18 if service.type == "bytestreams" then |
19 outstanding_proxies = outstanding_proxies + 1; |
19 outstanding_proxies = outstanding_proxies + 1; |
20 stream:send_iq(verse.iq({ to = service.jid, type = "get" }) |
20 stream:send_iq(verse.iq({ to = service.jid, type = "get" }) |
21 :tag("query", { xmlns = xmlns_bytestreams }), function (result) |
21 :tag("query", { xmlns = xmlns_bytestreams }), function (result) |
22 |
22 |
23 outstanding_proxies = outstanding_proxies - 1; |
23 outstanding_proxies = outstanding_proxies - 1; |
24 if result.attr.type == "result" then |
24 if result.attr.type == "result" then |
25 local streamhost = result:get_child("query", xmlns_bytestreams) |
25 local streamhost = result:get_child("query", xmlns_bytestreams) |
26 :get_child("streamhost").attr; |
26 :get_child("streamhost").attr; |
27 |
27 |
28 stream.proxy65.available_streamhosts[streamhost.jid] = { |
28 stream.proxy65.available_streamhosts[streamhost.jid] = { |
29 jid = streamhost.jid; |
29 jid = streamhost.jid; |
30 host = streamhost.host; |
30 host = streamhost.host; |
31 port = tonumber(streamhost.port); |
31 port = tonumber(streamhost.port); |
32 }; |
32 }; |
41 local conn = verse.new(nil, { |
41 local conn = verse.new(nil, { |
42 initiator_jid = request.attr.from, |
42 initiator_jid = request.attr.from, |
43 streamhosts = {}, |
43 streamhosts = {}, |
44 current_host = 0; |
44 current_host = 0; |
45 }); |
45 }); |
46 |
46 |
47 -- Parse hosts from request |
47 -- Parse hosts from request |
48 for tag in request.tags[1]:childtags() do |
48 for tag in request.tags[1]:childtags() do |
49 if tag.name == "streamhost" then |
49 if tag.name == "streamhost" then |
50 table.insert(conn.streamhosts, tag.attr); |
50 table.insert(conn.streamhosts, tag.attr); |
51 end |
51 end |
52 end |
52 end |
53 |
53 |
54 --Attempt to connect to the next host |
54 --Attempt to connect to the next host |
55 local function attempt_next_streamhost() |
55 local function attempt_next_streamhost() |
56 -- First connect, or the last connect failed |
56 -- First connect, or the last connect failed |
57 if conn.current_host < #conn.streamhosts then |
57 if conn.current_host < #conn.streamhosts then |
58 conn.current_host = conn.current_host + 1; |
58 conn.current_host = conn.current_host + 1; |
66 -- All streamhosts tried, none successful |
66 -- All streamhosts tried, none successful |
67 conn:unhook("disconnected", attempt_next_streamhost); |
67 conn:unhook("disconnected", attempt_next_streamhost); |
68 stream:send(verse.error_reply(request, "cancel", "item-not-found")); |
68 stream:send(verse.error_reply(request, "cancel", "item-not-found")); |
69 -- Let disconnected event fall through to user handlers... |
69 -- Let disconnected event fall through to user handlers... |
70 end |
70 end |
71 |
71 |
72 function conn:accept() |
72 function conn:accept() |
73 conn:hook("disconnected", attempt_next_streamhost, 100); |
73 conn:hook("disconnected", attempt_next_streamhost, 100); |
74 -- When this event fires, we're connected to a streamhost |
74 -- When this event fires, we're connected to a streamhost |
75 conn:hook("connected", function () |
75 conn:hook("connected", function () |
76 conn:unhook("disconnected", attempt_next_streamhost); |
76 conn:unhook("disconnected", attempt_next_streamhost); |
92 function proxy65_mt:new(target_jid, proxies) |
92 function proxy65_mt:new(target_jid, proxies) |
93 local conn = verse.new(nil, { |
93 local conn = verse.new(nil, { |
94 target_jid = target_jid; |
94 target_jid = target_jid; |
95 bytestream_sid = uuid.generate(); |
95 bytestream_sid = uuid.generate(); |
96 }); |
96 }); |
97 |
97 |
98 local request = verse.iq{type="set", to = target_jid} |
98 local request = verse.iq{type="set", to = target_jid} |
99 :tag("query", { xmlns = xmlns_bytestreams, mode = "tcp", sid = conn.bytestream_sid }); |
99 :tag("query", { xmlns = xmlns_bytestreams, mode = "tcp", sid = conn.bytestream_sid }); |
100 for _, proxy in ipairs(proxies or self.proxies) do |
100 for _, proxy in ipairs(proxies or self.proxies) do |
101 request:tag("streamhost", proxy):up(); |
101 request:tag("streamhost", proxy):up(); |
102 end |
102 end |
103 |
103 |
104 |
104 |
105 self.stream:send_iq(request, function (reply) |
105 self.stream:send_iq(request, function (reply) |
106 if reply.attr.type == "error" then |
106 if reply.attr.type == "error" then |
107 local type, condition, text = reply:get_error(); |
107 local type, condition, text = reply:get_error(); |
108 conn:event("connection-failed", { conn = conn, type = type, condition = condition, text = text }); |
108 conn:event("connection-failed", { conn = conn, type = type, condition = condition, text = text }); |
109 else |
109 else |
121 end |
121 end |
122 end |
122 end |
123 if not (host and port) then |
123 if not (host and port) then |
124 --FIXME: Emit error |
124 --FIXME: Emit error |
125 end |
125 end |
126 |
126 |
127 conn:connect(host, port); |
127 conn:connect(host, port); |
128 |
128 |
129 local function handle_proxy_connected() |
129 local function handle_proxy_connected() |
130 conn:unhook("connected", handle_proxy_connected); |
130 conn:unhook("connected", handle_proxy_connected); |
131 -- Both of us connected, tell proxy to activate connection |
131 -- Both of us connected, tell proxy to activate connection |
156 conn:unhook("connected", suppress_connected); |
156 conn:unhook("connected", suppress_connected); |
157 return true; |
157 return true; |
158 end |
158 end |
159 local function receive_connection_response(data) |
159 local function receive_connection_response(data) |
160 conn:unhook("incoming-raw", receive_connection_response); |
160 conn:unhook("incoming-raw", receive_connection_response); |
161 |
161 |
162 if data:sub(1, 2) ~= "\005\000" then |
162 if data:sub(1, 2) ~= "\005\000" then |
163 return conn:event("error", "connection-failure"); |
163 return conn:event("error", "connection-failure"); |
164 end |
164 end |
165 conn:event("connected"); |
165 conn:event("connected"); |
166 return true; |
166 return true; |