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