10 conn:unhook("connected", suppress_connected); |
10 conn:unhook("connected", suppress_connected); |
11 return true; |
11 return true; |
12 end |
12 end |
13 local function receive_connection_response(data) |
13 local function receive_connection_response(data) |
14 conn:unhook("incoming-raw", receive_connection_response); |
14 conn:unhook("incoming-raw", receive_connection_response); |
15 |
15 |
16 if data:sub(1, 2) ~= "\005\000" then |
16 if data:sub(1, 2) ~= "\005\000" then |
17 return conn:event("error", "connection-failure"); |
17 return conn:event("error", "connection-failure"); |
18 end |
18 end |
19 conn:event("connected"); |
19 conn:event("connected"); |
20 return true; |
20 return true; |
45 current_host = 0; |
45 current_host = 0; |
46 }); |
46 }); |
47 --Attempt to connect to the next host |
47 --Attempt to connect to the next host |
48 local function attempt_next_streamhost(event) |
48 local function attempt_next_streamhost(event) |
49 if event then |
49 if event then |
50 return callback(nil, event.reason); |
50 return callback(nil, event.reason); |
51 end |
51 end |
52 -- First connect, or the last connect failed |
52 -- First connect, or the last connect failed |
53 if conn.current_host < #conn.streamhosts then |
53 if conn.current_host < #conn.streamhosts then |
54 conn.current_host = conn.current_host + 1; |
54 conn.current_host = conn.current_host + 1; |
55 conn:debug("Attempting to connect to "..conn.streamhosts[conn.current_host].host..":"..conn.streamhosts[conn.current_host].port.."..."); |
55 conn:debug("Attempting to connect to "..conn.streamhosts[conn.current_host].host..":"..conn.streamhosts[conn.current_host].port.."..."); |
56 local ok, err = conn:connect( |
56 local ok, err = conn:connect( |
57 conn.streamhosts[conn.current_host].host, |
57 conn.streamhosts[conn.current_host].host, |
58 conn.streamhosts[conn.current_host].port |
58 conn.streamhosts[conn.current_host].port |
59 ); |
59 ); |
60 if not ok then |
60 if not ok then |
61 conn:debug("Error connecting to proxy (%s:%s): %s", |
61 conn:debug("Error connecting to proxy (%s:%s): %s", |
62 conn.streamhosts[conn.current_host].host, |
62 conn.streamhosts[conn.current_host].host, |
63 conn.streamhosts[conn.current_host].port, |
63 conn.streamhosts[conn.current_host].port, |
64 err |
64 err |
65 ); |
65 ); |
66 else |
66 else |
88 stream:hook("ready", function () |
88 stream:hook("ready", function () |
89 stream:add_disco_feature(xmlns_s5b); |
89 stream:add_disco_feature(xmlns_s5b); |
90 end, 10); |
90 end, 10); |
91 |
91 |
92 local s5b = {}; |
92 local s5b = {}; |
93 |
93 |
94 function s5b:generate_initiate() |
94 function s5b:generate_initiate() |
95 self.s5b_sid = uuid_generate(); |
95 self.s5b_sid = uuid_generate(); |
96 local transport = verse.stanza("transport", { xmlns = xmlns_s5b, |
96 local transport = verse.stanza("transport", { xmlns = xmlns_s5b, |
97 mode = "tcp", sid = self.s5b_sid }); |
97 mode = "tcp", sid = self.s5b_sid }); |
98 local p = 0; |
98 local p = 0; |
102 port = streamhost.port, cid=jid, priority = p, type = "proxy" }):up(); |
102 port = streamhost.port, cid=jid, priority = p, type = "proxy" }):up(); |
103 end |
103 end |
104 stream:debug("Have %d proxies", p) |
104 stream:debug("Have %d proxies", p) |
105 return transport; |
105 return transport; |
106 end |
106 end |
107 |
107 |
108 function s5b:generate_accept(initiate_transport) |
108 function s5b:generate_accept(initiate_transport) |
109 local candidates = {}; |
109 local candidates = {}; |
110 self.s5b_peer_candidates = candidates; |
110 self.s5b_peer_candidates = candidates; |
111 self.s5b_mode = initiate_transport.attr.mode or "tcp"; |
111 self.s5b_mode = initiate_transport.attr.mode or "tcp"; |
112 self.s5b_sid = initiate_transport.attr.sid or self.jingle.sid; |
112 self.s5b_sid = initiate_transport.attr.sid or self.jingle.sid; |
113 |
113 |
114 -- Import the list of candidates the initiator offered us |
114 -- Import the list of candidates the initiator offered us |
115 for candidate in initiate_transport:childtags() do |
115 for candidate in initiate_transport:childtags() do |
116 --if candidate.attr.jid == "asterix4@jabber.lagaule.org/Gajim" |
116 --if candidate.attr.jid == "asterix4@jabber.lagaule.org/Gajim" |
117 --and candidate.attr.host == "82.246.25.239" then |
117 --and candidate.attr.host == "82.246.25.239" then |
118 candidates[candidate.attr.cid] = { |
118 candidates[candidate.attr.cid] = { |
123 priority = tonumber(candidate.attr.priority) or 0; |
123 priority = tonumber(candidate.attr.priority) or 0; |
124 cid = candidate.attr.cid; |
124 cid = candidate.attr.cid; |
125 }; |
125 }; |
126 --end |
126 --end |
127 end |
127 end |
128 |
128 |
129 -- Import our own candidates |
129 -- Import our own candidates |
130 -- TODO ^ |
130 -- TODO ^ |
131 local transport = verse.stanza("transport", { xmlns = xmlns_s5b }); |
131 local transport = verse.stanza("transport", { xmlns = xmlns_s5b }); |
132 return transport; |
132 return transport; |
133 end |
133 end |
134 |
134 |
135 function s5b:connect(callback) |
135 function s5b:connect(callback) |
136 stream:warn("Connecting!"); |
136 stream:warn("Connecting!"); |
137 |
137 |
138 local streamhost_array = {}; |
138 local streamhost_array = {}; |
139 for cid, streamhost in pairs(self.s5b_peer_candidates or {}) do |
139 for cid, streamhost in pairs(self.s5b_peer_candidates or {}) do |
140 streamhost_array[#streamhost_array+1] = streamhost; |
140 streamhost_array[#streamhost_array+1] = streamhost; |
141 end |
141 end |
142 |
142 |
143 if #streamhost_array > 0 then |
143 if #streamhost_array > 0 then |
144 self.connecting_peer_candidates = true; |
144 self.connecting_peer_candidates = true; |
145 local function onconnect(streamhost, conn) |
145 local function onconnect(streamhost, conn) |
146 self.jingle:send_command("transport-info", verse.stanza("content", { creator = self.creator, name = self.name }) |
146 self.jingle:send_command("transport-info", verse.stanza("content", { creator = self.creator, name = self.name }) |
147 :tag("transport", { xmlns = xmlns_s5b, sid = self.s5b_sid }) |
147 :tag("transport", { xmlns = xmlns_s5b, sid = self.s5b_sid }) |
154 else |
154 else |
155 stream:warn("Actually, I'm going to wait for my peer to tell me its streamhost..."); |
155 stream:warn("Actually, I'm going to wait for my peer to tell me its streamhost..."); |
156 self.onconnect_callback = callback; |
156 self.onconnect_callback = callback; |
157 end |
157 end |
158 end |
158 end |
159 |
159 |
160 function s5b:info_received(jingle_tag) |
160 function s5b:info_received(jingle_tag) |
161 stream:warn("Info received"); |
161 stream:warn("Info received"); |
162 local content_tag = jingle_tag:child_with_name("content"); |
162 local content_tag = jingle_tag:child_with_name("content"); |
163 local transport_tag = content_tag:child_with_name("transport"); |
163 local transport_tag = content_tag:child_with_name("transport"); |
164 if transport_tag:get_child("candidate-used") and not self.connecting_peer_candidates then |
164 if transport_tag:get_child("candidate-used") and not self.connecting_peer_candidates then |
169 if self.jingle.role == "initiator" then -- More correct would be - "is this a candidate we offered?" |
169 if self.jingle.role == "initiator" then -- More correct would be - "is this a candidate we offered?" |
170 -- Activate the stream |
170 -- Activate the stream |
171 self.jingle.stream:send_iq(verse.iq({ to = streamhost.jid, type = "set" }) |
171 self.jingle.stream:send_iq(verse.iq({ to = streamhost.jid, type = "set" }) |
172 :tag("query", { xmlns = xmlns_bytestreams, sid = self.s5b_sid }) |
172 :tag("query", { xmlns = xmlns_bytestreams, sid = self.s5b_sid }) |
173 :tag("activate"):text(self.jingle.peer), function (result) |
173 :tag("activate"):text(self.jingle.peer), function (result) |
174 |
174 |
175 if result.attr.type == "result" then |
175 if result.attr.type == "result" then |
176 self.jingle:send_command("transport-info", verse.stanza("content", content_tag.attr) |
176 self.jingle:send_command("transport-info", verse.stanza("content", content_tag.attr) |
177 :tag("transport", { xmlns = xmlns_s5b, sid = self.s5b_sid }) |
177 :tag("transport", { xmlns = xmlns_s5b, sid = self.s5b_sid }) |
178 :tag("activated", { cid = candidate_used.attr.cid })); |
178 :tag("activated", { cid = candidate_used.attr.cid })); |
179 self.conn = conn; |
179 self.conn = conn; |
182 self.jingle.stream:error("Failed to activate bytestream"); |
182 self.jingle.stream:error("Failed to activate bytestream"); |
183 end |
183 end |
184 end); |
184 end); |
185 end |
185 end |
186 end |
186 end |
187 |
187 |
188 -- FIXME: Another assumption that cid==jid, and that it was our candidate |
188 -- FIXME: Another assumption that cid==jid, and that it was our candidate |
189 self.jingle.stream:debug("CID: %s", self.jingle.stream.proxy65.available_streamhosts[candidate_used.attr.cid]); |
189 self.jingle.stream:debug("CID: %s", self.jingle.stream.proxy65.available_streamhosts[candidate_used.attr.cid]); |
190 local streamhost_array = { |
190 local streamhost_array = { |
191 self.jingle.stream.proxy65.available_streamhosts[candidate_used.attr.cid]; |
191 self.jingle.stream.proxy65.available_streamhosts[candidate_used.attr.cid]; |
192 }; |
192 }; |
196 end |
196 end |
197 elseif transport_tag:get_child("activated") then |
197 elseif transport_tag:get_child("activated") then |
198 self.onconnect_callback(self.conn); |
198 self.onconnect_callback(self.conn); |
199 end |
199 end |
200 end |
200 end |
201 |
201 |
202 function s5b:disconnect() |
202 function s5b:disconnect() |
203 if self.conn then |
203 if self.conn then |
204 self.conn:close(); |
204 self.conn:close(); |
205 end |
205 end |
206 end |
206 end |
207 |
207 |
208 function s5b:handle_accepted(jingle_tag) |
208 function s5b:handle_accepted(jingle_tag) |
209 end |
209 end |
210 |
210 |
211 local s5b_mt = { __index = s5b }; |
211 local s5b_mt = { __index = s5b }; |
212 stream:hook("jingle/transport/"..xmlns_s5b, function (jingle) |
212 stream:hook("jingle/transport/"..xmlns_s5b, function (jingle) |