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 153 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
164 case Field::CHANNEL: | 164 case Field::CHANNEL: |
165 attribute_name = (from) ? "from-channel" : "to-channel"; | 165 attribute_name = (from) ? "from-channel" : "to-channel"; |
166 break; | 166 break; |
167 default: | 167 default: |
168 NOTREACHED(); | 168 NOTREACHED(); |
169 } | 169 } |
170 return QName(kEmptyNamespace, attribute_name); | 170 return QName(kEmptyNamespace, attribute_name); |
171 } | 171 } |
172 | 172 |
173 SignalingAddress ParseAddress( | 173 SignalingAddress ParseAddress( |
174 const buzz::XmlElement* stanza, bool from, std::string* error) { | 174 const buzz::XmlElement* iq, bool from, std::string* error) { |
175 SignalingAddress empty_instance; | 175 SignalingAddress empty_instance; |
176 | 176 |
177 std::string jid(stanza->Attr(GetQNameByField(Field::JID, from))); | 177 std::string jid(iq->Attr(GetQNameByField(Field::JID, from))); |
| 178 |
| 179 const XmlElement* jingle = iq->FirstNamed(QName(kJingleNamespace, "jingle")); |
| 180 |
| 181 if (!jingle) { |
| 182 return SignalingAddress(jid); |
| 183 } |
| 184 |
| 185 std::string type(iq->Attr(QName(std::string(), "type"))); |
| 186 // For error IQs, flips the |from| flag as the jingle node represents the |
| 187 // original request. |
| 188 if (type == "error") { |
| 189 from = !from; |
| 190 } |
| 191 |
178 std::string endpoint_id( | 192 std::string endpoint_id( |
179 stanza->Attr(GetQNameByField(Field::ENDPOINT_ID, from))); | 193 jingle->Attr(GetQNameByField(Field::ENDPOINT_ID, from))); |
180 std::string channel_str(stanza->Attr(GetQNameByField(Field::CHANNEL, from))); | 194 std::string channel_str(jingle->Attr(GetQNameByField(Field::CHANNEL, from))); |
181 SignalingAddress::Channel channel; | 195 SignalingAddress::Channel channel; |
182 | 196 |
183 if (channel_str.empty()) { | 197 if (channel_str.empty()) { |
184 channel = SignalingAddress::Channel::XMPP; | 198 channel = SignalingAddress::Channel::XMPP; |
185 } else if (!NameToValue(kChannelTypes, channel_str, &channel)) { | 199 } else if (!NameToValue(kChannelTypes, channel_str, &channel)) { |
186 *error = "Unknown channel: " + channel_str; | 200 *error = "Unknown channel: " + channel_str; |
187 return empty_instance; | 201 return empty_instance; |
188 } | 202 } |
189 | 203 |
190 bool isLcs = (channel == SignalingAddress::Channel::LCS); | 204 bool isLcs = (channel == SignalingAddress::Channel::LCS); |
191 | 205 |
192 if (isLcs == endpoint_id.empty()) { | 206 if (isLcs == endpoint_id.empty()) { |
193 *error = (isLcs ? "Missing |endpoint-id| for LCS channel" | 207 *error = (isLcs ? "Missing |endpoint-id| for LCS channel" |
194 : "|endpoint_id| should be empty for XMPP channel"); | 208 : "|endpoint_id| should be empty for XMPP channel"); |
195 return empty_instance; | 209 return empty_instance; |
196 } | 210 } |
197 | 211 |
198 return SignalingAddress(jid, endpoint_id, channel); | 212 return SignalingAddress(jid, endpoint_id, channel); |
199 } | 213 } |
200 | 214 |
201 void SetAddress(buzz::XmlElement* iqElement, | 215 void SetAddress(buzz::XmlElement* iq, |
| 216 buzz::XmlElement* jingle, |
202 const SignalingAddress& address, | 217 const SignalingAddress& address, |
203 bool from) { | 218 bool from) { |
204 if (address.empty()) { | 219 if (address.empty()) { |
205 return; | 220 return; |
206 } | 221 } |
207 | 222 |
208 iqElement->AddAttr(GetQNameByField(Field::JID, from), address.jid); | 223 // Always set the JID. |
| 224 iq->SetAttr(GetQNameByField(Field::JID, from), address.jid); |
209 | 225 |
| 226 // Do not tamper the routing-info in the jingle tag for error IQ's, as |
| 227 // it corresponds to the original message. |
| 228 std::string type(iq->Attr(QName(std::string(), "type"))); |
| 229 if (type == "error") { |
| 230 return; |
| 231 } |
| 232 |
| 233 // Start from a fresh slate regardless of the previous address format. |
| 234 jingle->ClearAttr(GetQNameByField(Field::CHANNEL, from)); |
| 235 jingle->ClearAttr(GetQNameByField(Field::ENDPOINT_ID, from)); |
| 236 |
| 237 // Only set the channel and endpoint_id in the LCS channel. |
210 if (address.channel == SignalingAddress::Channel::LCS) { | 238 if (address.channel == SignalingAddress::Channel::LCS) { |
211 iqElement->AddAttr(GetQNameByField(Field::ENDPOINT_ID, from), | 239 jingle->AddAttr( |
212 address.endpoint_id); | 240 GetQNameByField(Field::ENDPOINT_ID, from), address.endpoint_id); |
213 const char* channel_str = ValueToName(kChannelTypes, address.channel); | 241 jingle->AddAttr( |
214 iqElement->AddAttr(GetQNameByField(Field::CHANNEL, from), channel_str); | 242 GetQNameByField(Field::CHANNEL, from), |
| 243 ValueToName(kChannelTypes, address.channel)); |
215 } | 244 } |
216 } | 245 } |
217 | 246 |
218 } // namespace | 247 } // namespace |
219 | 248 |
220 IceTransportInfo::NamedCandidate::NamedCandidate( | 249 IceTransportInfo::NamedCandidate::NamedCandidate( |
221 const std::string& name, | 250 const std::string& name, |
222 const cricket::Candidate& candidate) | 251 const cricket::Candidate& candidate) |
223 : name(name), | 252 : name(name), |
224 candidate(candidate) { | 253 candidate(candidate) { |
(...skipping 158 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
383 } | 412 } |
384 | 413 |
385 return true; | 414 return true; |
386 } | 415 } |
387 | 416 |
388 std::unique_ptr<buzz::XmlElement> JingleMessage::ToXml() const { | 417 std::unique_ptr<buzz::XmlElement> JingleMessage::ToXml() const { |
389 std::unique_ptr<XmlElement> root( | 418 std::unique_ptr<XmlElement> root( |
390 new XmlElement(QName("jabber:client", "iq"), true)); | 419 new XmlElement(QName("jabber:client", "iq"), true)); |
391 | 420 |
392 DCHECK(!to.empty()); | 421 DCHECK(!to.empty()); |
393 SetAddress(root.get(), to, false); | |
394 SetAddress(root.get(), from, true); | |
395 root->SetAttr(QName(kEmptyNamespace, "type"), "set"); | 422 root->SetAttr(QName(kEmptyNamespace, "type"), "set"); |
396 | 423 |
397 XmlElement* jingle_tag = | 424 XmlElement* jingle_tag = |
398 new XmlElement(QName(kJingleNamespace, "jingle"), true); | 425 new XmlElement(QName(kJingleNamespace, "jingle"), true); |
399 root->AddElement(jingle_tag); | 426 root->AddElement(jingle_tag); |
400 jingle_tag->AddAttr(QName(kEmptyNamespace, "sid"), sid); | 427 jingle_tag->AddAttr(QName(kEmptyNamespace, "sid"), sid); |
| 428 SetAddress(root.get(), jingle_tag, to, false); |
| 429 SetAddress(root.get(), jingle_tag, from, true); |
401 | 430 |
402 const char* action_attr = ValueToName(kActionTypes, action); | 431 const char* action_attr = ValueToName(kActionTypes, action); |
403 if (!action_attr) | 432 if (!action_attr) |
404 LOG(FATAL) << "Invalid action value " << action; | 433 LOG(FATAL) << "Invalid action value " << action; |
405 jingle_tag->AddAttr(QName(kEmptyNamespace, "action"), action_attr); | 434 jingle_tag->AddAttr(QName(kEmptyNamespace, "action"), action_attr); |
406 | 435 |
407 if (action == SESSION_INFO) { | 436 if (action == SESSION_INFO) { |
408 if (info.get()) | 437 if (info.get()) |
409 jingle_tag->AddElement(new XmlElement(*info.get())); | 438 jingle_tag->AddElement(new XmlElement(*info.get())); |
410 return root; | 439 return root; |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
464 text(text_value) { | 493 text(text_value) { |
465 } | 494 } |
466 | 495 |
467 JingleMessageReply::~JingleMessageReply() { } | 496 JingleMessageReply::~JingleMessageReply() { } |
468 | 497 |
469 std::unique_ptr<buzz::XmlElement> JingleMessageReply::ToXml( | 498 std::unique_ptr<buzz::XmlElement> JingleMessageReply::ToXml( |
470 const buzz::XmlElement* request_stanza) const { | 499 const buzz::XmlElement* request_stanza) const { |
471 std::unique_ptr<XmlElement> iq( | 500 std::unique_ptr<XmlElement> iq( |
472 new XmlElement(QName(kJabberNamespace, "iq"), true)); | 501 new XmlElement(QName(kJabberNamespace, "iq"), true)); |
473 | 502 |
| 503 iq->SetAttr(QName(kEmptyNamespace, "id"), |
| 504 request_stanza->Attr(QName(kEmptyNamespace, "id"))); |
| 505 |
474 SignalingAddress original_from; | 506 SignalingAddress original_from; |
475 std::string error_message; | 507 std::string error_message; |
476 original_from = ParseAddress(request_stanza, true, &error_message); | 508 original_from = ParseAddress(request_stanza, true, &error_message); |
477 DCHECK(error_message.empty()); | 509 DCHECK(error_message.empty()); |
478 SetAddress(iq.get(), original_from, false); | |
479 | |
480 iq->SetAttr(QName(kEmptyNamespace, "id"), | |
481 request_stanza->Attr(QName(kEmptyNamespace, "id"))); | |
482 | 510 |
483 if (type == REPLY_RESULT) { | 511 if (type == REPLY_RESULT) { |
484 iq->SetAttr(QName(kEmptyNamespace, "type"), "result"); | 512 iq->SetAttr(QName(kEmptyNamespace, "type"), "result"); |
| 513 XmlElement* jingle = |
| 514 new XmlElement(QName(kJingleNamespace, "jingle"), true); |
| 515 iq->AddElement(jingle); |
| 516 SetAddress(iq.get(), jingle, original_from, false); |
485 return iq; | 517 return iq; |
486 } | 518 } |
487 | 519 |
488 DCHECK_EQ(type, REPLY_ERROR); | 520 DCHECK_EQ(type, REPLY_ERROR); |
489 | 521 |
490 iq->SetAttr(QName(kEmptyNamespace, "type"), "error"); | 522 iq->SetAttr(QName(kEmptyNamespace, "type"), "error"); |
| 523 SetAddress(iq.get(), nullptr, original_from, false); |
491 | 524 |
492 for (const buzz::XmlElement* child = request_stanza->FirstElement(); | 525 for (const buzz::XmlElement* child = request_stanza->FirstElement(); |
493 child != nullptr; child = child->NextElement()) { | 526 child != nullptr; child = child->NextElement()) { |
494 iq->AddElement(new buzz::XmlElement(*child)); | 527 iq->AddElement(new buzz::XmlElement(*child)); |
495 } | 528 } |
496 | 529 |
497 buzz::XmlElement* error = | 530 buzz::XmlElement* error = |
498 new buzz::XmlElement(QName(kJabberNamespace, "error")); | 531 new buzz::XmlElement(QName(kJabberNamespace, "error")); |
499 iq->AddElement(error); | 532 iq->AddElement(error); |
500 | 533 |
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
593 result->AddElement(FormatIceCredentials(credentials)); | 626 result->AddElement(FormatIceCredentials(credentials)); |
594 } | 627 } |
595 for (const NamedCandidate& candidate : candidates) { | 628 for (const NamedCandidate& candidate : candidates) { |
596 result->AddElement(FormatIceCandidate(candidate)); | 629 result->AddElement(FormatIceCandidate(candidate)); |
597 } | 630 } |
598 return result; | 631 return result; |
599 } | 632 } |
600 | 633 |
601 } // namespace protocol | 634 } // namespace protocol |
602 } // namespace remoting | 635 } // namespace remoting |
OLD | NEW |