Chromium Code Reviews| OLD | NEW |
|---|---|
| 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/protocol/content_description.h" | 10 #include "remoting/protocol/content_description.h" |
| (...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 142 result->SetAttr(QName(kEmptyNamespace, "type"), candidate.candidate.type()); | 142 result->SetAttr(QName(kEmptyNamespace, "type"), candidate.candidate.type()); |
| 143 result->SetAttr(QName(kEmptyNamespace, "protocol"), | 143 result->SetAttr(QName(kEmptyNamespace, "protocol"), |
| 144 candidate.candidate.protocol()); | 144 candidate.candidate.protocol()); |
| 145 result->SetAttr(QName(kEmptyNamespace, "priority"), | 145 result->SetAttr(QName(kEmptyNamespace, "priority"), |
| 146 base::UintToString(candidate.candidate.priority())); | 146 base::UintToString(candidate.candidate.priority())); |
| 147 result->SetAttr(QName(kEmptyNamespace, "generation"), | 147 result->SetAttr(QName(kEmptyNamespace, "generation"), |
| 148 base::UintToString(candidate.candidate.generation())); | 148 base::UintToString(candidate.candidate.generation())); |
| 149 return result; | 149 return result; |
| 150 } | 150 } |
| 151 | 151 |
| 152 XmlElement* EnsureJingleTag(XmlElement* iq) { | |
| 153 XmlElement* jingle = iq->FirstNamed(QName(kJingleNamespace, "jingle")); | |
| 154 if (!jingle) { | |
| 155 jingle = new XmlElement(QName(kJingleNamespace, "jingle"), true); | |
| 156 iq->AddElement(jingle); | |
| 157 } | |
| 158 return jingle; | |
| 159 } | |
| 160 | |
| 152 // Represents the XML attrbute names for the various address fields in the | 161 // Represents the XML attrbute names for the various address fields in the |
| 153 // iq stanza. | 162 // iq stanza. |
| 154 enum class Field { JID, CHANNEL, ENDPOINT_ID }; | 163 enum class Field { JID, CHANNEL, ENDPOINT_ID }; |
| 155 | 164 |
| 156 buzz::QName GetQNameByField(Field attr, bool from) { | 165 buzz::QName GetQNameByField(Field attr, bool from) { |
| 157 std::string attribute_name; | 166 std::string attribute_name; |
| 158 switch (attr) { | 167 switch (attr) { |
| 159 case Field::JID: | 168 case Field::JID: |
| 160 attribute_name = (from) ? "from" : "to"; | 169 attribute_name = (from) ? "from" : "to"; |
| 161 break; | 170 break; |
| 162 case Field::ENDPOINT_ID: | 171 case Field::ENDPOINT_ID: |
| 163 attribute_name = (from) ? "from-endpoint-id" : "to-endpoint-id"; | 172 attribute_name = (from) ? "from-endpoint-id" : "to-endpoint-id"; |
| 164 break; | 173 break; |
| 165 case Field::CHANNEL: | 174 case Field::CHANNEL: |
| 166 attribute_name = (from) ? "from-channel" : "to-channel"; | 175 attribute_name = (from) ? "from-channel" : "to-channel"; |
| 167 break; | 176 break; |
| 168 default: | 177 default: |
| 169 NOTREACHED(); | 178 NOTREACHED(); |
| 170 } | 179 } |
| 171 return QName(kEmptyNamespace, attribute_name); | 180 return QName(kEmptyNamespace, attribute_name); |
| 172 } | 181 } |
| 173 | 182 |
| 174 SignalingAddress ParseAddress( | 183 SignalingAddress ParseAddress( |
| 175 const buzz::XmlElement* stanza, bool from, std::string* error) { | 184 const buzz::XmlElement* iq, bool from, std::string* error) { |
| 176 SignalingAddress empty_instance; | 185 SignalingAddress empty_instance; |
| 177 | 186 |
| 178 std::string jid(stanza->Attr(GetQNameByField(Field::JID, from))); | 187 std::string jid(iq->Attr(GetQNameByField(Field::JID, from))); |
| 188 | |
| 189 const XmlElement* jingle = iq->FirstNamed(QName(kJingleNamespace, "jingle")); | |
| 190 | |
| 191 if (!jingle) { | |
| 192 return SignalingAddress(jid); | |
| 193 } | |
| 194 | |
| 195 std::string type(iq->Attr(QName(std::string(), "type"))); | |
| 196 // For error IQs, flips the |from| flag as the jingle node represents the | |
| 197 // original request. | |
| 198 if (type == "error") { | |
| 199 from = !from; | |
| 200 } | |
| 201 | |
| 179 std::string endpoint_id( | 202 std::string endpoint_id( |
| 180 stanza->Attr(GetQNameByField(Field::ENDPOINT_ID, from))); | 203 jingle->Attr(GetQNameByField(Field::ENDPOINT_ID, from))); |
| 181 std::string channel_str(stanza->Attr(GetQNameByField(Field::CHANNEL, from))); | 204 std::string channel_str(jingle->Attr(GetQNameByField(Field::CHANNEL, from))); |
| 182 SignalingAddress::Channel channel; | 205 SignalingAddress::Channel channel; |
| 183 | 206 |
| 184 if (channel_str.empty()) { | 207 if (channel_str.empty()) { |
| 185 channel = SignalingAddress::Channel::XMPP; | 208 channel = SignalingAddress::Channel::XMPP; |
| 186 } else if (!NameToValue(kChannelTypes, channel_str, &channel)) { | 209 } else if (!NameToValue(kChannelTypes, channel_str, &channel)) { |
| 187 *error = "Unknown channel: " + channel_str; | 210 *error = "Unknown channel: " + channel_str; |
| 188 return empty_instance; | 211 return empty_instance; |
| 189 } | 212 } |
| 190 | 213 |
| 191 bool isLcs = (channel == SignalingAddress::Channel::LCS); | 214 bool isLcs = (channel == SignalingAddress::Channel::LCS); |
| 192 | 215 |
| 193 if (isLcs == endpoint_id.empty()) { | 216 if (isLcs == endpoint_id.empty()) { |
| 194 *error = (isLcs ? "Missing |endpoint-id| for LCS channel" | 217 *error = (isLcs ? "Missing |endpoint-id| for LCS channel" |
| 195 : "|endpoint_id| should be empty for XMPP channel"); | 218 : "|endpoint_id| should be empty for XMPP channel"); |
| 196 return empty_instance; | 219 return empty_instance; |
| 197 } | 220 } |
| 198 | 221 |
| 199 return SignalingAddress(jid, endpoint_id, channel); | 222 return SignalingAddress(jid, endpoint_id, channel); |
| 200 } | 223 } |
| 201 | 224 |
| 202 void SetAddress(buzz::XmlElement* iqElement, | 225 void SetAddress(buzz::XmlElement* iq, |
| 203 const SignalingAddress& address, | 226 const SignalingAddress& address, |
| 204 bool from) { | 227 bool from) { |
| 205 // Start from a fresh slate regardless of the previous address format. | |
| 206 iqElement->ClearAttr(GetQNameByField(Field::JID, from)); | |
| 207 iqElement->ClearAttr(GetQNameByField(Field::CHANNEL, from)); | |
| 208 iqElement->ClearAttr(GetQNameByField(Field::ENDPOINT_ID, from)); | |
| 209 | |
| 210 if (address.empty()) { | 228 if (address.empty()) { |
| 211 return; | 229 return; |
| 212 } | 230 } |
| 213 | 231 |
| 214 // Always set the JID. | 232 // Always set the JID. |
| 215 iqElement->AddAttr(GetQNameByField(Field::JID, from), address.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 XmlElement* jingle = EnsureJingleTag(iq); | |
|
Sergey Ulanov
2016/06/04 17:10:31
I suggest passing a pointer to <jingle> explicitly
kelvinp
2016/06/06 20:43:41
Done.
| |
| 244 jingle->ClearAttr(GetQNameByField(Field::CHANNEL, from)); | |
|
Sergey Ulanov
2016/06/04 17:10:31
I this necessary? SetAddress() is always called wi
kelvinp
2016/06/06 20:43:41
This is true. For the sake of future maintenance,
| |
| 245 jingle->ClearAttr(GetQNameByField(Field::ENDPOINT_ID, from)); | |
| 216 | 246 |
| 217 // Only set the channel and endpoint_id in the LCS channel. | 247 // Only set the channel and endpoint_id in the LCS channel. |
| 218 if (address.channel == SignalingAddress::Channel::LCS) { | 248 if (address.channel == SignalingAddress::Channel::LCS) { |
| 219 iqElement->AddAttr(GetQNameByField(Field::ENDPOINT_ID, from), | 249 jingle->AddAttr( |
| 220 address.endpoint_id); | 250 GetQNameByField(Field::ENDPOINT_ID, from), address.endpoint_id); |
| 221 const char* channel_str = ValueToName(kChannelTypes, address.channel); | 251 jingle->AddAttr( |
| 222 iqElement->AddAttr(GetQNameByField(Field::CHANNEL, from), channel_str); | 252 GetQNameByField(Field::CHANNEL, from), |
| 253 ValueToName(kChannelTypes, address.channel)); | |
| 223 } | 254 } |
| 224 } | 255 } |
| 225 | 256 |
| 226 } // namespace | 257 } // namespace |
| 227 | 258 |
| 228 IceTransportInfo::NamedCandidate::NamedCandidate( | 259 IceTransportInfo::NamedCandidate::NamedCandidate( |
| 229 const std::string& name, | 260 const std::string& name, |
| 230 const cricket::Candidate& candidate) | 261 const cricket::Candidate& candidate) |
| 231 : name(name), | 262 : name(name), |
| 232 candidate(candidate) { | 263 candidate(candidate) { |
| (...skipping 162 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 395 | 426 |
| 396 std::unique_ptr<buzz::XmlElement> JingleMessage::ToXml() const { | 427 std::unique_ptr<buzz::XmlElement> JingleMessage::ToXml() const { |
| 397 std::unique_ptr<XmlElement> root( | 428 std::unique_ptr<XmlElement> root( |
| 398 new XmlElement(QName("jabber:client", "iq"), true)); | 429 new XmlElement(QName("jabber:client", "iq"), true)); |
| 399 | 430 |
| 400 DCHECK(!to.empty()); | 431 DCHECK(!to.empty()); |
| 401 SetAddress(root.get(), to, false); | 432 SetAddress(root.get(), to, false); |
| 402 SetAddress(root.get(), from, true); | 433 SetAddress(root.get(), from, true); |
| 403 root->SetAttr(QName(kEmptyNamespace, "type"), "set"); | 434 root->SetAttr(QName(kEmptyNamespace, "type"), "set"); |
| 404 | 435 |
| 405 XmlElement* jingle_tag = | 436 XmlElement* jingle_tag = EnsureJingleTag(root.get()); |
| 406 new XmlElement(QName(kJingleNamespace, "jingle"), true); | |
| 407 root->AddElement(jingle_tag); | |
| 408 jingle_tag->AddAttr(QName(kEmptyNamespace, "sid"), sid); | 437 jingle_tag->AddAttr(QName(kEmptyNamespace, "sid"), sid); |
| 409 | 438 |
| 410 const char* action_attr = ValueToName(kActionTypes, action); | 439 const char* action_attr = ValueToName(kActionTypes, action); |
| 411 if (!action_attr) | 440 if (!action_attr) |
| 412 LOG(FATAL) << "Invalid action value " << action; | 441 LOG(FATAL) << "Invalid action value " << action; |
| 413 jingle_tag->AddAttr(QName(kEmptyNamespace, "action"), action_attr); | 442 jingle_tag->AddAttr(QName(kEmptyNamespace, "action"), action_attr); |
| 414 | 443 |
| 415 if (action == SESSION_INFO) { | 444 if (action == SESSION_INFO) { |
| 416 if (info.get()) | 445 if (info.get()) |
| 417 jingle_tag->AddElement(new XmlElement(*info.get())); | 446 jingle_tag->AddElement(new XmlElement(*info.get())); |
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 472 text(text_value) { | 501 text(text_value) { |
| 473 } | 502 } |
| 474 | 503 |
| 475 JingleMessageReply::~JingleMessageReply() { } | 504 JingleMessageReply::~JingleMessageReply() { } |
| 476 | 505 |
| 477 std::unique_ptr<buzz::XmlElement> JingleMessageReply::ToXml( | 506 std::unique_ptr<buzz::XmlElement> JingleMessageReply::ToXml( |
| 478 const buzz::XmlElement* request_stanza) const { | 507 const buzz::XmlElement* request_stanza) const { |
| 479 std::unique_ptr<XmlElement> iq( | 508 std::unique_ptr<XmlElement> iq( |
| 480 new XmlElement(QName(kJabberNamespace, "iq"), true)); | 509 new XmlElement(QName(kJabberNamespace, "iq"), true)); |
| 481 | 510 |
| 511 iq->SetAttr(QName(kEmptyNamespace, "id"), | |
| 512 request_stanza->Attr(QName(kEmptyNamespace, "id"))); | |
| 513 | |
| 514 std::string type_string(type == REPLY_RESULT ? "result" : "error"); | |
| 515 iq->SetAttr(QName(kEmptyNamespace, "type"), type_string); | |
| 516 | |
| 482 SignalingAddress original_from; | 517 SignalingAddress original_from; |
| 483 std::string error_message; | 518 std::string error_message; |
| 484 original_from = ParseAddress(request_stanza, true, &error_message); | 519 original_from = ParseAddress(request_stanza, true, &error_message); |
| 485 DCHECK(error_message.empty()); | 520 DCHECK(error_message.empty()); |
| 486 SetAddress(iq.get(), original_from, false); | 521 SetAddress(iq.get(), original_from, false); |
| 487 | 522 |
| 488 iq->SetAttr(QName(kEmptyNamespace, "id"), | |
| 489 request_stanza->Attr(QName(kEmptyNamespace, "id"))); | |
| 490 | |
| 491 if (type == REPLY_RESULT) { | 523 if (type == REPLY_RESULT) { |
| 492 iq->SetAttr(QName(kEmptyNamespace, "type"), "result"); | |
| 493 return iq; | 524 return iq; |
| 494 } | 525 } |
| 495 | 526 |
| 496 DCHECK_EQ(type, REPLY_ERROR); | 527 DCHECK_EQ(type, REPLY_ERROR); |
| 497 | 528 |
| 498 iq->SetAttr(QName(kEmptyNamespace, "type"), "error"); | 529 iq->SetAttr(QName(kEmptyNamespace, "type"), "error"); |
| 499 | 530 |
| 500 for (const buzz::XmlElement* child = request_stanza->FirstElement(); | 531 for (const buzz::XmlElement* child = request_stanza->FirstElement(); |
| 501 child != nullptr; child = child->NextElement()) { | 532 child != nullptr; child = child->NextElement()) { |
| 502 iq->AddElement(new buzz::XmlElement(*child)); | 533 iq->AddElement(new buzz::XmlElement(*child)); |
| (...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 601 result->AddElement(FormatIceCredentials(credentials)); | 632 result->AddElement(FormatIceCredentials(credentials)); |
| 602 } | 633 } |
| 603 for (const NamedCandidate& candidate : candidates) { | 634 for (const NamedCandidate& candidate : candidates) { |
| 604 result->AddElement(FormatIceCandidate(candidate)); | 635 result->AddElement(FormatIceCandidate(candidate)); |
| 605 } | 636 } |
| 606 return result; | 637 return result; |
| 607 } | 638 } |
| 608 | 639 |
| 609 } // namespace protocol | 640 } // namespace protocol |
| 610 } // namespace remoting | 641 } // namespace remoting |
| OLD | NEW |