Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(141)

Side by Side Diff: remoting/protocol/jingle_messages.cc

Issue 2805173005: Move SignalingAddress to remoting/signaling (Closed)
Patch Set: fix compilation on windows Created 3 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « remoting/protocol/jingle_messages.h ('k') | remoting/protocol/jingle_messages_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "remoting/protocol/jingle_messages.h" 5 #include "remoting/protocol/jingle_messages.h"
6 6
7 #include "base/logging.h" 7 #include "base/logging.h"
8 #include "base/strings/string_number_conversions.h" 8 #include "base/strings/string_number_conversions.h"
9 #include "remoting/base/constants.h" 9 #include "remoting/base/constants.h"
10 #include "remoting/base/name_value_map.h" 10 #include "remoting/base/name_value_map.h"
11 #include "remoting/base/remoting_bot.h" 11 #include "remoting/base/remoting_bot.h"
12 #include "remoting/protocol/content_description.h" 12 #include "remoting/protocol/content_description.h"
13 #include "remoting/protocol/session_plugin.h" 13 #include "remoting/protocol/session_plugin.h"
14 #include "remoting/signaling/jid_util.h"
15 #include "third_party/libjingle_xmpp/xmllite/xmlelement.h" 14 #include "third_party/libjingle_xmpp/xmllite/xmlelement.h"
16 15
17 using buzz::QName; 16 using buzz::QName;
18 using buzz::XmlElement; 17 using buzz::XmlElement;
19 18
20 namespace remoting { 19 namespace remoting {
21 namespace protocol { 20 namespace protocol {
22 21
23 namespace { 22 namespace {
24 23
25 const char kJabberNamespace[] = "jabber:client"; 24 const char kJabberNamespace[] = "jabber:client";
26 const char kJingleNamespace[] = "urn:xmpp:jingle:1"; 25 const char kJingleNamespace[] = "urn:xmpp:jingle:1";
27 26
28 // Namespace for transport messages when using standard ICE. 27 // Namespace for transport messages when using standard ICE.
29 const char kIceTransportNamespace[] = "google:remoting:ice"; 28 const char kIceTransportNamespace[] = "google:remoting:ice";
30 29
31 const char kWebrtcTransportNamespace[] = "google:remoting:webrtc"; 30 const char kWebrtcTransportNamespace[] = "google:remoting:webrtc";
32 31
33 const char kEmptyNamespace[] = ""; 32 const char kEmptyNamespace[] = "";
34 const char kXmlNamespace[] = "http://www.w3.org/XML/1998/namespace"; 33 const char kXmlNamespace[] = "http://www.w3.org/XML/1998/namespace";
35 34
36 const int kPortMin = 1000; 35 const int kPortMin = 1000;
37 const int kPortMax = 65535; 36 const int kPortMax = 65535;
38 37
39 const NameMapElement<SignalingAddress::Channel> kChannelTypes[] = {
40 {SignalingAddress::Channel::LCS, "lcs"},
41 {SignalingAddress::Channel::XMPP, "xmpp"},
42 };
43
44 const NameMapElement<JingleMessage::ActionType> kActionTypes[] = { 38 const NameMapElement<JingleMessage::ActionType> kActionTypes[] = {
45 { JingleMessage::SESSION_INITIATE, "session-initiate" }, 39 { JingleMessage::SESSION_INITIATE, "session-initiate" },
46 { JingleMessage::SESSION_ACCEPT, "session-accept" }, 40 { JingleMessage::SESSION_ACCEPT, "session-accept" },
47 { JingleMessage::SESSION_TERMINATE, "session-terminate" }, 41 { JingleMessage::SESSION_TERMINATE, "session-terminate" },
48 { JingleMessage::SESSION_INFO, "session-info" }, 42 { JingleMessage::SESSION_INFO, "session-info" },
49 { JingleMessage::TRANSPORT_INFO, "transport-info" }, 43 { JingleMessage::TRANSPORT_INFO, "transport-info" },
50 }; 44 };
51 45
52 const NameMapElement<JingleMessage::Reason> kReasons[] = { 46 const NameMapElement<JingleMessage::Reason> kReasons[] = {
53 { JingleMessage::SUCCESS, "success" }, 47 { JingleMessage::SUCCESS, "success" },
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after
144 result->SetAttr(QName(kEmptyNamespace, "type"), candidate.candidate.type()); 138 result->SetAttr(QName(kEmptyNamespace, "type"), candidate.candidate.type());
145 result->SetAttr(QName(kEmptyNamespace, "protocol"), 139 result->SetAttr(QName(kEmptyNamespace, "protocol"),
146 candidate.candidate.protocol()); 140 candidate.candidate.protocol());
147 result->SetAttr(QName(kEmptyNamespace, "priority"), 141 result->SetAttr(QName(kEmptyNamespace, "priority"),
148 base::UintToString(candidate.candidate.priority())); 142 base::UintToString(candidate.candidate.priority()));
149 result->SetAttr(QName(kEmptyNamespace, "generation"), 143 result->SetAttr(QName(kEmptyNamespace, "generation"),
150 base::UintToString(candidate.candidate.generation())); 144 base::UintToString(candidate.candidate.generation()));
151 return result; 145 return result;
152 } 146 }
153 147
154 // Represents the XML attrbute names for the various address fields in the
155 // iq stanza.
156 enum class Field { JID, CHANNEL, ENDPOINT_ID };
157
158 buzz::QName GetQNameByField(Field attr, bool from) {
159 std::string attribute_name;
160 switch (attr) {
161 case Field::JID:
162 attribute_name = (from) ? "from" : "to";
163 break;
164 case Field::ENDPOINT_ID:
165 attribute_name = (from) ? "from-endpoint-id" : "to-endpoint-id";
166 break;
167 case Field::CHANNEL:
168 attribute_name = (from) ? "from-channel" : "to-channel";
169 break;
170 default:
171 NOTREACHED();
172 }
173 return QName(kEmptyNamespace, attribute_name);
174 }
175
176 SignalingAddress ParseAddress(
177 const buzz::XmlElement* iq, bool from, std::string* error) {
178 std::string jid(iq->Attr(GetQNameByField(Field::JID, from)));
179 if (jid.empty()) {
180 return SignalingAddress();
181 }
182
183 const XmlElement* jingle = iq->FirstNamed(QName(kJingleNamespace, "jingle"));
184
185 if (!jingle) {
186 return SignalingAddress(jid);
187 }
188
189 std::string type(iq->Attr(QName(std::string(), "type")));
190 // For error IQs, flips the |from| flag as the jingle node represents the
191 // original request.
192 if (type == "error") {
193 from = !from;
194 }
195
196 std::string endpoint_id(
197 jingle->Attr(GetQNameByField(Field::ENDPOINT_ID, from)));
198 std::string channel_str(jingle->Attr(GetQNameByField(Field::CHANNEL, from)));
199 SignalingAddress::Channel channel;
200
201 if (channel_str.empty()) {
202 channel = SignalingAddress::Channel::XMPP;
203 } else if (!NameToValue(kChannelTypes, channel_str, &channel)) {
204 *error = "Unknown channel: " + channel_str;
205 return SignalingAddress();
206 }
207
208 bool is_lcs = (channel == SignalingAddress::Channel::LCS);
209
210 if (is_lcs == endpoint_id.empty()) {
211 *error = (is_lcs ? "Missing |endpoint-id| for LCS channel"
212 : "|endpoint_id| should be empty for XMPP channel");
213 return SignalingAddress();
214 }
215
216 if (from && is_lcs && !IsValidBotJid(jid)) {
217 *error = "Reject LCS message from untrusted sender: " + jid;
218 return SignalingAddress();
219 }
220
221 return SignalingAddress(jid, endpoint_id, channel);
222 }
223
224 void SetAddress(buzz::XmlElement* iq,
225 buzz::XmlElement* jingle,
226 const SignalingAddress& address,
227 bool from) {
228 if (address.empty()) {
229 return;
230 }
231
232 // Always set the JID.
233 iq->SetAttr(GetQNameByField(Field::JID, from), address.jid());
234
235 // Do not tamper the routing-info in the jingle tag for error IQ's, as
236 // it corresponds to the original message.
237 std::string type(iq->Attr(QName(std::string(), "type")));
238 if (type == "error") {
239 return;
240 }
241
242 // Start from a fresh slate regardless of the previous address format.
243 jingle->ClearAttr(GetQNameByField(Field::CHANNEL, from));
244 jingle->ClearAttr(GetQNameByField(Field::ENDPOINT_ID, from));
245
246 // Only set the channel and endpoint_id in the LCS channel.
247 if (address.channel() == SignalingAddress::Channel::LCS) {
248 jingle->AddAttr(GetQNameByField(Field::ENDPOINT_ID, from),
249 address.endpoint_id());
250 jingle->AddAttr(GetQNameByField(Field::CHANNEL, from),
251 ValueToName(kChannelTypes, address.channel()));
252 }
253 }
254
255 } // namespace 148 } // namespace
256 149
257 SignalingAddress::SignalingAddress()
258 : channel_(SignalingAddress::Channel::XMPP) {}
259
260 SignalingAddress::SignalingAddress(const std::string& jid)
261 : jid_(NormalizeJid(jid)), channel_(SignalingAddress::Channel::XMPP) {
262 DCHECK(!jid.empty());
263 }
264
265 SignalingAddress::SignalingAddress(const std::string& jid,
266 const std::string& endpoint_id,
267 Channel channel)
268 : jid_(NormalizeJid(jid)),
269 endpoint_id_(NormalizeJid(endpoint_id)),
270 channel_(channel) {
271 DCHECK(!jid.empty());
272 }
273
274 bool SignalingAddress::operator==(const SignalingAddress& other) const {
275 return (other.jid_ == jid_) && (other.endpoint_id_ == endpoint_id_) &&
276 (other.channel_ == channel_);
277 }
278
279 bool SignalingAddress::operator!=(const SignalingAddress& other) const {
280 return !(*this == other);
281 }
282
283 // static 150 // static
284 bool JingleMessage::IsJingleMessage(const buzz::XmlElement* stanza) { 151 bool JingleMessage::IsJingleMessage(const buzz::XmlElement* stanza) {
285 return stanza->Name() == QName(kJabberNamespace, "iq") && 152 return stanza->Name() == QName(kJabberNamespace, "iq") &&
286 stanza->Attr(QName(std::string(), "type")) == "set" && 153 stanza->Attr(QName(std::string(), "type")) == "set" &&
287 stanza->FirstNamed(QName(kJingleNamespace, "jingle")) != nullptr; 154 stanza->FirstNamed(QName(kJingleNamespace, "jingle")) != nullptr;
288 } 155 }
289 156
290 // static 157 // static
291 std::string JingleMessage::GetActionName(ActionType action) { 158 std::string JingleMessage::GetActionName(ActionType action) {
292 return ValueToName(kActionTypes, action); 159 return ValueToName(kActionTypes, action);
(...skipping 15 matching lines...) Expand all
308 return false; 175 return false;
309 } 176 }
310 177
311 const XmlElement* jingle_tag = 178 const XmlElement* jingle_tag =
312 stanza->FirstNamed(QName(kJingleNamespace, "jingle")); 179 stanza->FirstNamed(QName(kJingleNamespace, "jingle"));
313 if (!jingle_tag) { 180 if (!jingle_tag) {
314 *error = "Not a jingle message"; 181 *error = "Not a jingle message";
315 return false; 182 return false;
316 } 183 }
317 184
318 from = ParseAddress(stanza, true, error); 185 from = SignalingAddress::Parse(stanza, SignalingAddress::FROM, error);
319 if (!error->empty()) { 186 to = SignalingAddress::Parse(stanza, SignalingAddress::TO, error);
187 if (from.empty() || to.empty()) {
320 return false; 188 return false;
321 } 189 }
322 190
323 to = ParseAddress(stanza, false, error);
324 if (!error->empty()) {
325 return false;
326 }
327
328 initiator = jingle_tag->Attr(QName(kEmptyNamespace, "initiator")); 191 initiator = jingle_tag->Attr(QName(kEmptyNamespace, "initiator"));
329 192
330 std::string action_str = jingle_tag->Attr(QName(kEmptyNamespace, "action")); 193 std::string action_str = jingle_tag->Attr(QName(kEmptyNamespace, "action"));
331 if (action_str.empty()) { 194 if (action_str.empty()) {
332 *error = "action attribute is missing"; 195 *error = "action attribute is missing";
333 return false; 196 return false;
334 } 197 }
335 if (!NameToValue(kActionTypes, action_str, &action)) { 198 if (!NameToValue(kActionTypes, action_str, &action)) {
336 *error = "Unknown action " + action_str; 199 *error = "Unknown action " + action_str;
337 return false; 200 return false;
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after
443 std::unique_ptr<XmlElement> root( 306 std::unique_ptr<XmlElement> root(
444 new XmlElement(QName("jabber:client", "iq"), true)); 307 new XmlElement(QName("jabber:client", "iq"), true));
445 308
446 DCHECK(!to.empty()); 309 DCHECK(!to.empty());
447 root->SetAttr(QName(kEmptyNamespace, "type"), "set"); 310 root->SetAttr(QName(kEmptyNamespace, "type"), "set");
448 311
449 XmlElement* jingle_tag = 312 XmlElement* jingle_tag =
450 new XmlElement(QName(kJingleNamespace, "jingle"), true); 313 new XmlElement(QName(kJingleNamespace, "jingle"), true);
451 root->AddElement(jingle_tag); 314 root->AddElement(jingle_tag);
452 jingle_tag->AddAttr(QName(kEmptyNamespace, "sid"), sid); 315 jingle_tag->AddAttr(QName(kEmptyNamespace, "sid"), sid);
453 SetAddress(root.get(), jingle_tag, to, false); 316
454 SetAddress(root.get(), jingle_tag, from, true); 317 to.SetInMessage(root.get(), SignalingAddress::TO);
318 if (!from.empty())
319 from.SetInMessage(root.get(), SignalingAddress::FROM);
455 320
456 const char* action_attr = ValueToName(kActionTypes, action); 321 const char* action_attr = ValueToName(kActionTypes, action);
457 if (!action_attr) { 322 if (!action_attr) {
458 LOG(FATAL) << "Invalid action value " << action; 323 LOG(FATAL) << "Invalid action value " << action;
459 } 324 }
460 jingle_tag->AddAttr(QName(kEmptyNamespace, "action"), action_attr); 325 jingle_tag->AddAttr(QName(kEmptyNamespace, "action"), action_attr);
461 326
462 if (attachments) { 327 if (attachments) {
463 jingle_tag->AddElement(new XmlElement(*attachments)); 328 jingle_tag->AddElement(new XmlElement(*attachments));
464 } 329 }
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after
543 std::unique_ptr<buzz::XmlElement> JingleMessageReply::ToXml( 408 std::unique_ptr<buzz::XmlElement> JingleMessageReply::ToXml(
544 const buzz::XmlElement* request_stanza) const { 409 const buzz::XmlElement* request_stanza) const {
545 std::unique_ptr<XmlElement> iq( 410 std::unique_ptr<XmlElement> iq(
546 new XmlElement(QName(kJabberNamespace, "iq"), true)); 411 new XmlElement(QName(kJabberNamespace, "iq"), true));
547 412
548 iq->SetAttr(QName(kEmptyNamespace, "id"), 413 iq->SetAttr(QName(kEmptyNamespace, "id"),
549 request_stanza->Attr(QName(kEmptyNamespace, "id"))); 414 request_stanza->Attr(QName(kEmptyNamespace, "id")));
550 415
551 SignalingAddress original_from; 416 SignalingAddress original_from;
552 std::string error_message; 417 std::string error_message;
553 original_from = ParseAddress(request_stanza, true, &error_message); 418 original_from = SignalingAddress::Parse(
554 DCHECK(error_message.empty()); 419 request_stanza, SignalingAddress::FROM, &error_message);
420 DCHECK(!original_from.empty());
555 421
556 if (type == REPLY_RESULT) { 422 if (type == REPLY_RESULT) {
557 iq->SetAttr(QName(kEmptyNamespace, "type"), "result"); 423 iq->SetAttr(QName(kEmptyNamespace, "type"), "result");
558 XmlElement* jingle = 424 XmlElement* jingle =
559 new XmlElement(QName(kJingleNamespace, "jingle"), true); 425 new XmlElement(QName(kJingleNamespace, "jingle"), true);
560 iq->AddElement(jingle); 426 iq->AddElement(jingle);
561 SetAddress(iq.get(), jingle, original_from, false); 427 original_from.SetInMessage(iq.get(), SignalingAddress::TO);
562 return iq; 428 return iq;
563 } 429 }
564 430
565 DCHECK_EQ(type, REPLY_ERROR); 431 DCHECK_EQ(type, REPLY_ERROR);
566 432
567 iq->SetAttr(QName(kEmptyNamespace, "type"), "error"); 433 iq->SetAttr(QName(kEmptyNamespace, "type"), "error");
568 SetAddress(iq.get(), nullptr, original_from, false); 434 original_from.SetInMessage(iq.get(), SignalingAddress::TO);
569 435
570 for (const buzz::XmlElement* child = request_stanza->FirstElement(); 436 for (const buzz::XmlElement* child = request_stanza->FirstElement();
571 child != nullptr; child = child->NextElement()) { 437 child != nullptr; child = child->NextElement()) {
572 iq->AddElement(new buzz::XmlElement(*child)); 438 iq->AddElement(new buzz::XmlElement(*child));
573 } 439 }
574 440
575 buzz::XmlElement* error = 441 buzz::XmlElement* error =
576 new buzz::XmlElement(QName(kJabberNamespace, "error")); 442 new buzz::XmlElement(QName(kJabberNamespace, "error"));
577 iq->AddElement(error); 443 iq->AddElement(error);
578 444
(...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after
685 result->AddElement(FormatIceCredentials(credentials)); 551 result->AddElement(FormatIceCredentials(credentials));
686 } 552 }
687 for (const NamedCandidate& candidate : candidates) { 553 for (const NamedCandidate& candidate : candidates) {
688 result->AddElement(FormatIceCandidate(candidate)); 554 result->AddElement(FormatIceCandidate(candidate));
689 } 555 }
690 return result; 556 return result;
691 } 557 }
692 558
693 } // namespace protocol 559 } // namespace protocol
694 } // namespace remoting 560 } // namespace remoting
OLDNEW
« no previous file with comments | « remoting/protocol/jingle_messages.h ('k') | remoting/protocol/jingle_messages_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698