Breakup Transports and TransportParsers and move TransportParsers into webrtc/libjingle. This is part of an ongoing effort to move Jingle-specific code out of WebRTC and into its own repository.
R=juberti@webrtc.org Review URL: https://webrtc-codereview.appspot.com/33679004 git-svn-id: http://webrtc.googlecode.com/svn/trunk@7959 4adac7df-926f-26a2-2b94-8c16560cd09d
This commit is contained in:
parent
0c39e91cc8
commit
5647877b2d
@ -575,6 +575,7 @@
|
||||
'<(DEPTH)/third_party/libsrtp/libsrtp.gyp:libsrtp',
|
||||
'libjingle',
|
||||
'libjingle_media',
|
||||
'<(webrtc_root)/libjingle/libjingle.gyp:jingle_session',
|
||||
],
|
||||
'include_dirs': [
|
||||
'<(DEPTH)/testing/gtest/include',
|
||||
|
@ -30,19 +30,6 @@
|
||||
'build/common.gypi',
|
||||
],
|
||||
'targets': [
|
||||
{
|
||||
'target_name': 'libjingle_xmpphelp',
|
||||
'type': 'static_library',
|
||||
'dependencies': [
|
||||
'<(DEPTH)/third_party/expat/expat.gyp:expat',
|
||||
'libjingle.gyp:libjingle',
|
||||
'libjingle.gyp:libjingle_p2p',
|
||||
],
|
||||
'sources': [
|
||||
'<(webrtc_root)/libjingle/xmpp/jingleinfotask.cc',
|
||||
'<(webrtc_root)/libjingle/xmpp/jingleinfotask.h',
|
||||
],
|
||||
}, # target libjingle_xmpphelp
|
||||
{
|
||||
'target_name': 'relayserver',
|
||||
'type': 'executable',
|
||||
|
@ -37,14 +37,14 @@
|
||||
#include "talk/media/base/screencastid.h"
|
||||
#include "talk/media/base/streamparams.h"
|
||||
#include "talk/media/base/videocommon.h"
|
||||
#include "webrtc/p2p/base/sessionmanager.h"
|
||||
#include "webrtc/p2p/client/socketmonitor.h"
|
||||
#include "talk/session/media/audiomonitor.h"
|
||||
#include "talk/session/media/currentspeakermonitor.h"
|
||||
#include "talk/session/media/mediamessages.h"
|
||||
#include "talk/session/media/mediasession.h"
|
||||
#include "webrtc/libjingle/xmpp/jid.h"
|
||||
#include "webrtc/base/messagequeue.h"
|
||||
#include "webrtc/libjingle/session/sessionmanager.h"
|
||||
#include "webrtc/libjingle/xmpp/jid.h"
|
||||
#include "webrtc/p2p/client/socketmonitor.h"
|
||||
|
||||
namespace cricket {
|
||||
|
||||
|
@ -33,10 +33,6 @@
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include "talk/media/base/cryptoparams.h"
|
||||
#include "webrtc/p2p/base/session.h"
|
||||
#include "webrtc/p2p/base/sessionclient.h"
|
||||
#include "webrtc/p2p/base/sessiondescription.h"
|
||||
#include "webrtc/p2p/base/sessionmanager.h"
|
||||
#include "talk/session/media/call.h"
|
||||
#include "talk/session/media/channelmanager.h"
|
||||
#include "talk/session/media/mediasession.h"
|
||||
@ -44,6 +40,10 @@
|
||||
#include "webrtc/base/sigslot.h"
|
||||
#include "webrtc/base/sigslotrepeater.h"
|
||||
#include "webrtc/base/thread.h"
|
||||
#include "webrtc/libjingle/session/sessionmanager.h"
|
||||
#include "webrtc/p2p/base/session.h"
|
||||
#include "webrtc/p2p/base/sessionclient.h"
|
||||
#include "webrtc/p2p/base/sessiondescription.h"
|
||||
|
||||
namespace cricket {
|
||||
|
||||
|
@ -40,6 +40,14 @@
|
||||
'<(DEPTH)/third_party/expat/expat.gyp:expat',
|
||||
],
|
||||
'sources': [
|
||||
'session/p2ptransportparser.cc',
|
||||
'session/p2ptransportparser.h',
|
||||
'session/rawtransportparser.cc',
|
||||
'session/rawtransportparser.h',
|
||||
'session/sessionmanager.cc',
|
||||
'session/sessionmanager.h',
|
||||
'session/transportparser.cc',
|
||||
'session/transportparser.h',
|
||||
'session/tunnel/pseudotcpchannel.cc',
|
||||
'session/tunnel/pseudotcpchannel.h',
|
||||
'session/tunnel/tunnelsessionclient.cc',
|
||||
@ -64,6 +72,18 @@
|
||||
}],
|
||||
],
|
||||
},
|
||||
{
|
||||
'target_name': 'jingle_session_unittest',
|
||||
'type': 'executable',
|
||||
'dependencies': [
|
||||
'jingle_session',
|
||||
'<(webrtc_root)/base/base_tests.gyp:rtc_base_tests_utils',
|
||||
],
|
||||
'sources': [
|
||||
'session/session_unittest.cc',
|
||||
'session/transportparser_unittest.cc',
|
||||
],
|
||||
}, # target jingle_session_unittest
|
||||
{
|
||||
'target_name': 'login',
|
||||
'type': 'executable',
|
||||
|
215
webrtc/libjingle/session/p2ptransportparser.cc
Normal file
215
webrtc/libjingle/session/p2ptransportparser.cc
Normal file
@ -0,0 +1,215 @@
|
||||
/*
|
||||
* Copyright 2004 The WebRTC Project Authors. All rights reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
#include "webrtc/libjingle/session/p2ptransportparser.h"
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include "webrtc/p2p/base/constants.h"
|
||||
#include "webrtc/p2p/base/parsing.h"
|
||||
#include "webrtc/libjingle/session/sessionmanager.h"
|
||||
#include "webrtc/p2p/base/sessionmessages.h"
|
||||
#include "webrtc/libjingle/xmllite/qname.h"
|
||||
#include "webrtc/libjingle/xmllite/xmlelement.h"
|
||||
#include "webrtc/libjingle/xmpp/constants.h"
|
||||
#include "webrtc/base/base64.h"
|
||||
#include "webrtc/base/common.h"
|
||||
#include "webrtc/base/stringencode.h"
|
||||
#include "webrtc/base/stringutils.h"
|
||||
|
||||
namespace cricket {
|
||||
|
||||
static buzz::XmlElement* NewTransportElement(const std::string& name) {
|
||||
return new buzz::XmlElement(buzz::QName(name, LN_TRANSPORT), true);
|
||||
}
|
||||
|
||||
bool P2PTransportParser::ParseTransportDescription(
|
||||
const buzz::XmlElement* elem,
|
||||
const CandidateTranslator* translator,
|
||||
TransportDescription* desc,
|
||||
ParseError* error) {
|
||||
ASSERT(elem->Name().LocalPart() == LN_TRANSPORT);
|
||||
desc->transport_type = elem->Name().Namespace();
|
||||
if (desc->transport_type != NS_GINGLE_P2P)
|
||||
return BadParse("Unsupported transport type", error);
|
||||
|
||||
for (const buzz::XmlElement* candidate_elem = elem->FirstElement();
|
||||
candidate_elem != NULL;
|
||||
candidate_elem = candidate_elem->NextElement()) {
|
||||
// Only look at local part because the namespace might (eventually)
|
||||
// be NS_GINGLE_P2P or NS_JINGLE_ICE_UDP.
|
||||
if (candidate_elem->Name().LocalPart() == LN_CANDIDATE) {
|
||||
Candidate candidate;
|
||||
if (!ParseCandidate(ICEPROTO_GOOGLE, candidate_elem, translator,
|
||||
&candidate, error)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
desc->candidates.push_back(candidate);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool P2PTransportParser::WriteTransportDescription(
|
||||
const TransportDescription& desc,
|
||||
const CandidateTranslator* translator,
|
||||
buzz::XmlElement** out_elem,
|
||||
WriteError* error) {
|
||||
TransportProtocol proto = TransportProtocolFromDescription(&desc);
|
||||
rtc::scoped_ptr<buzz::XmlElement> trans_elem(
|
||||
NewTransportElement(desc.transport_type));
|
||||
|
||||
// Fail if we get HYBRID or ICE right now.
|
||||
// TODO(juberti): Add ICE and HYBRID serialization.
|
||||
if (proto != ICEPROTO_GOOGLE) {
|
||||
LOG(LS_ERROR) << "Failed to serialize non-GICE TransportDescription";
|
||||
return false;
|
||||
}
|
||||
|
||||
for (std::vector<Candidate>::const_iterator iter = desc.candidates.begin();
|
||||
iter != desc.candidates.end(); ++iter) {
|
||||
rtc::scoped_ptr<buzz::XmlElement> cand_elem(
|
||||
new buzz::XmlElement(QN_GINGLE_P2P_CANDIDATE));
|
||||
if (!WriteCandidate(proto, *iter, translator, cand_elem.get(), error)) {
|
||||
return false;
|
||||
}
|
||||
trans_elem->AddElement(cand_elem.release());
|
||||
}
|
||||
|
||||
*out_elem = trans_elem.release();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool P2PTransportParser::ParseGingleCandidate(
|
||||
const buzz::XmlElement* elem,
|
||||
const CandidateTranslator* translator,
|
||||
Candidate* candidate,
|
||||
ParseError* error) {
|
||||
return ParseCandidate(ICEPROTO_GOOGLE, elem, translator, candidate, error);
|
||||
}
|
||||
|
||||
bool P2PTransportParser::WriteGingleCandidate(
|
||||
const Candidate& candidate,
|
||||
const CandidateTranslator* translator,
|
||||
buzz::XmlElement** out_elem,
|
||||
WriteError* error) {
|
||||
rtc::scoped_ptr<buzz::XmlElement> elem(
|
||||
new buzz::XmlElement(QN_GINGLE_CANDIDATE));
|
||||
bool ret = WriteCandidate(ICEPROTO_GOOGLE, candidate, translator, elem.get(),
|
||||
error);
|
||||
if (ret) {
|
||||
*out_elem = elem.release();
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool P2PTransportParser::VerifyUsernameFormat(TransportProtocol proto,
|
||||
const std::string& username,
|
||||
ParseError* error) {
|
||||
if (proto == ICEPROTO_GOOGLE || proto == ICEPROTO_HYBRID) {
|
||||
if (username.size() > GICE_UFRAG_MAX_LENGTH)
|
||||
return BadParse("candidate username is too long", error);
|
||||
if (!rtc::Base64::IsBase64Encoded(username))
|
||||
return BadParse("candidate username has non-base64 encoded characters",
|
||||
error);
|
||||
} else if (proto == ICEPROTO_RFC5245) {
|
||||
if (username.size() > ICE_UFRAG_MAX_LENGTH)
|
||||
return BadParse("candidate username is too long", error);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool P2PTransportParser::ParseCandidate(TransportProtocol proto,
|
||||
const buzz::XmlElement* elem,
|
||||
const CandidateTranslator* translator,
|
||||
Candidate* candidate,
|
||||
ParseError* error) {
|
||||
ASSERT(proto == ICEPROTO_GOOGLE);
|
||||
ASSERT(translator != NULL);
|
||||
|
||||
if (!elem->HasAttr(buzz::QN_NAME) ||
|
||||
!elem->HasAttr(QN_ADDRESS) ||
|
||||
!elem->HasAttr(QN_PORT) ||
|
||||
!elem->HasAttr(QN_USERNAME) ||
|
||||
!elem->HasAttr(QN_PROTOCOL) ||
|
||||
!elem->HasAttr(QN_GENERATION)) {
|
||||
return BadParse("candidate missing required attribute", error);
|
||||
}
|
||||
|
||||
rtc::SocketAddress address;
|
||||
if (!ParseAddress(elem, QN_ADDRESS, QN_PORT, &address, error))
|
||||
return false;
|
||||
|
||||
std::string channel_name = elem->Attr(buzz::QN_NAME);
|
||||
int component = 0;
|
||||
if (!translator ||
|
||||
!translator->GetComponentFromChannelName(channel_name, &component)) {
|
||||
return BadParse("candidate has unknown channel name " + channel_name,
|
||||
error);
|
||||
}
|
||||
|
||||
float preference = 0.0;
|
||||
if (!GetXmlAttr(elem, QN_PREFERENCE, 0.0f, &preference)) {
|
||||
return BadParse("candidate has unknown preference", error);
|
||||
}
|
||||
|
||||
candidate->set_component(component);
|
||||
candidate->set_address(address);
|
||||
candidate->set_username(elem->Attr(QN_USERNAME));
|
||||
candidate->set_preference(preference);
|
||||
candidate->set_protocol(elem->Attr(QN_PROTOCOL));
|
||||
candidate->set_generation_str(elem->Attr(QN_GENERATION));
|
||||
if (elem->HasAttr(QN_PASSWORD))
|
||||
candidate->set_password(elem->Attr(QN_PASSWORD));
|
||||
if (elem->HasAttr(buzz::QN_TYPE))
|
||||
candidate->set_type(elem->Attr(buzz::QN_TYPE));
|
||||
if (elem->HasAttr(QN_NETWORK))
|
||||
candidate->set_network_name(elem->Attr(QN_NETWORK));
|
||||
|
||||
if (!VerifyUsernameFormat(proto, candidate->username(), error))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool P2PTransportParser::WriteCandidate(TransportProtocol proto,
|
||||
const Candidate& candidate,
|
||||
const CandidateTranslator* translator,
|
||||
buzz::XmlElement* elem,
|
||||
WriteError* error) {
|
||||
ASSERT(proto == ICEPROTO_GOOGLE);
|
||||
ASSERT(translator != NULL);
|
||||
|
||||
std::string channel_name;
|
||||
if (!translator ||
|
||||
!translator->GetChannelNameFromComponent(
|
||||
candidate.component(), &channel_name)) {
|
||||
return BadWrite("Cannot write candidate because of unknown component.",
|
||||
error);
|
||||
}
|
||||
|
||||
elem->SetAttr(buzz::QN_NAME, channel_name);
|
||||
elem->SetAttr(QN_ADDRESS, candidate.address().ipaddr().ToString());
|
||||
elem->SetAttr(QN_PORT, candidate.address().PortAsString());
|
||||
AddXmlAttr(elem, QN_PREFERENCE, candidate.preference());
|
||||
elem->SetAttr(QN_USERNAME, candidate.username());
|
||||
elem->SetAttr(QN_PROTOCOL, candidate.protocol());
|
||||
elem->SetAttr(QN_GENERATION, candidate.generation_str());
|
||||
if (!candidate.password().empty())
|
||||
elem->SetAttr(QN_PASSWORD, candidate.password());
|
||||
elem->SetAttr(buzz::QN_TYPE, candidate.type());
|
||||
if (!candidate.network_name().empty())
|
||||
elem->SetAttr(QN_NETWORK, candidate.network_name());
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace cricket
|
67
webrtc/libjingle/session/p2ptransportparser.h
Normal file
67
webrtc/libjingle/session/p2ptransportparser.h
Normal file
@ -0,0 +1,67 @@
|
||||
/*
|
||||
* Copyright 2004 The WebRTC Project Authors. All rights reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
#ifndef WEBRTC_P2P_BASE_P2PTRANSPORTPARSER_H_
|
||||
#define WEBRTC_P2P_BASE_P2PTRANSPORTPARSER_H_
|
||||
|
||||
#include <string>
|
||||
#include "webrtc/libjingle/session/transportparser.h"
|
||||
|
||||
namespace cricket {
|
||||
|
||||
class P2PTransportParser : public TransportParser {
|
||||
public:
|
||||
P2PTransportParser() {}
|
||||
// Translator may be null, in which case ParseCandidates should
|
||||
// return false if there are candidates to parse. We can't not call
|
||||
// ParseCandidates because there's no way to know ahead of time if
|
||||
// there are candidates or not.
|
||||
|
||||
// Jingle-specific functions; can be used with either ICE, GICE, or HYBRID.
|
||||
virtual bool ParseTransportDescription(const buzz::XmlElement* elem,
|
||||
const CandidateTranslator* translator,
|
||||
TransportDescription* desc,
|
||||
ParseError* error);
|
||||
virtual bool WriteTransportDescription(const TransportDescription& desc,
|
||||
const CandidateTranslator* translator,
|
||||
buzz::XmlElement** elem,
|
||||
WriteError* error);
|
||||
|
||||
// Legacy Gingle functions; only can be used with GICE.
|
||||
virtual bool ParseGingleCandidate(const buzz::XmlElement* elem,
|
||||
const CandidateTranslator* translator,
|
||||
Candidate* candidate,
|
||||
ParseError* error);
|
||||
virtual bool WriteGingleCandidate(const Candidate& candidate,
|
||||
const CandidateTranslator* translator,
|
||||
buzz::XmlElement** elem,
|
||||
WriteError* error);
|
||||
|
||||
private:
|
||||
bool ParseCandidate(TransportProtocol proto,
|
||||
const buzz::XmlElement* elem,
|
||||
const CandidateTranslator* translator,
|
||||
Candidate* candidate,
|
||||
ParseError* error);
|
||||
bool WriteCandidate(TransportProtocol proto,
|
||||
const Candidate& candidate,
|
||||
const CandidateTranslator* translator,
|
||||
buzz::XmlElement* elem,
|
||||
WriteError* error);
|
||||
bool VerifyUsernameFormat(TransportProtocol proto,
|
||||
const std::string& username,
|
||||
ParseError* error);
|
||||
|
||||
DISALLOW_EVIL_CONSTRUCTORS(P2PTransportParser);
|
||||
};
|
||||
|
||||
} // namespace cricket
|
||||
|
||||
#endif // WEBRTC_P2P_BASE_P2PTRANSPORTPARSER_H_
|
92
webrtc/libjingle/session/rawtransportparser.cc
Normal file
92
webrtc/libjingle/session/rawtransportparser.cc
Normal file
@ -0,0 +1,92 @@
|
||||
/*
|
||||
* Copyright 2004 The WebRTC Project Authors. All rights reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
#include "webrtc/libjingle/session/rawtransportparser.h"
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "webrtc/p2p/base/parsing.h"
|
||||
#include "webrtc/libjingle/xmllite/qname.h"
|
||||
#include "webrtc/libjingle/xmllite/xmlelement.h"
|
||||
#include "webrtc/libjingle/xmpp/constants.h"
|
||||
#include "webrtc/p2p/base/constants.h"
|
||||
|
||||
#if defined(FEATURE_ENABLE_PSTN)
|
||||
namespace cricket {
|
||||
|
||||
bool RawTransportParser::ParseCandidates(SignalingProtocol protocol,
|
||||
const buzz::XmlElement* elem,
|
||||
const CandidateTranslator* translator,
|
||||
Candidates* candidates,
|
||||
ParseError* error) {
|
||||
for (const buzz::XmlElement* cand_elem = elem->FirstElement();
|
||||
cand_elem != NULL;
|
||||
cand_elem = cand_elem->NextElement()) {
|
||||
if (cand_elem->Name() == QN_GINGLE_RAW_CHANNEL) {
|
||||
if (!cand_elem->HasAttr(buzz::QN_NAME)) {
|
||||
return BadParse("no channel name given", error);
|
||||
}
|
||||
if (NS_GINGLE_RAW != cand_elem->Attr(buzz::QN_NAME)) {
|
||||
return BadParse("channel named does not exist", error);
|
||||
}
|
||||
rtc::SocketAddress addr;
|
||||
if (!ParseRawAddress(cand_elem, &addr, error))
|
||||
return false;
|
||||
|
||||
Candidate candidate;
|
||||
candidate.set_component(1);
|
||||
candidate.set_address(addr);
|
||||
candidates->push_back(candidate);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool RawTransportParser::WriteCandidates(SignalingProtocol protocol,
|
||||
const Candidates& candidates,
|
||||
const CandidateTranslator* translator,
|
||||
XmlElements* candidate_elems,
|
||||
WriteError* error) {
|
||||
for (std::vector<Candidate>::const_iterator
|
||||
cand = candidates.begin();
|
||||
cand != candidates.end();
|
||||
++cand) {
|
||||
ASSERT(cand->component() == 1);
|
||||
ASSERT(cand->protocol() == "udp");
|
||||
rtc::SocketAddress addr = cand->address();
|
||||
|
||||
buzz::XmlElement* elem = new buzz::XmlElement(QN_GINGLE_RAW_CHANNEL);
|
||||
elem->SetAttr(buzz::QN_NAME, NS_GINGLE_RAW);
|
||||
elem->SetAttr(QN_ADDRESS, addr.ipaddr().ToString());
|
||||
elem->SetAttr(QN_PORT, addr.PortAsString());
|
||||
candidate_elems->push_back(elem);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool RawTransportParser::ParseRawAddress(const buzz::XmlElement* elem,
|
||||
rtc::SocketAddress* addr,
|
||||
ParseError* error) {
|
||||
// Make sure the required attributes exist
|
||||
if (!elem->HasAttr(QN_ADDRESS) ||
|
||||
!elem->HasAttr(QN_PORT)) {
|
||||
return BadParse("channel missing required attribute", error);
|
||||
}
|
||||
|
||||
// Parse the address.
|
||||
if (!ParseAddress(elem, QN_ADDRESS, QN_PORT, addr, error))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace cricket
|
||||
#endif // defined(FEATURE_ENABLE_PSTN)
|
48
webrtc/libjingle/session/rawtransportparser.h
Normal file
48
webrtc/libjingle/session/rawtransportparser.h
Normal file
@ -0,0 +1,48 @@
|
||||
/*
|
||||
* Copyright 2004 The WebRTC Project Authors. All rights reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
#ifndef WEBRTC_P2P_BASE_RAWTRANSPORTPARSER_H_
|
||||
#define WEBRTC_P2P_BASE_RAWTRANSPORTPARSER_H_
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "webrtc/p2p/base/constants.h"
|
||||
#include "webrtc/libjingle/session/transportparser.h"
|
||||
|
||||
namespace cricket {
|
||||
|
||||
class RawTransportParser : public TransportParser {
|
||||
public:
|
||||
RawTransportParser() {}
|
||||
|
||||
virtual bool ParseCandidates(SignalingProtocol protocol,
|
||||
const buzz::XmlElement* elem,
|
||||
const CandidateTranslator* translator,
|
||||
Candidates* candidates,
|
||||
ParseError* error);
|
||||
virtual bool WriteCandidates(SignalingProtocol protocol,
|
||||
const Candidates& candidates,
|
||||
const CandidateTranslator* translator,
|
||||
XmlElements* candidate_elems,
|
||||
WriteError* error);
|
||||
private:
|
||||
// Parses the given element, which should describe the address to use for a
|
||||
// given channel. This will return false and signal an error if the address
|
||||
// or channel name is bad.
|
||||
bool ParseRawAddress(const buzz::XmlElement* elem,
|
||||
rtc::SocketAddress* addr,
|
||||
ParseError* error);
|
||||
|
||||
DISALLOW_EVIL_CONSTRUCTORS(RawTransportParser);
|
||||
};
|
||||
|
||||
} // namespace cricket
|
||||
|
||||
#endif // WEBRTC_P2P_BASE_RAWTRANSPORTPARSER_H_
|
@ -22,6 +22,8 @@
|
||||
#include "webrtc/base/natserver.h"
|
||||
#include "webrtc/base/natsocketfactory.h"
|
||||
#include "webrtc/base/stringencode.h"
|
||||
#include "webrtc/libjingle/session/sessionmanager.h"
|
||||
#include "webrtc/libjingle/xmpp/constants.h"
|
||||
#include "webrtc/p2p/base/basicpacketsocketfactory.h"
|
||||
#include "webrtc/p2p/base/constants.h"
|
||||
#include "webrtc/p2p/base/p2ptransport.h"
|
||||
@ -30,13 +32,11 @@
|
||||
#include "webrtc/p2p/base/relayport.h"
|
||||
#include "webrtc/p2p/base/relayserver.h"
|
||||
#include "webrtc/p2p/base/sessionclient.h"
|
||||
#include "webrtc/p2p/base/sessionmanager.h"
|
||||
#include "webrtc/p2p/base/stunport.h"
|
||||
#include "webrtc/p2p/base/stunserver.h"
|
||||
#include "webrtc/p2p/base/transportchannel.h"
|
||||
#include "webrtc/p2p/base/transportchannelproxy.h"
|
||||
#include "webrtc/p2p/base/udpport.h"
|
||||
#include "webrtc/libjingle/xmpp/constants.h"
|
||||
|
||||
using cricket::SignalingProtocol;
|
||||
using cricket::PROTOCOL_HYBRID;
|
1150
webrtc/libjingle/session/sessionmanager.cc
Normal file
1150
webrtc/libjingle/session/sessionmanager.cc
Normal file
File diff suppressed because it is too large
Load Diff
436
webrtc/libjingle/session/sessionmanager.h
Normal file
436
webrtc/libjingle/session/sessionmanager.h
Normal file
@ -0,0 +1,436 @@
|
||||
/*
|
||||
* Copyright 2004 The WebRTC Project Authors. All rights reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
#ifndef WEBRTC_P2P_BASE_SESSIONMANAGER_H_
|
||||
#define WEBRTC_P2P_BASE_SESSIONMANAGER_H_
|
||||
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#include "webrtc/libjingle/xmllite/xmlelement.h"
|
||||
#include "webrtc/libjingle/xmpp/constants.h"
|
||||
#include "webrtc/p2p/base/parsing.h"
|
||||
#include "webrtc/p2p/base/portallocator.h"
|
||||
#include "webrtc/p2p/base/session.h"
|
||||
#include "webrtc/p2p/base/sessionclient.h"
|
||||
#include "webrtc/p2p/base/sessionmessages.h"
|
||||
#include "webrtc/p2p/base/transportdescriptionfactory.h"
|
||||
#include "webrtc/base/sigslot.h"
|
||||
#include "webrtc/base/thread.h"
|
||||
|
||||
namespace buzz {
|
||||
class QName;
|
||||
class XmlElement;
|
||||
}
|
||||
|
||||
namespace cricket {
|
||||
|
||||
class BaseSession;
|
||||
class SessionClient;
|
||||
class SessionManager;
|
||||
|
||||
// Used for errors that will send back a specific error message to the
|
||||
// remote peer. We add "type" to the errors because it's needed for
|
||||
// SignalErrorMessage.
|
||||
struct MessageError : ParseError {
|
||||
buzz::QName type;
|
||||
|
||||
// if unset, assume type is a parse error
|
||||
MessageError() : ParseError(), type(buzz::QN_STANZA_BAD_REQUEST) {}
|
||||
|
||||
void SetType(const buzz::QName type) {
|
||||
this->type = type;
|
||||
}
|
||||
};
|
||||
|
||||
// Used for errors that may be returned by public session methods that
|
||||
// can fail.
|
||||
// TODO: Use this error in Session::Initiate and
|
||||
// Session::Accept.
|
||||
struct SessionError : WriteError {
|
||||
};
|
||||
|
||||
// A specific Session created by the SessionManager, using XMPP for protocol.
|
||||
class Session : public BaseSession {
|
||||
public:
|
||||
// Returns the manager that created and owns this session.
|
||||
SessionManager* session_manager() const { return session_manager_; }
|
||||
|
||||
// Returns the client that is handling the application data of this session.
|
||||
SessionClient* client() const { return client_; }
|
||||
|
||||
// Returns the JID of this client.
|
||||
const std::string& local_name() const { return local_name_; }
|
||||
|
||||
// Returns the JID of the other peer in this session.
|
||||
const std::string& remote_name() const { return remote_name_; }
|
||||
|
||||
// Set the JID of the other peer in this session.
|
||||
// Typically the remote_name_ is set when the session is initiated.
|
||||
// However, sometimes (e.g when a proxy is used) the peer name is
|
||||
// known after the BaseSession has been initiated and it must be updated
|
||||
// explicitly.
|
||||
void set_remote_name(const std::string& name) { remote_name_ = name; }
|
||||
|
||||
// Set the JID of the initiator of this session. Allows for the overriding
|
||||
// of the initiator to be a third-party, eg. the MUC JID when creating p2p
|
||||
// sessions.
|
||||
void set_initiator_name(const std::string& name) { initiator_name_ = name; }
|
||||
|
||||
// Indicates the JID of the entity who initiated this session.
|
||||
// In special cases, may be different than both local_name and remote_name.
|
||||
const std::string& initiator_name() const { return initiator_name_; }
|
||||
|
||||
SignalingProtocol current_protocol() const { return current_protocol_; }
|
||||
|
||||
void set_current_protocol(SignalingProtocol protocol) {
|
||||
current_protocol_ = protocol;
|
||||
}
|
||||
|
||||
// Updates the error state, signaling if necessary.
|
||||
virtual void SetError(Error error, const std::string& error_desc);
|
||||
|
||||
// When the session needs to send signaling messages, it beings by requesting
|
||||
// signaling. The client should handle this by calling OnSignalingReady once
|
||||
// it is ready to send the messages.
|
||||
// (These are called only by SessionManager.)
|
||||
sigslot::signal1<Session*> SignalRequestSignaling;
|
||||
void OnSignalingReady() { BaseSession::OnSignalingReady(); }
|
||||
|
||||
// Takes ownership of session description.
|
||||
// TODO: Add an error argument to pass back to the caller.
|
||||
bool Initiate(const std::string& to,
|
||||
const SessionDescription* sdesc);
|
||||
|
||||
// When we receive an initiate, we create a session in the
|
||||
// RECEIVEDINITIATE state and respond by accepting or rejecting.
|
||||
// Takes ownership of session description.
|
||||
// TODO: Add an error argument to pass back to the caller.
|
||||
bool Accept(const SessionDescription* sdesc);
|
||||
bool Reject(const std::string& reason);
|
||||
bool Terminate() {
|
||||
return TerminateWithReason(STR_TERMINATE_SUCCESS);
|
||||
}
|
||||
bool TerminateWithReason(const std::string& reason);
|
||||
// Fired whenever we receive a terminate message along with a reason
|
||||
sigslot::signal2<Session*, const std::string&> SignalReceivedTerminateReason;
|
||||
|
||||
// The two clients in the session may also send one another
|
||||
// arbitrary XML messages, which are called "info" messages. Sending
|
||||
// takes ownership of the given elements. The signal does not; the
|
||||
// parent element will be deleted after the signal.
|
||||
bool SendInfoMessage(const XmlElements& elems,
|
||||
const std::string& remote_name);
|
||||
bool SendDescriptionInfoMessage(const ContentInfos& contents);
|
||||
sigslot::signal2<Session*, const buzz::XmlElement*> SignalInfoMessage;
|
||||
|
||||
private:
|
||||
// Creates or destroys a session. (These are called only SessionManager.)
|
||||
Session(SessionManager *session_manager,
|
||||
const std::string& local_name, const std::string& initiator_name,
|
||||
const std::string& sid, const std::string& content_type,
|
||||
SessionClient* client);
|
||||
~Session();
|
||||
// For each transport info, create a transport proxy. Can fail for
|
||||
// incompatible transport types.
|
||||
bool CreateTransportProxies(const TransportInfos& tinfos,
|
||||
SessionError* error);
|
||||
bool OnRemoteCandidates(const TransportInfos& tinfos,
|
||||
ParseError* error);
|
||||
// Returns a TransportInfo without candidates for each content name.
|
||||
// Uses the transport_type_ of the session.
|
||||
TransportInfos GetEmptyTransportInfos(const ContentInfos& contents) const;
|
||||
|
||||
// Maps passed to serialization functions.
|
||||
TransportParserMap GetTransportParsers();
|
||||
ContentParserMap GetContentParsers();
|
||||
CandidateTranslatorMap GetCandidateTranslators();
|
||||
|
||||
virtual void OnTransportRequestSignaling(Transport* transport);
|
||||
virtual void OnTransportConnecting(Transport* transport);
|
||||
virtual void OnTransportWritable(Transport* transport);
|
||||
virtual void OnTransportProxyCandidatesReady(TransportProxy* proxy,
|
||||
const Candidates& candidates);
|
||||
virtual void OnMessage(rtc::Message *pmsg);
|
||||
|
||||
// Send various kinds of session messages.
|
||||
bool SendInitiateMessage(const SessionDescription* sdesc,
|
||||
SessionError* error);
|
||||
bool SendAcceptMessage(const SessionDescription* sdesc, SessionError* error);
|
||||
bool SendRejectMessage(const std::string& reason, SessionError* error);
|
||||
bool SendTerminateMessage(const std::string& reason, SessionError* error);
|
||||
bool SendTransportInfoMessage(const TransportInfo& tinfo,
|
||||
SessionError* error);
|
||||
bool SendTransportInfoMessage(const TransportProxy* transproxy,
|
||||
const Candidates& candidates,
|
||||
SessionError* error);
|
||||
|
||||
bool ResendAllTransportInfoMessages(SessionError* error);
|
||||
bool SendAllUnsentTransportInfoMessages(SessionError* error);
|
||||
|
||||
// All versions of SendMessage send a message of the given type to
|
||||
// the other client. Can pass either a set of elements or an
|
||||
// "action", which must have a WriteSessionAction method to go along
|
||||
// with it. Sending with an action supports sending a "hybrid"
|
||||
// message. Sending with elements must be sent as Jingle or Gingle.
|
||||
|
||||
// When passing elems, must be either Jingle or Gingle protocol.
|
||||
// Takes ownership of action_elems.
|
||||
bool SendMessage(ActionType type, const XmlElements& action_elems,
|
||||
SessionError* error);
|
||||
// Sends a messge, but overrides the remote name.
|
||||
bool SendMessage(ActionType type, const XmlElements& action_elems,
|
||||
const std::string& remote_name,
|
||||
SessionError* error);
|
||||
// When passing an action, may be Hybrid protocol.
|
||||
template <typename Action>
|
||||
bool SendMessage(ActionType type, const Action& action,
|
||||
SessionError* error);
|
||||
|
||||
// Helper methods to write the session message stanza.
|
||||
template <typename Action>
|
||||
bool WriteActionMessage(ActionType type, const Action& action,
|
||||
buzz::XmlElement* stanza, WriteError* error);
|
||||
template <typename Action>
|
||||
bool WriteActionMessage(SignalingProtocol protocol,
|
||||
ActionType type, const Action& action,
|
||||
buzz::XmlElement* stanza, WriteError* error);
|
||||
|
||||
// Sending messages in hybrid form requires being able to write them
|
||||
// on a per-protocol basis with a common method signature, which all
|
||||
// of these have.
|
||||
bool WriteSessionAction(SignalingProtocol protocol,
|
||||
const SessionInitiate& init,
|
||||
XmlElements* elems, WriteError* error);
|
||||
bool WriteSessionAction(SignalingProtocol protocol,
|
||||
const TransportInfo& tinfo,
|
||||
XmlElements* elems, WriteError* error);
|
||||
bool WriteSessionAction(SignalingProtocol protocol,
|
||||
const SessionTerminate& term,
|
||||
XmlElements* elems, WriteError* error);
|
||||
|
||||
// Sends a message back to the other client indicating that we have received
|
||||
// and accepted their message.
|
||||
void SendAcknowledgementMessage(const buzz::XmlElement* stanza);
|
||||
|
||||
// Once signaling is ready, the session will use this signal to request the
|
||||
// sending of each message. When messages are received by the other client,
|
||||
// they should be handed to OnIncomingMessage.
|
||||
// (These are called only by SessionManager.)
|
||||
sigslot::signal2<Session* , const buzz::XmlElement*> SignalOutgoingMessage;
|
||||
void OnIncomingMessage(const SessionMessage& msg);
|
||||
|
||||
void OnIncomingResponse(const buzz::XmlElement* orig_stanza,
|
||||
const buzz::XmlElement* response_stanza,
|
||||
const SessionMessage& msg);
|
||||
void OnInitiateAcked();
|
||||
void OnFailedSend(const buzz::XmlElement* orig_stanza,
|
||||
const buzz::XmlElement* error_stanza);
|
||||
|
||||
// Invoked when an error is found in an incoming message. This is translated
|
||||
// into the appropriate XMPP response by SessionManager.
|
||||
sigslot::signal6<BaseSession*,
|
||||
const buzz::XmlElement*,
|
||||
const buzz::QName&,
|
||||
const std::string&,
|
||||
const std::string&,
|
||||
const buzz::XmlElement*> SignalErrorMessage;
|
||||
|
||||
// Handlers for the various types of messages. These functions may take
|
||||
// pointers to the whole stanza or to just the session element.
|
||||
bool OnInitiateMessage(const SessionMessage& msg, MessageError* error);
|
||||
bool OnAcceptMessage(const SessionMessage& msg, MessageError* error);
|
||||
bool OnRejectMessage(const SessionMessage& msg, MessageError* error);
|
||||
bool OnInfoMessage(const SessionMessage& msg);
|
||||
bool OnTerminateMessage(const SessionMessage& msg, MessageError* error);
|
||||
bool OnTransportInfoMessage(const SessionMessage& msg, MessageError* error);
|
||||
bool OnTransportAcceptMessage(const SessionMessage& msg, MessageError* error);
|
||||
bool OnDescriptionInfoMessage(const SessionMessage& msg, MessageError* error);
|
||||
bool OnRedirectError(const SessionRedirect& redirect, SessionError* error);
|
||||
|
||||
// Verifies that we are in the appropriate state to receive this message.
|
||||
bool CheckState(State state, MessageError* error);
|
||||
|
||||
SessionManager* session_manager_;
|
||||
bool initiate_acked_;
|
||||
std::string local_name_;
|
||||
std::string initiator_name_;
|
||||
std::string remote_name_;
|
||||
SessionClient* client_;
|
||||
TransportParser* transport_parser_;
|
||||
// Keeps track of what protocol we are speaking.
|
||||
SignalingProtocol current_protocol_;
|
||||
|
||||
friend class SessionManager; // For access to constructor, destructor,
|
||||
// and signaling related methods.
|
||||
};
|
||||
|
||||
// SessionManager manages session instances.
|
||||
class SessionManager : public sigslot::has_slots<> {
|
||||
public:
|
||||
SessionManager(PortAllocator *allocator,
|
||||
rtc::Thread *worker_thread = NULL);
|
||||
virtual ~SessionManager();
|
||||
|
||||
PortAllocator *port_allocator() const { return allocator_; }
|
||||
rtc::Thread *worker_thread() const { return worker_thread_; }
|
||||
rtc::Thread *signaling_thread() const { return signaling_thread_; }
|
||||
|
||||
int session_timeout() const { return timeout_; }
|
||||
void set_session_timeout(int timeout) { timeout_ = timeout; }
|
||||
|
||||
// Set what transport protocol we want to default to.
|
||||
void set_transport_protocol(TransportProtocol proto) {
|
||||
transport_desc_factory_.set_protocol(proto);
|
||||
}
|
||||
|
||||
// Control use of DTLS. An identity must be supplied if DTLS is enabled.
|
||||
void set_secure(SecurePolicy policy) {
|
||||
transport_desc_factory_.set_secure(policy);
|
||||
}
|
||||
void set_identity(rtc::SSLIdentity* identity) {
|
||||
transport_desc_factory_.set_identity(identity);
|
||||
}
|
||||
const TransportDescriptionFactory* transport_desc_factory() const {
|
||||
return &transport_desc_factory_;
|
||||
}
|
||||
|
||||
// Registers support for the given client. If we receive an initiate
|
||||
// describing a session of the given type, we will automatically create a
|
||||
// Session object and notify this client. The client may then accept or
|
||||
// reject the session.
|
||||
void AddClient(const std::string& content_type, SessionClient* client);
|
||||
void RemoveClient(const std::string& content_type);
|
||||
SessionClient* GetClient(const std::string& content_type);
|
||||
|
||||
// Creates a new session. The given name is the JID of the client on whose
|
||||
// behalf we initiate the session.
|
||||
Session *CreateSession(const std::string& local_name,
|
||||
const std::string& content_type);
|
||||
|
||||
Session *CreateSession(const std::string& id,
|
||||
const std::string& local_name,
|
||||
const std::string& content_type);
|
||||
|
||||
// Destroys the given session.
|
||||
void DestroySession(Session *session);
|
||||
|
||||
// Returns the session with the given ID or NULL if none exists.
|
||||
Session *GetSession(const std::string& sid);
|
||||
|
||||
// Terminates all of the sessions created by this manager.
|
||||
void TerminateAll();
|
||||
|
||||
// These are signaled whenever the set of existing sessions changes.
|
||||
sigslot::signal2<Session *, bool> SignalSessionCreate;
|
||||
sigslot::signal1<Session *> SignalSessionDestroy;
|
||||
|
||||
// Determines whether the given stanza is intended for some session.
|
||||
bool IsSessionMessage(const buzz::XmlElement* stanza);
|
||||
|
||||
// Given a sid, initiator, and remote_name, this finds the matching Session
|
||||
Session* FindSession(const std::string& sid,
|
||||
const std::string& remote_name);
|
||||
|
||||
// Called when we receive a stanza for which IsSessionMessage is true.
|
||||
void OnIncomingMessage(const buzz::XmlElement* stanza);
|
||||
|
||||
// Called when we get a response to a message that we sent.
|
||||
void OnIncomingResponse(const buzz::XmlElement* orig_stanza,
|
||||
const buzz::XmlElement* response_stanza);
|
||||
|
||||
// Called if an attempted to send times out or an error is returned. In the
|
||||
// timeout case error_stanza will be NULL
|
||||
void OnFailedSend(const buzz::XmlElement* orig_stanza,
|
||||
const buzz::XmlElement* error_stanza);
|
||||
|
||||
// Signalled each time a session generates a signaling message to send.
|
||||
// Also signalled on errors, but with a NULL session.
|
||||
sigslot::signal2<SessionManager*,
|
||||
const buzz::XmlElement*> SignalOutgoingMessage;
|
||||
|
||||
// Signaled before sessions try to send certain signaling messages. The
|
||||
// client should call OnSignalingReady once it is safe to send them. These
|
||||
// steps are taken so that we don't send signaling messages trying to
|
||||
// re-establish the connectivity of a session when the client cannot send
|
||||
// the messages (and would probably just drop them on the floor).
|
||||
//
|
||||
// Note: you can connect this directly to OnSignalingReady(), if a signalling
|
||||
// check is not supported.
|
||||
sigslot::signal0<> SignalRequestSignaling;
|
||||
void OnSignalingReady();
|
||||
|
||||
// Signaled when this SessionManager is deleted.
|
||||
sigslot::signal0<> SignalDestroyed;
|
||||
|
||||
private:
|
||||
typedef std::map<std::string, Session*> SessionMap;
|
||||
typedef std::map<std::string, SessionClient*> ClientMap;
|
||||
|
||||
// Helper function for CreateSession. This is also invoked when we receive
|
||||
// a message attempting to initiate a session with this client.
|
||||
Session *CreateSession(const std::string& local_name,
|
||||
const std::string& initiator,
|
||||
const std::string& sid,
|
||||
const std::string& content_type,
|
||||
bool received_initiate);
|
||||
|
||||
// Attempts to find a registered session type whose description appears as
|
||||
// a child of the session element. Such a child should be present indicating
|
||||
// the application they hope to initiate.
|
||||
std::string FindClient(const buzz::XmlElement* session);
|
||||
|
||||
// Sends a message back to the other client indicating that we found an error
|
||||
// in the stanza they sent. name identifies the error, type is one of the
|
||||
// standard XMPP types (cancel, continue, modify, auth, wait), and text is a
|
||||
// description for debugging purposes.
|
||||
void SendErrorMessage(const buzz::XmlElement* stanza,
|
||||
const buzz::QName& name,
|
||||
const std::string& type,
|
||||
const std::string& text,
|
||||
const buzz::XmlElement* extra_info);
|
||||
|
||||
// Creates and returns an error message from the given components. The
|
||||
// caller is responsible for deleting this.
|
||||
buzz::XmlElement* CreateErrorMessage(
|
||||
const buzz::XmlElement* stanza,
|
||||
const buzz::QName& name,
|
||||
const std::string& type,
|
||||
const std::string& text,
|
||||
const buzz::XmlElement* extra_info);
|
||||
|
||||
// Called each time a session requests signaling.
|
||||
void OnRequestSignaling(Session* session);
|
||||
|
||||
// Called each time a session has an outgoing message.
|
||||
void OnOutgoingMessage(Session* session, const buzz::XmlElement* stanza);
|
||||
|
||||
// Called each time a session has an error to send.
|
||||
void OnErrorMessage(BaseSession* session,
|
||||
const buzz::XmlElement* stanza,
|
||||
const buzz::QName& name,
|
||||
const std::string& type,
|
||||
const std::string& text,
|
||||
const buzz::XmlElement* extra_info);
|
||||
|
||||
PortAllocator *allocator_;
|
||||
rtc::Thread *signaling_thread_;
|
||||
rtc::Thread *worker_thread_;
|
||||
int timeout_;
|
||||
TransportDescriptionFactory transport_desc_factory_;
|
||||
SessionMap session_map_;
|
||||
ClientMap client_map_;
|
||||
};
|
||||
|
||||
} // namespace cricket
|
||||
|
||||
#endif // WEBRTC_P2P_BASE_SESSIONMANAGER_H_
|
38
webrtc/libjingle/session/transportparser.cc
Normal file
38
webrtc/libjingle/session/transportparser.cc
Normal file
@ -0,0 +1,38 @@
|
||||
/*
|
||||
* Copyright 2004 The WebRTC Project Authors. All rights reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
#include "webrtc/libjingle/session/transportparser.h"
|
||||
|
||||
#include "webrtc/p2p/base/parsing.h"
|
||||
#include "webrtc/libjingle/xmllite/xmlelement.h"
|
||||
#include "webrtc/libjingle/xmpp/constants.h"
|
||||
|
||||
namespace cricket {
|
||||
|
||||
bool TransportParser::ParseAddress(const buzz::XmlElement* elem,
|
||||
const buzz::QName& address_name,
|
||||
const buzz::QName& port_name,
|
||||
rtc::SocketAddress* address,
|
||||
ParseError* error) {
|
||||
if (!elem->HasAttr(address_name))
|
||||
return BadParse("address does not have " + address_name.LocalPart(), error);
|
||||
if (!elem->HasAttr(port_name))
|
||||
return BadParse("address does not have " + port_name.LocalPart(), error);
|
||||
|
||||
address->SetIP(elem->Attr(address_name));
|
||||
std::istringstream ist(elem->Attr(port_name));
|
||||
int port = 0;
|
||||
ist >> port;
|
||||
address->SetPort(port);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace cricket
|
78
webrtc/libjingle/session/transportparser.h
Normal file
78
webrtc/libjingle/session/transportparser.h
Normal file
@ -0,0 +1,78 @@
|
||||
/*
|
||||
* Copyright 2004 The WebRTC Project Authors. All rights reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
#ifndef WEBRTC_P2P_BASE_TRANSPORTPARSER_H_
|
||||
#define WEBRTC_P2P_BASE_TRANSPORTPARSER_H_
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "webrtc/p2p/base/transportinfo.h"
|
||||
|
||||
namespace buzz {
|
||||
class QName;
|
||||
class XmlElement;
|
||||
}
|
||||
|
||||
namespace cricket {
|
||||
|
||||
struct ParseError;
|
||||
struct WriteError;
|
||||
class CandidateTranslator;
|
||||
|
||||
typedef std::vector<buzz::XmlElement*> XmlElements;
|
||||
|
||||
class TransportParser {
|
||||
public:
|
||||
// The incoming Translator value may be null, in which case
|
||||
// ParseCandidates should return false if there are candidates to
|
||||
// parse (indicating a failure to parse). If the Translator is null
|
||||
// and there are no candidates to parse, then return true,
|
||||
// indicating a successful parse of 0 candidates.
|
||||
|
||||
// Parse or write a transport description, including ICE credentials and
|
||||
// any DTLS fingerprint. Since only Jingle has transport descriptions, these
|
||||
// functions are only used when serializing to Jingle.
|
||||
virtual bool ParseTransportDescription(const buzz::XmlElement* elem,
|
||||
const CandidateTranslator* translator,
|
||||
TransportDescription* tdesc,
|
||||
ParseError* error) = 0;
|
||||
virtual bool WriteTransportDescription(const TransportDescription& tdesc,
|
||||
const CandidateTranslator* translator,
|
||||
buzz::XmlElement** tdesc_elem,
|
||||
WriteError* error) = 0;
|
||||
|
||||
|
||||
// Parse a single candidate. This must be used when parsing Gingle
|
||||
// candidates, since there is no enclosing transport description.
|
||||
virtual bool ParseGingleCandidate(const buzz::XmlElement* elem,
|
||||
const CandidateTranslator* translator,
|
||||
Candidate* candidates,
|
||||
ParseError* error) = 0;
|
||||
virtual bool WriteGingleCandidate(const Candidate& candidate,
|
||||
const CandidateTranslator* translator,
|
||||
buzz::XmlElement** candidate_elem,
|
||||
WriteError* error) = 0;
|
||||
|
||||
// Helper function to parse an element describing an address. This
|
||||
// retrieves the IP and port from the given element and verifies
|
||||
// that they look like plausible values.
|
||||
bool ParseAddress(const buzz::XmlElement* elem,
|
||||
const buzz::QName& address_name,
|
||||
const buzz::QName& port_name,
|
||||
rtc::SocketAddress* address,
|
||||
ParseError* error);
|
||||
|
||||
virtual ~TransportParser() {}
|
||||
};
|
||||
|
||||
} // namespace cricket
|
||||
|
||||
#endif // WEBRTC_P2P_BASE_TRANSPORTPARSER_H_
|
136
webrtc/libjingle/session/transportparser_unittest.cc
Normal file
136
webrtc/libjingle/session/transportparser_unittest.cc
Normal file
@ -0,0 +1,136 @@
|
||||
/*
|
||||
* Copyright 2011 The WebRTC Project Authors. All rights reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
#include "webrtc/base/gunit.h"
|
||||
#include "webrtc/libjingle/session/p2ptransportparser.h"
|
||||
#include "webrtc/p2p/base/parsing.h"
|
||||
#include "webrtc/p2p/base/sessionmessages.h"
|
||||
#include "webrtc/libjingle/xmllite/xmlelement.h"
|
||||
#include "webrtc/libjingle/xmpp/constants.h"
|
||||
#include "webrtc/p2p/base/constants.h"
|
||||
|
||||
using cricket::Candidate;
|
||||
using cricket::Candidates;
|
||||
using cricket::ParseError;
|
||||
using cricket::WriteError;
|
||||
|
||||
class TransportParserTest : public testing::Test {
|
||||
};
|
||||
|
||||
class FakeCandidateTranslator : public cricket::CandidateTranslator {
|
||||
public:
|
||||
void AddMapping(int component, const std::string& channel_name) {
|
||||
name_to_component[channel_name] = component;
|
||||
component_to_name[component] = channel_name;
|
||||
}
|
||||
|
||||
bool GetChannelNameFromComponent(
|
||||
int component, std::string* channel_name) const {
|
||||
if (component_to_name.find(component) == component_to_name.end()) {
|
||||
return false;
|
||||
}
|
||||
*channel_name = component_to_name.find(component)->second;
|
||||
return true;
|
||||
}
|
||||
bool GetComponentFromChannelName(
|
||||
const std::string& channel_name, int* component) const {
|
||||
if (name_to_component.find(channel_name) == name_to_component.end()) {
|
||||
return false;
|
||||
}
|
||||
*component = name_to_component.find(channel_name)->second;
|
||||
return true;
|
||||
}
|
||||
|
||||
std::map<std::string, int> name_to_component;
|
||||
std::map<int, std::string> component_to_name;
|
||||
};
|
||||
|
||||
// Tests that we can properly serialize/deserialize candidates.
|
||||
TEST_F(TransportParserTest, TestP2PTransportWriteAndParseCandidate) {
|
||||
Candidate test_candidate(
|
||||
"", 1, "udp",
|
||||
rtc::SocketAddress("2001:db8:fefe::1", 9999),
|
||||
738197504, "abcdef", "ghijkl", "foo", 50, "");
|
||||
test_candidate.set_network_name("testnet");
|
||||
Candidate test_candidate2(
|
||||
"", 2, "tcp",
|
||||
rtc::SocketAddress("192.168.7.1", 9999),
|
||||
1107296256, "mnopqr", "stuvwx", "bar", 100, "");
|
||||
test_candidate2.set_network_name("testnet2");
|
||||
rtc::SocketAddress host_address("www.google.com", 24601);
|
||||
host_address.SetResolvedIP(rtc::IPAddress(0x0A000001));
|
||||
Candidate test_candidate3(
|
||||
"", 3, "spdy", host_address, 1476395008, "yzabcd",
|
||||
"efghij", "baz", 150, "");
|
||||
test_candidate3.set_network_name("testnet3");
|
||||
WriteError write_error;
|
||||
ParseError parse_error;
|
||||
rtc::scoped_ptr<buzz::XmlElement> elem;
|
||||
cricket::Candidate parsed_candidate;
|
||||
cricket::P2PTransportParser parser;
|
||||
|
||||
FakeCandidateTranslator translator;
|
||||
translator.AddMapping(1, "test");
|
||||
translator.AddMapping(2, "test2");
|
||||
translator.AddMapping(3, "test3");
|
||||
|
||||
EXPECT_TRUE(parser.WriteGingleCandidate(test_candidate, &translator,
|
||||
elem.accept(), &write_error));
|
||||
EXPECT_EQ("", write_error.text);
|
||||
EXPECT_EQ("test", elem->Attr(buzz::QN_NAME));
|
||||
EXPECT_EQ("udp", elem->Attr(cricket::QN_PROTOCOL));
|
||||
EXPECT_EQ("2001:db8:fefe::1", elem->Attr(cricket::QN_ADDRESS));
|
||||
EXPECT_EQ("9999", elem->Attr(cricket::QN_PORT));
|
||||
EXPECT_EQ("0.34", elem->Attr(cricket::QN_PREFERENCE));
|
||||
EXPECT_EQ("abcdef", elem->Attr(cricket::QN_USERNAME));
|
||||
EXPECT_EQ("ghijkl", elem->Attr(cricket::QN_PASSWORD));
|
||||
EXPECT_EQ("foo", elem->Attr(cricket::QN_TYPE));
|
||||
EXPECT_EQ("testnet", elem->Attr(cricket::QN_NETWORK));
|
||||
EXPECT_EQ("50", elem->Attr(cricket::QN_GENERATION));
|
||||
|
||||
EXPECT_TRUE(parser.ParseGingleCandidate(elem.get(), &translator,
|
||||
&parsed_candidate, &parse_error));
|
||||
EXPECT_TRUE(test_candidate.IsEquivalent(parsed_candidate));
|
||||
|
||||
EXPECT_TRUE(parser.WriteGingleCandidate(test_candidate2, &translator,
|
||||
elem.accept(), &write_error));
|
||||
EXPECT_EQ("test2", elem->Attr(buzz::QN_NAME));
|
||||
EXPECT_EQ("tcp", elem->Attr(cricket::QN_PROTOCOL));
|
||||
EXPECT_EQ("192.168.7.1", elem->Attr(cricket::QN_ADDRESS));
|
||||
EXPECT_EQ("9999", elem->Attr(cricket::QN_PORT));
|
||||
EXPECT_EQ("0.51", elem->Attr(cricket::QN_PREFERENCE));
|
||||
EXPECT_EQ("mnopqr", elem->Attr(cricket::QN_USERNAME));
|
||||
EXPECT_EQ("stuvwx", elem->Attr(cricket::QN_PASSWORD));
|
||||
EXPECT_EQ("bar", elem->Attr(cricket::QN_TYPE));
|
||||
EXPECT_EQ("testnet2", elem->Attr(cricket::QN_NETWORK));
|
||||
EXPECT_EQ("100", elem->Attr(cricket::QN_GENERATION));
|
||||
|
||||
EXPECT_TRUE(parser.ParseGingleCandidate(elem.get(), &translator,
|
||||
&parsed_candidate, &parse_error));
|
||||
EXPECT_TRUE(test_candidate2.IsEquivalent(parsed_candidate));
|
||||
|
||||
// Check that an ip is preferred over hostname.
|
||||
EXPECT_TRUE(parser.WriteGingleCandidate(test_candidate3, &translator,
|
||||
elem.accept(), &write_error));
|
||||
EXPECT_EQ("test3", elem->Attr(cricket::QN_NAME));
|
||||
EXPECT_EQ("spdy", elem->Attr(cricket::QN_PROTOCOL));
|
||||
EXPECT_EQ("10.0.0.1", elem->Attr(cricket::QN_ADDRESS));
|
||||
EXPECT_EQ("24601", elem->Attr(cricket::QN_PORT));
|
||||
EXPECT_EQ("0.69", elem->Attr(cricket::QN_PREFERENCE));
|
||||
EXPECT_EQ("yzabcd", elem->Attr(cricket::QN_USERNAME));
|
||||
EXPECT_EQ("efghij", elem->Attr(cricket::QN_PASSWORD));
|
||||
EXPECT_EQ("baz", elem->Attr(cricket::QN_TYPE));
|
||||
EXPECT_EQ("testnet3", elem->Attr(cricket::QN_NETWORK));
|
||||
EXPECT_EQ("150", elem->Attr(cricket::QN_GENERATION));
|
||||
|
||||
EXPECT_TRUE(parser.ParseGingleCandidate(elem.get(), &translator,
|
||||
&parsed_candidate, &parse_error));
|
||||
EXPECT_TRUE(test_candidate3.IsEquivalent(parsed_candidate));
|
||||
}
|
@ -25,14 +25,14 @@
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef TALK_SESSION_TUNNEL_PSEUDOTCPCHANNEL_H_
|
||||
#define TALK_SESSION_TUNNEL_PSEUDOTCPCHANNEL_H_
|
||||
#ifndef WEBRTC_LIBJINGLE_SESSION_TUNNEL_PSEUDOTCPCHANNEL_H_
|
||||
#define WEBRTC_LIBJINGLE_SESSION_TUNNEL_PSEUDOTCPCHANNEL_H_
|
||||
|
||||
#include "webrtc/base/criticalsection.h"
|
||||
#include "webrtc/base/messagequeue.h"
|
||||
#include "webrtc/base/stream.h"
|
||||
#include "webrtc/libjingle/session/sessionmanager.h"
|
||||
#include "webrtc/p2p/base/pseudotcp.h"
|
||||
#include "webrtc/p2p/base/sessionmanager.h"
|
||||
|
||||
namespace rtc {
|
||||
class Thread;
|
||||
@ -137,4 +137,4 @@ class PseudoTcpChannel
|
||||
|
||||
} // namespace cricket
|
||||
|
||||
#endif // TALK_SESSION_TUNNEL_PSEUDOTCPCHANNEL_H_
|
||||
#endif // WEBRTC_LIBJINGLE_SESSION_TUNNEL_PSEUDOTCPCHANNEL_H_
|
||||
|
@ -31,8 +31,8 @@
|
||||
// SecureTunnelSession is a TunnelSession that wraps the underlying
|
||||
// tunnel stream into an SSLStreamAdapter.
|
||||
|
||||
#ifndef TALK_SESSION_TUNNEL_SECURETUNNELSESSIONCLIENT_H_
|
||||
#define TALK_SESSION_TUNNEL_SECURETUNNELSESSIONCLIENT_H_
|
||||
#ifndef WEBRTC_LIBJINGLE_SESSION_TUNNEL_SECURETUNNELSESSIONCLIENT_H_
|
||||
#define WEBRTC_LIBJINGLE_SESSION_TUNNEL_SECURETUNNELSESSIONCLIENT_H_
|
||||
|
||||
#include <string>
|
||||
|
||||
@ -162,4 +162,4 @@ class SecureTunnelSession : public TunnelSession {
|
||||
|
||||
} // namespace cricket
|
||||
|
||||
#endif // TALK_SESSION_TUNNEL_SECURETUNNELSESSIONCLIENT_H_
|
||||
#endif // WEBRTC_LIBJINGLE_SESSION_TUNNEL_SECURETUNNELSESSIONCLIENT_H_
|
||||
|
@ -30,16 +30,16 @@
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include "webrtc/base/criticalsection.h"
|
||||
#include "webrtc/base/stream.h"
|
||||
#include "webrtc/libjingle/session/sessionmanager.h"
|
||||
#include "webrtc/libjingle/xmllite/qname.h"
|
||||
#include "webrtc/libjingle/xmpp/constants.h"
|
||||
#include "webrtc/p2p/base/constants.h"
|
||||
#include "webrtc/p2p/base/pseudotcp.h"
|
||||
#include "webrtc/p2p/base/session.h"
|
||||
#include "webrtc/p2p/base/sessionclient.h"
|
||||
#include "webrtc/p2p/base/sessiondescription.h"
|
||||
#include "webrtc/p2p/base/sessionmanager.h"
|
||||
#include "webrtc/libjingle/xmllite/qname.h"
|
||||
#include "webrtc/libjingle/xmpp/constants.h"
|
||||
#include "webrtc/base/criticalsection.h"
|
||||
#include "webrtc/base/stream.h"
|
||||
|
||||
namespace cricket {
|
||||
|
||||
|
@ -26,16 +26,16 @@
|
||||
*/
|
||||
|
||||
#include <string>
|
||||
#include "webrtc/p2p/base/sessionmanager.h"
|
||||
#include "webrtc/p2p/base/transport.h"
|
||||
#include "webrtc/p2p/client/fakeportallocator.h"
|
||||
#include "webrtc/libjingle/session/tunnel/tunnelsessionclient.h"
|
||||
#include "webrtc/base/gunit.h"
|
||||
#include "webrtc/base/messagehandler.h"
|
||||
#include "webrtc/base/scoped_ptr.h"
|
||||
#include "webrtc/base/stream.h"
|
||||
#include "webrtc/base/thread.h"
|
||||
#include "webrtc/base/timeutils.h"
|
||||
#include "webrtc/libjingle/session/sessionmanager.h"
|
||||
#include "webrtc/libjingle/session/tunnel/tunnelsessionclient.h"
|
||||
#include "webrtc/p2p/base/transport.h"
|
||||
#include "webrtc/p2p/client/fakeportallocator.h"
|
||||
|
||||
static const int kTimeoutMs = 10000;
|
||||
static const int kBlockSize = 4096;
|
||||
|
@ -163,6 +163,7 @@ const size_t ICE_UFRAG_MIN_LENGTH = 4;
|
||||
const size_t ICE_PWD_MIN_LENGTH = 22;
|
||||
const size_t ICE_UFRAG_MAX_LENGTH = 255;
|
||||
const size_t ICE_PWD_MAX_LENGTH = 256;
|
||||
const size_t GICE_UFRAG_MAX_LENGTH = 16;
|
||||
// TODO: This is media-specific, so might belong
|
||||
// somewhere like media/base/constants.h
|
||||
const int ICE_CANDIDATE_COMPONENT_RTP = 1;
|
||||
|
@ -165,6 +165,7 @@ extern const size_t ICE_UFRAG_MIN_LENGTH;
|
||||
extern const size_t ICE_PWD_MIN_LENGTH;
|
||||
extern const size_t ICE_UFRAG_MAX_LENGTH;
|
||||
extern const size_t ICE_PWD_MAX_LENGTH;
|
||||
extern const size_t GICE_UFRAG_MAX_LENGTH;
|
||||
extern const int ICE_CANDIDATE_COMPONENT_RTP;
|
||||
extern const int ICE_CANDIDATE_COMPONENT_RTCP;
|
||||
extern const int ICE_CANDIDATE_COMPONENT_DEFAULT;
|
||||
|
@ -11,13 +11,8 @@
|
||||
#include "webrtc/p2p/base/p2ptransport.h"
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "webrtc/p2p/base/constants.h"
|
||||
#include "webrtc/p2p/base/p2ptransportchannel.h"
|
||||
#include "webrtc/p2p/base/parsing.h"
|
||||
#include "webrtc/p2p/base/sessionmanager.h"
|
||||
#include "webrtc/p2p/base/sessionmessages.h"
|
||||
#include "webrtc/libjingle/xmllite/qname.h"
|
||||
#include "webrtc/libjingle/xmllite/xmlelement.h"
|
||||
#include "webrtc/libjingle/xmpp/constants.h"
|
||||
@ -26,20 +21,8 @@
|
||||
#include "webrtc/base/stringencode.h"
|
||||
#include "webrtc/base/stringutils.h"
|
||||
|
||||
namespace {
|
||||
|
||||
// Limits for GICE and ICE username sizes.
|
||||
const size_t kMaxGiceUsernameSize = 16;
|
||||
const size_t kMaxIceUsernameSize = 512;
|
||||
|
||||
} // namespace
|
||||
|
||||
namespace cricket {
|
||||
|
||||
static buzz::XmlElement* NewTransportElement(const std::string& name) {
|
||||
return new buzz::XmlElement(buzz::QName(name, LN_TRANSPORT), true);
|
||||
}
|
||||
|
||||
P2PTransport::P2PTransport(rtc::Thread* signaling_thread,
|
||||
rtc::Thread* worker_thread,
|
||||
const std::string& content_name,
|
||||
@ -61,186 +44,4 @@ void P2PTransport::DestroyTransportChannel(TransportChannelImpl* channel) {
|
||||
delete channel;
|
||||
}
|
||||
|
||||
bool P2PTransportParser::ParseTransportDescription(
|
||||
const buzz::XmlElement* elem,
|
||||
const CandidateTranslator* translator,
|
||||
TransportDescription* desc,
|
||||
ParseError* error) {
|
||||
ASSERT(elem->Name().LocalPart() == LN_TRANSPORT);
|
||||
desc->transport_type = elem->Name().Namespace();
|
||||
if (desc->transport_type != NS_GINGLE_P2P)
|
||||
return BadParse("Unsupported transport type", error);
|
||||
|
||||
for (const buzz::XmlElement* candidate_elem = elem->FirstElement();
|
||||
candidate_elem != NULL;
|
||||
candidate_elem = candidate_elem->NextElement()) {
|
||||
// Only look at local part because the namespace might (eventually)
|
||||
// be NS_GINGLE_P2P or NS_JINGLE_ICE_UDP.
|
||||
if (candidate_elem->Name().LocalPart() == LN_CANDIDATE) {
|
||||
Candidate candidate;
|
||||
if (!ParseCandidate(ICEPROTO_GOOGLE, candidate_elem, translator,
|
||||
&candidate, error)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
desc->candidates.push_back(candidate);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool P2PTransportParser::WriteTransportDescription(
|
||||
const TransportDescription& desc,
|
||||
const CandidateTranslator* translator,
|
||||
buzz::XmlElement** out_elem,
|
||||
WriteError* error) {
|
||||
TransportProtocol proto = TransportProtocolFromDescription(&desc);
|
||||
rtc::scoped_ptr<buzz::XmlElement> trans_elem(
|
||||
NewTransportElement(desc.transport_type));
|
||||
|
||||
// Fail if we get HYBRID or ICE right now.
|
||||
// TODO(juberti): Add ICE and HYBRID serialization.
|
||||
if (proto != ICEPROTO_GOOGLE) {
|
||||
LOG(LS_ERROR) << "Failed to serialize non-GICE TransportDescription";
|
||||
return false;
|
||||
}
|
||||
|
||||
for (std::vector<Candidate>::const_iterator iter = desc.candidates.begin();
|
||||
iter != desc.candidates.end(); ++iter) {
|
||||
rtc::scoped_ptr<buzz::XmlElement> cand_elem(
|
||||
new buzz::XmlElement(QN_GINGLE_P2P_CANDIDATE));
|
||||
if (!WriteCandidate(proto, *iter, translator, cand_elem.get(), error)) {
|
||||
return false;
|
||||
}
|
||||
trans_elem->AddElement(cand_elem.release());
|
||||
}
|
||||
|
||||
*out_elem = trans_elem.release();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool P2PTransportParser::ParseGingleCandidate(
|
||||
const buzz::XmlElement* elem,
|
||||
const CandidateTranslator* translator,
|
||||
Candidate* candidate,
|
||||
ParseError* error) {
|
||||
return ParseCandidate(ICEPROTO_GOOGLE, elem, translator, candidate, error);
|
||||
}
|
||||
|
||||
bool P2PTransportParser::WriteGingleCandidate(
|
||||
const Candidate& candidate,
|
||||
const CandidateTranslator* translator,
|
||||
buzz::XmlElement** out_elem,
|
||||
WriteError* error) {
|
||||
rtc::scoped_ptr<buzz::XmlElement> elem(
|
||||
new buzz::XmlElement(QN_GINGLE_CANDIDATE));
|
||||
bool ret = WriteCandidate(ICEPROTO_GOOGLE, candidate, translator, elem.get(),
|
||||
error);
|
||||
if (ret) {
|
||||
*out_elem = elem.release();
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool P2PTransportParser::VerifyUsernameFormat(TransportProtocol proto,
|
||||
const std::string& username,
|
||||
ParseError* error) {
|
||||
if (proto == ICEPROTO_GOOGLE || proto == ICEPROTO_HYBRID) {
|
||||
if (username.size() > kMaxGiceUsernameSize)
|
||||
return BadParse("candidate username is too long", error);
|
||||
if (!rtc::Base64::IsBase64Encoded(username))
|
||||
return BadParse("candidate username has non-base64 encoded characters",
|
||||
error);
|
||||
} else if (proto == ICEPROTO_RFC5245) {
|
||||
if (username.size() > kMaxIceUsernameSize)
|
||||
return BadParse("candidate username is too long", error);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool P2PTransportParser::ParseCandidate(TransportProtocol proto,
|
||||
const buzz::XmlElement* elem,
|
||||
const CandidateTranslator* translator,
|
||||
Candidate* candidate,
|
||||
ParseError* error) {
|
||||
ASSERT(proto == ICEPROTO_GOOGLE);
|
||||
ASSERT(translator != NULL);
|
||||
|
||||
if (!elem->HasAttr(buzz::QN_NAME) ||
|
||||
!elem->HasAttr(QN_ADDRESS) ||
|
||||
!elem->HasAttr(QN_PORT) ||
|
||||
!elem->HasAttr(QN_USERNAME) ||
|
||||
!elem->HasAttr(QN_PROTOCOL) ||
|
||||
!elem->HasAttr(QN_GENERATION)) {
|
||||
return BadParse("candidate missing required attribute", error);
|
||||
}
|
||||
|
||||
rtc::SocketAddress address;
|
||||
if (!ParseAddress(elem, QN_ADDRESS, QN_PORT, &address, error))
|
||||
return false;
|
||||
|
||||
std::string channel_name = elem->Attr(buzz::QN_NAME);
|
||||
int component = 0;
|
||||
if (!translator ||
|
||||
!translator->GetComponentFromChannelName(channel_name, &component)) {
|
||||
return BadParse("candidate has unknown channel name " + channel_name,
|
||||
error);
|
||||
}
|
||||
|
||||
float preference = 0.0;
|
||||
if (!GetXmlAttr(elem, QN_PREFERENCE, 0.0f, &preference)) {
|
||||
return BadParse("candidate has unknown preference", error);
|
||||
}
|
||||
|
||||
candidate->set_component(component);
|
||||
candidate->set_address(address);
|
||||
candidate->set_username(elem->Attr(QN_USERNAME));
|
||||
candidate->set_preference(preference);
|
||||
candidate->set_protocol(elem->Attr(QN_PROTOCOL));
|
||||
candidate->set_generation_str(elem->Attr(QN_GENERATION));
|
||||
if (elem->HasAttr(QN_PASSWORD))
|
||||
candidate->set_password(elem->Attr(QN_PASSWORD));
|
||||
if (elem->HasAttr(buzz::QN_TYPE))
|
||||
candidate->set_type(elem->Attr(buzz::QN_TYPE));
|
||||
if (elem->HasAttr(QN_NETWORK))
|
||||
candidate->set_network_name(elem->Attr(QN_NETWORK));
|
||||
|
||||
if (!VerifyUsernameFormat(proto, candidate->username(), error))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool P2PTransportParser::WriteCandidate(TransportProtocol proto,
|
||||
const Candidate& candidate,
|
||||
const CandidateTranslator* translator,
|
||||
buzz::XmlElement* elem,
|
||||
WriteError* error) {
|
||||
ASSERT(proto == ICEPROTO_GOOGLE);
|
||||
ASSERT(translator != NULL);
|
||||
|
||||
std::string channel_name;
|
||||
if (!translator ||
|
||||
!translator->GetChannelNameFromComponent(
|
||||
candidate.component(), &channel_name)) {
|
||||
return BadWrite("Cannot write candidate because of unknown component.",
|
||||
error);
|
||||
}
|
||||
|
||||
elem->SetAttr(buzz::QN_NAME, channel_name);
|
||||
elem->SetAttr(QN_ADDRESS, candidate.address().ipaddr().ToString());
|
||||
elem->SetAttr(QN_PORT, candidate.address().PortAsString());
|
||||
AddXmlAttr(elem, QN_PREFERENCE, candidate.preference());
|
||||
elem->SetAttr(QN_USERNAME, candidate.username());
|
||||
elem->SetAttr(QN_PROTOCOL, candidate.protocol());
|
||||
elem->SetAttr(QN_GENERATION, candidate.generation_str());
|
||||
if (!candidate.password().empty())
|
||||
elem->SetAttr(QN_PASSWORD, candidate.password());
|
||||
elem->SetAttr(buzz::QN_TYPE, candidate.type());
|
||||
if (!candidate.network_name().empty())
|
||||
elem->SetAttr(QN_NETWORK, candidate.network_name());
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace cricket
|
||||
|
@ -12,7 +12,6 @@
|
||||
#define WEBRTC_P2P_BASE_P2PTRANSPORT_H_
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include "webrtc/p2p/base/transport.h"
|
||||
|
||||
namespace cricket {
|
||||
@ -35,52 +34,6 @@ class P2PTransport : public Transport {
|
||||
DISALLOW_EVIL_CONSTRUCTORS(P2PTransport);
|
||||
};
|
||||
|
||||
class P2PTransportParser : public TransportParser {
|
||||
public:
|
||||
P2PTransportParser() {}
|
||||
// Translator may be null, in which case ParseCandidates should
|
||||
// return false if there are candidates to parse. We can't not call
|
||||
// ParseCandidates because there's no way to know ahead of time if
|
||||
// there are candidates or not.
|
||||
|
||||
// Jingle-specific functions; can be used with either ICE, GICE, or HYBRID.
|
||||
virtual bool ParseTransportDescription(const buzz::XmlElement* elem,
|
||||
const CandidateTranslator* translator,
|
||||
TransportDescription* desc,
|
||||
ParseError* error);
|
||||
virtual bool WriteTransportDescription(const TransportDescription& desc,
|
||||
const CandidateTranslator* translator,
|
||||
buzz::XmlElement** elem,
|
||||
WriteError* error);
|
||||
|
||||
// Legacy Gingle functions; only can be used with GICE.
|
||||
virtual bool ParseGingleCandidate(const buzz::XmlElement* elem,
|
||||
const CandidateTranslator* translator,
|
||||
Candidate* candidate,
|
||||
ParseError* error);
|
||||
virtual bool WriteGingleCandidate(const Candidate& candidate,
|
||||
const CandidateTranslator* translator,
|
||||
buzz::XmlElement** elem,
|
||||
WriteError* error);
|
||||
|
||||
private:
|
||||
bool ParseCandidate(TransportProtocol proto,
|
||||
const buzz::XmlElement* elem,
|
||||
const CandidateTranslator* translator,
|
||||
Candidate* candidate,
|
||||
ParseError* error);
|
||||
bool WriteCandidate(TransportProtocol proto,
|
||||
const Candidate& candidate,
|
||||
const CandidateTranslator* translator,
|
||||
buzz::XmlElement* elem,
|
||||
WriteError* error);
|
||||
bool VerifyUsernameFormat(TransportProtocol proto,
|
||||
const std::string& username,
|
||||
ParseError* error);
|
||||
|
||||
DISALLOW_EVIL_CONSTRUCTORS(P2PTransportParser);
|
||||
};
|
||||
|
||||
} // namespace cricket
|
||||
|
||||
#endif // WEBRTC_P2P_BASE_P2PTRANSPORT_H_
|
||||
|
@ -9,15 +9,9 @@
|
||||
*/
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include "webrtc/p2p/base/constants.h"
|
||||
#include "webrtc/p2p/base/parsing.h"
|
||||
|
||||
#include "webrtc/p2p/base/rawtransport.h"
|
||||
#include "webrtc/p2p/base/rawtransportchannel.h"
|
||||
#include "webrtc/p2p/base/sessionmanager.h"
|
||||
#include "webrtc/libjingle/xmllite/qname.h"
|
||||
#include "webrtc/libjingle/xmllite/xmlelement.h"
|
||||
#include "webrtc/libjingle/xmpp/constants.h"
|
||||
#include "webrtc/base/common.h"
|
||||
|
||||
#if defined(FEATURE_ENABLE_PSTN)
|
||||
@ -35,72 +29,6 @@ RawTransport::~RawTransport() {
|
||||
DestroyAllChannels();
|
||||
}
|
||||
|
||||
bool RawTransport::ParseCandidates(SignalingProtocol protocol,
|
||||
const buzz::XmlElement* elem,
|
||||
const CandidateTranslator* translator,
|
||||
Candidates* candidates,
|
||||
ParseError* error) {
|
||||
for (const buzz::XmlElement* cand_elem = elem->FirstElement();
|
||||
cand_elem != NULL;
|
||||
cand_elem = cand_elem->NextElement()) {
|
||||
if (cand_elem->Name() == QN_GINGLE_RAW_CHANNEL) {
|
||||
if (!cand_elem->HasAttr(buzz::QN_NAME)) {
|
||||
return BadParse("no channel name given", error);
|
||||
}
|
||||
if (type() != cand_elem->Attr(buzz::QN_NAME)) {
|
||||
return BadParse("channel named does not exist", error);
|
||||
}
|
||||
rtc::SocketAddress addr;
|
||||
if (!ParseRawAddress(cand_elem, &addr, error))
|
||||
return false;
|
||||
|
||||
Candidate candidate;
|
||||
candidate.set_component(1);
|
||||
candidate.set_address(addr);
|
||||
candidates->push_back(candidate);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool RawTransport::WriteCandidates(SignalingProtocol protocol,
|
||||
const Candidates& candidates,
|
||||
const CandidateTranslator* translator,
|
||||
XmlElements* candidate_elems,
|
||||
WriteError* error) {
|
||||
for (std::vector<Candidate>::const_iterator
|
||||
cand = candidates.begin();
|
||||
cand != candidates.end();
|
||||
++cand) {
|
||||
ASSERT(cand->component() == 1);
|
||||
ASSERT(cand->protocol() == "udp");
|
||||
rtc::SocketAddress addr = cand->address();
|
||||
|
||||
buzz::XmlElement* elem = new buzz::XmlElement(QN_GINGLE_RAW_CHANNEL);
|
||||
elem->SetAttr(buzz::QN_NAME, type());
|
||||
elem->SetAttr(QN_ADDRESS, addr.ipaddr().ToString());
|
||||
elem->SetAttr(QN_PORT, addr.PortAsString());
|
||||
candidate_elems->push_back(elem);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool RawTransport::ParseRawAddress(const buzz::XmlElement* elem,
|
||||
rtc::SocketAddress* addr,
|
||||
ParseError* error) {
|
||||
// Make sure the required attributes exist
|
||||
if (!elem->HasAttr(QN_ADDRESS) ||
|
||||
!elem->HasAttr(QN_PORT)) {
|
||||
return BadParse("channel missing required attribute", error);
|
||||
}
|
||||
|
||||
// Parse the address.
|
||||
if (!ParseAddress(elem, QN_ADDRESS, QN_PORT, addr, error))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
TransportChannelImpl* RawTransport::CreateTransportChannel(int component) {
|
||||
return new RawTransportChannel(content_name(), component, this,
|
||||
worker_thread(),
|
||||
|
@ -20,7 +20,7 @@ namespace cricket {
|
||||
// Implements a transport that only sends raw packets, no STUN. As a result,
|
||||
// it cannot do pings to determine connectivity, so it only uses a single port
|
||||
// that it thinks will work.
|
||||
class RawTransport : public Transport, public TransportParser {
|
||||
class RawTransport : public Transport {
|
||||
public:
|
||||
RawTransport(rtc::Thread* signaling_thread,
|
||||
rtc::Thread* worker_thread,
|
||||
@ -28,30 +28,12 @@ class RawTransport : public Transport, public TransportParser {
|
||||
PortAllocator* allocator);
|
||||
virtual ~RawTransport();
|
||||
|
||||
virtual bool ParseCandidates(SignalingProtocol protocol,
|
||||
const buzz::XmlElement* elem,
|
||||
const CandidateTranslator* translator,
|
||||
Candidates* candidates,
|
||||
ParseError* error);
|
||||
virtual bool WriteCandidates(SignalingProtocol protocol,
|
||||
const Candidates& candidates,
|
||||
const CandidateTranslator* translator,
|
||||
XmlElements* candidate_elems,
|
||||
WriteError* error);
|
||||
|
||||
protected:
|
||||
// Creates and destroys raw channels.
|
||||
virtual TransportChannelImpl* CreateTransportChannel(int component);
|
||||
virtual void DestroyTransportChannel(TransportChannelImpl* channel);
|
||||
|
||||
private:
|
||||
// Parses the given element, which should describe the address to use for a
|
||||
// given channel. This will return false and signal an error if the address
|
||||
// or channel name is bad.
|
||||
bool ParseRawAddress(const buzz::XmlElement* elem,
|
||||
rtc::SocketAddress* addr,
|
||||
ParseError* error);
|
||||
|
||||
friend class RawTransportChannel; // For ParseAddress.
|
||||
|
||||
DISALLOW_EVIL_CONSTRUCTORS(RawTransport);
|
||||
|
@ -17,11 +17,7 @@
|
||||
#include "webrtc/p2p/base/portinterface.h"
|
||||
#include "webrtc/p2p/base/rawtransport.h"
|
||||
#include "webrtc/p2p/base/relayport.h"
|
||||
#include "webrtc/p2p/base/sessionmanager.h"
|
||||
#include "webrtc/p2p/base/stunport.h"
|
||||
#include "webrtc/libjingle/xmllite/qname.h"
|
||||
#include "webrtc/libjingle/xmllite/xmlelement.h"
|
||||
#include "webrtc/libjingle/xmpp/constants.h"
|
||||
#include "webrtc/base/common.h"
|
||||
|
||||
#if defined(FEATURE_ENABLE_PSTN)
|
||||
|
@ -20,6 +20,7 @@ class XmlElement;
|
||||
namespace cricket {
|
||||
|
||||
struct ParseError;
|
||||
struct WriteError;
|
||||
class Session;
|
||||
class ContentDescription;
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,436 +1 @@
|
||||
/*
|
||||
* Copyright 2004 The WebRTC Project Authors. All rights reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
#ifndef WEBRTC_P2P_BASE_SESSIONMANAGER_H_
|
||||
#define WEBRTC_P2P_BASE_SESSIONMANAGER_H_
|
||||
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#include "webrtc/libjingle/xmllite/xmlelement.h"
|
||||
#include "webrtc/libjingle/xmpp/constants.h"
|
||||
#include "webrtc/p2p/base/parsing.h"
|
||||
#include "webrtc/p2p/base/portallocator.h"
|
||||
#include "webrtc/p2p/base/session.h"
|
||||
#include "webrtc/p2p/base/sessionclient.h"
|
||||
#include "webrtc/p2p/base/sessionmessages.h"
|
||||
#include "webrtc/p2p/base/transportdescriptionfactory.h"
|
||||
#include "webrtc/base/sigslot.h"
|
||||
#include "webrtc/base/thread.h"
|
||||
|
||||
namespace buzz {
|
||||
class QName;
|
||||
class XmlElement;
|
||||
}
|
||||
|
||||
namespace cricket {
|
||||
|
||||
class BaseSession;
|
||||
class SessionClient;
|
||||
class SessionManager;
|
||||
|
||||
// Used for errors that will send back a specific error message to the
|
||||
// remote peer. We add "type" to the errors because it's needed for
|
||||
// SignalErrorMessage.
|
||||
struct MessageError : ParseError {
|
||||
buzz::QName type;
|
||||
|
||||
// if unset, assume type is a parse error
|
||||
MessageError() : ParseError(), type(buzz::QN_STANZA_BAD_REQUEST) {}
|
||||
|
||||
void SetType(const buzz::QName type) {
|
||||
this->type = type;
|
||||
}
|
||||
};
|
||||
|
||||
// Used for errors that may be returned by public session methods that
|
||||
// can fail.
|
||||
// TODO: Use this error in Session::Initiate and
|
||||
// Session::Accept.
|
||||
struct SessionError : WriteError {
|
||||
};
|
||||
|
||||
// A specific Session created by the SessionManager, using XMPP for protocol.
|
||||
class Session : public BaseSession {
|
||||
public:
|
||||
// Returns the manager that created and owns this session.
|
||||
SessionManager* session_manager() const { return session_manager_; }
|
||||
|
||||
// Returns the client that is handling the application data of this session.
|
||||
SessionClient* client() const { return client_; }
|
||||
|
||||
// Returns the JID of this client.
|
||||
const std::string& local_name() const { return local_name_; }
|
||||
|
||||
// Returns the JID of the other peer in this session.
|
||||
const std::string& remote_name() const { return remote_name_; }
|
||||
|
||||
// Set the JID of the other peer in this session.
|
||||
// Typically the remote_name_ is set when the session is initiated.
|
||||
// However, sometimes (e.g when a proxy is used) the peer name is
|
||||
// known after the BaseSession has been initiated and it must be updated
|
||||
// explicitly.
|
||||
void set_remote_name(const std::string& name) { remote_name_ = name; }
|
||||
|
||||
// Set the JID of the initiator of this session. Allows for the overriding
|
||||
// of the initiator to be a third-party, eg. the MUC JID when creating p2p
|
||||
// sessions.
|
||||
void set_initiator_name(const std::string& name) { initiator_name_ = name; }
|
||||
|
||||
// Indicates the JID of the entity who initiated this session.
|
||||
// In special cases, may be different than both local_name and remote_name.
|
||||
const std::string& initiator_name() const { return initiator_name_; }
|
||||
|
||||
SignalingProtocol current_protocol() const { return current_protocol_; }
|
||||
|
||||
void set_current_protocol(SignalingProtocol protocol) {
|
||||
current_protocol_ = protocol;
|
||||
}
|
||||
|
||||
// Updates the error state, signaling if necessary.
|
||||
virtual void SetError(Error error, const std::string& error_desc);
|
||||
|
||||
// When the session needs to send signaling messages, it beings by requesting
|
||||
// signaling. The client should handle this by calling OnSignalingReady once
|
||||
// it is ready to send the messages.
|
||||
// (These are called only by SessionManager.)
|
||||
sigslot::signal1<Session*> SignalRequestSignaling;
|
||||
void OnSignalingReady() { BaseSession::OnSignalingReady(); }
|
||||
|
||||
// Takes ownership of session description.
|
||||
// TODO: Add an error argument to pass back to the caller.
|
||||
bool Initiate(const std::string& to,
|
||||
const SessionDescription* sdesc);
|
||||
|
||||
// When we receive an initiate, we create a session in the
|
||||
// RECEIVEDINITIATE state and respond by accepting or rejecting.
|
||||
// Takes ownership of session description.
|
||||
// TODO: Add an error argument to pass back to the caller.
|
||||
bool Accept(const SessionDescription* sdesc);
|
||||
bool Reject(const std::string& reason);
|
||||
bool Terminate() {
|
||||
return TerminateWithReason(STR_TERMINATE_SUCCESS);
|
||||
}
|
||||
bool TerminateWithReason(const std::string& reason);
|
||||
// Fired whenever we receive a terminate message along with a reason
|
||||
sigslot::signal2<Session*, const std::string&> SignalReceivedTerminateReason;
|
||||
|
||||
// The two clients in the session may also send one another
|
||||
// arbitrary XML messages, which are called "info" messages. Sending
|
||||
// takes ownership of the given elements. The signal does not; the
|
||||
// parent element will be deleted after the signal.
|
||||
bool SendInfoMessage(const XmlElements& elems,
|
||||
const std::string& remote_name);
|
||||
bool SendDescriptionInfoMessage(const ContentInfos& contents);
|
||||
sigslot::signal2<Session*, const buzz::XmlElement*> SignalInfoMessage;
|
||||
|
||||
private:
|
||||
// Creates or destroys a session. (These are called only SessionManager.)
|
||||
Session(SessionManager *session_manager,
|
||||
const std::string& local_name, const std::string& initiator_name,
|
||||
const std::string& sid, const std::string& content_type,
|
||||
SessionClient* client);
|
||||
~Session();
|
||||
// For each transport info, create a transport proxy. Can fail for
|
||||
// incompatible transport types.
|
||||
bool CreateTransportProxies(const TransportInfos& tinfos,
|
||||
SessionError* error);
|
||||
bool OnRemoteCandidates(const TransportInfos& tinfos,
|
||||
ParseError* error);
|
||||
// Returns a TransportInfo without candidates for each content name.
|
||||
// Uses the transport_type_ of the session.
|
||||
TransportInfos GetEmptyTransportInfos(const ContentInfos& contents) const;
|
||||
|
||||
// Maps passed to serialization functions.
|
||||
TransportParserMap GetTransportParsers();
|
||||
ContentParserMap GetContentParsers();
|
||||
CandidateTranslatorMap GetCandidateTranslators();
|
||||
|
||||
virtual void OnTransportRequestSignaling(Transport* transport);
|
||||
virtual void OnTransportConnecting(Transport* transport);
|
||||
virtual void OnTransportWritable(Transport* transport);
|
||||
virtual void OnTransportProxyCandidatesReady(TransportProxy* proxy,
|
||||
const Candidates& candidates);
|
||||
virtual void OnMessage(rtc::Message *pmsg);
|
||||
|
||||
// Send various kinds of session messages.
|
||||
bool SendInitiateMessage(const SessionDescription* sdesc,
|
||||
SessionError* error);
|
||||
bool SendAcceptMessage(const SessionDescription* sdesc, SessionError* error);
|
||||
bool SendRejectMessage(const std::string& reason, SessionError* error);
|
||||
bool SendTerminateMessage(const std::string& reason, SessionError* error);
|
||||
bool SendTransportInfoMessage(const TransportInfo& tinfo,
|
||||
SessionError* error);
|
||||
bool SendTransportInfoMessage(const TransportProxy* transproxy,
|
||||
const Candidates& candidates,
|
||||
SessionError* error);
|
||||
|
||||
bool ResendAllTransportInfoMessages(SessionError* error);
|
||||
bool SendAllUnsentTransportInfoMessages(SessionError* error);
|
||||
|
||||
// All versions of SendMessage send a message of the given type to
|
||||
// the other client. Can pass either a set of elements or an
|
||||
// "action", which must have a WriteSessionAction method to go along
|
||||
// with it. Sending with an action supports sending a "hybrid"
|
||||
// message. Sending with elements must be sent as Jingle or Gingle.
|
||||
|
||||
// When passing elems, must be either Jingle or Gingle protocol.
|
||||
// Takes ownership of action_elems.
|
||||
bool SendMessage(ActionType type, const XmlElements& action_elems,
|
||||
SessionError* error);
|
||||
// Sends a messge, but overrides the remote name.
|
||||
bool SendMessage(ActionType type, const XmlElements& action_elems,
|
||||
const std::string& remote_name,
|
||||
SessionError* error);
|
||||
// When passing an action, may be Hybrid protocol.
|
||||
template <typename Action>
|
||||
bool SendMessage(ActionType type, const Action& action,
|
||||
SessionError* error);
|
||||
|
||||
// Helper methods to write the session message stanza.
|
||||
template <typename Action>
|
||||
bool WriteActionMessage(ActionType type, const Action& action,
|
||||
buzz::XmlElement* stanza, WriteError* error);
|
||||
template <typename Action>
|
||||
bool WriteActionMessage(SignalingProtocol protocol,
|
||||
ActionType type, const Action& action,
|
||||
buzz::XmlElement* stanza, WriteError* error);
|
||||
|
||||
// Sending messages in hybrid form requires being able to write them
|
||||
// on a per-protocol basis with a common method signature, which all
|
||||
// of these have.
|
||||
bool WriteSessionAction(SignalingProtocol protocol,
|
||||
const SessionInitiate& init,
|
||||
XmlElements* elems, WriteError* error);
|
||||
bool WriteSessionAction(SignalingProtocol protocol,
|
||||
const TransportInfo& tinfo,
|
||||
XmlElements* elems, WriteError* error);
|
||||
bool WriteSessionAction(SignalingProtocol protocol,
|
||||
const SessionTerminate& term,
|
||||
XmlElements* elems, WriteError* error);
|
||||
|
||||
// Sends a message back to the other client indicating that we have received
|
||||
// and accepted their message.
|
||||
void SendAcknowledgementMessage(const buzz::XmlElement* stanza);
|
||||
|
||||
// Once signaling is ready, the session will use this signal to request the
|
||||
// sending of each message. When messages are received by the other client,
|
||||
// they should be handed to OnIncomingMessage.
|
||||
// (These are called only by SessionManager.)
|
||||
sigslot::signal2<Session* , const buzz::XmlElement*> SignalOutgoingMessage;
|
||||
void OnIncomingMessage(const SessionMessage& msg);
|
||||
|
||||
void OnIncomingResponse(const buzz::XmlElement* orig_stanza,
|
||||
const buzz::XmlElement* response_stanza,
|
||||
const SessionMessage& msg);
|
||||
void OnInitiateAcked();
|
||||
void OnFailedSend(const buzz::XmlElement* orig_stanza,
|
||||
const buzz::XmlElement* error_stanza);
|
||||
|
||||
// Invoked when an error is found in an incoming message. This is translated
|
||||
// into the appropriate XMPP response by SessionManager.
|
||||
sigslot::signal6<BaseSession*,
|
||||
const buzz::XmlElement*,
|
||||
const buzz::QName&,
|
||||
const std::string&,
|
||||
const std::string&,
|
||||
const buzz::XmlElement*> SignalErrorMessage;
|
||||
|
||||
// Handlers for the various types of messages. These functions may take
|
||||
// pointers to the whole stanza or to just the session element.
|
||||
bool OnInitiateMessage(const SessionMessage& msg, MessageError* error);
|
||||
bool OnAcceptMessage(const SessionMessage& msg, MessageError* error);
|
||||
bool OnRejectMessage(const SessionMessage& msg, MessageError* error);
|
||||
bool OnInfoMessage(const SessionMessage& msg);
|
||||
bool OnTerminateMessage(const SessionMessage& msg, MessageError* error);
|
||||
bool OnTransportInfoMessage(const SessionMessage& msg, MessageError* error);
|
||||
bool OnTransportAcceptMessage(const SessionMessage& msg, MessageError* error);
|
||||
bool OnDescriptionInfoMessage(const SessionMessage& msg, MessageError* error);
|
||||
bool OnRedirectError(const SessionRedirect& redirect, SessionError* error);
|
||||
|
||||
// Verifies that we are in the appropriate state to receive this message.
|
||||
bool CheckState(State state, MessageError* error);
|
||||
|
||||
SessionManager* session_manager_;
|
||||
bool initiate_acked_;
|
||||
std::string local_name_;
|
||||
std::string initiator_name_;
|
||||
std::string remote_name_;
|
||||
SessionClient* client_;
|
||||
TransportParser* transport_parser_;
|
||||
// Keeps track of what protocol we are speaking.
|
||||
SignalingProtocol current_protocol_;
|
||||
|
||||
friend class SessionManager; // For access to constructor, destructor,
|
||||
// and signaling related methods.
|
||||
};
|
||||
|
||||
// SessionManager manages session instances.
|
||||
class SessionManager : public sigslot::has_slots<> {
|
||||
public:
|
||||
SessionManager(PortAllocator *allocator,
|
||||
rtc::Thread *worker_thread = NULL);
|
||||
virtual ~SessionManager();
|
||||
|
||||
PortAllocator *port_allocator() const { return allocator_; }
|
||||
rtc::Thread *worker_thread() const { return worker_thread_; }
|
||||
rtc::Thread *signaling_thread() const { return signaling_thread_; }
|
||||
|
||||
int session_timeout() const { return timeout_; }
|
||||
void set_session_timeout(int timeout) { timeout_ = timeout; }
|
||||
|
||||
// Set what transport protocol we want to default to.
|
||||
void set_transport_protocol(TransportProtocol proto) {
|
||||
transport_desc_factory_.set_protocol(proto);
|
||||
}
|
||||
|
||||
// Control use of DTLS. An identity must be supplied if DTLS is enabled.
|
||||
void set_secure(SecurePolicy policy) {
|
||||
transport_desc_factory_.set_secure(policy);
|
||||
}
|
||||
void set_identity(rtc::SSLIdentity* identity) {
|
||||
transport_desc_factory_.set_identity(identity);
|
||||
}
|
||||
const TransportDescriptionFactory* transport_desc_factory() const {
|
||||
return &transport_desc_factory_;
|
||||
}
|
||||
|
||||
// Registers support for the given client. If we receive an initiate
|
||||
// describing a session of the given type, we will automatically create a
|
||||
// Session object and notify this client. The client may then accept or
|
||||
// reject the session.
|
||||
void AddClient(const std::string& content_type, SessionClient* client);
|
||||
void RemoveClient(const std::string& content_type);
|
||||
SessionClient* GetClient(const std::string& content_type);
|
||||
|
||||
// Creates a new session. The given name is the JID of the client on whose
|
||||
// behalf we initiate the session.
|
||||
Session *CreateSession(const std::string& local_name,
|
||||
const std::string& content_type);
|
||||
|
||||
Session *CreateSession(const std::string& id,
|
||||
const std::string& local_name,
|
||||
const std::string& content_type);
|
||||
|
||||
// Destroys the given session.
|
||||
void DestroySession(Session *session);
|
||||
|
||||
// Returns the session with the given ID or NULL if none exists.
|
||||
Session *GetSession(const std::string& sid);
|
||||
|
||||
// Terminates all of the sessions created by this manager.
|
||||
void TerminateAll();
|
||||
|
||||
// These are signaled whenever the set of existing sessions changes.
|
||||
sigslot::signal2<Session *, bool> SignalSessionCreate;
|
||||
sigslot::signal1<Session *> SignalSessionDestroy;
|
||||
|
||||
// Determines whether the given stanza is intended for some session.
|
||||
bool IsSessionMessage(const buzz::XmlElement* stanza);
|
||||
|
||||
// Given a sid, initiator, and remote_name, this finds the matching Session
|
||||
Session* FindSession(const std::string& sid,
|
||||
const std::string& remote_name);
|
||||
|
||||
// Called when we receive a stanza for which IsSessionMessage is true.
|
||||
void OnIncomingMessage(const buzz::XmlElement* stanza);
|
||||
|
||||
// Called when we get a response to a message that we sent.
|
||||
void OnIncomingResponse(const buzz::XmlElement* orig_stanza,
|
||||
const buzz::XmlElement* response_stanza);
|
||||
|
||||
// Called if an attempted to send times out or an error is returned. In the
|
||||
// timeout case error_stanza will be NULL
|
||||
void OnFailedSend(const buzz::XmlElement* orig_stanza,
|
||||
const buzz::XmlElement* error_stanza);
|
||||
|
||||
// Signalled each time a session generates a signaling message to send.
|
||||
// Also signalled on errors, but with a NULL session.
|
||||
sigslot::signal2<SessionManager*,
|
||||
const buzz::XmlElement*> SignalOutgoingMessage;
|
||||
|
||||
// Signaled before sessions try to send certain signaling messages. The
|
||||
// client should call OnSignalingReady once it is safe to send them. These
|
||||
// steps are taken so that we don't send signaling messages trying to
|
||||
// re-establish the connectivity of a session when the client cannot send
|
||||
// the messages (and would probably just drop them on the floor).
|
||||
//
|
||||
// Note: you can connect this directly to OnSignalingReady(), if a signalling
|
||||
// check is not supported.
|
||||
sigslot::signal0<> SignalRequestSignaling;
|
||||
void OnSignalingReady();
|
||||
|
||||
// Signaled when this SessionManager is deleted.
|
||||
sigslot::signal0<> SignalDestroyed;
|
||||
|
||||
private:
|
||||
typedef std::map<std::string, Session*> SessionMap;
|
||||
typedef std::map<std::string, SessionClient*> ClientMap;
|
||||
|
||||
// Helper function for CreateSession. This is also invoked when we receive
|
||||
// a message attempting to initiate a session with this client.
|
||||
Session *CreateSession(const std::string& local_name,
|
||||
const std::string& initiator,
|
||||
const std::string& sid,
|
||||
const std::string& content_type,
|
||||
bool received_initiate);
|
||||
|
||||
// Attempts to find a registered session type whose description appears as
|
||||
// a child of the session element. Such a child should be present indicating
|
||||
// the application they hope to initiate.
|
||||
std::string FindClient(const buzz::XmlElement* session);
|
||||
|
||||
// Sends a message back to the other client indicating that we found an error
|
||||
// in the stanza they sent. name identifies the error, type is one of the
|
||||
// standard XMPP types (cancel, continue, modify, auth, wait), and text is a
|
||||
// description for debugging purposes.
|
||||
void SendErrorMessage(const buzz::XmlElement* stanza,
|
||||
const buzz::QName& name,
|
||||
const std::string& type,
|
||||
const std::string& text,
|
||||
const buzz::XmlElement* extra_info);
|
||||
|
||||
// Creates and returns an error message from the given components. The
|
||||
// caller is responsible for deleting this.
|
||||
buzz::XmlElement* CreateErrorMessage(
|
||||
const buzz::XmlElement* stanza,
|
||||
const buzz::QName& name,
|
||||
const std::string& type,
|
||||
const std::string& text,
|
||||
const buzz::XmlElement* extra_info);
|
||||
|
||||
// Called each time a session requests signaling.
|
||||
void OnRequestSignaling(Session* session);
|
||||
|
||||
// Called each time a session has an outgoing message.
|
||||
void OnOutgoingMessage(Session* session, const buzz::XmlElement* stanza);
|
||||
|
||||
// Called each time a session has an error to send.
|
||||
void OnErrorMessage(BaseSession* session,
|
||||
const buzz::XmlElement* stanza,
|
||||
const buzz::QName& name,
|
||||
const std::string& type,
|
||||
const std::string& text,
|
||||
const buzz::XmlElement* extra_info);
|
||||
|
||||
PortAllocator *allocator_;
|
||||
rtc::Thread *signaling_thread_;
|
||||
rtc::Thread *worker_thread_;
|
||||
int timeout_;
|
||||
TransportDescriptionFactory transport_desc_factory_;
|
||||
SessionMap session_map_;
|
||||
ClientMap client_map_;
|
||||
};
|
||||
|
||||
} // namespace cricket
|
||||
|
||||
#endif // WEBRTC_P2P_BASE_SESSIONMANAGER_H_
|
||||
// TODO(pthatcher): Delete this file once Chromium no longer trys to build it.
|
||||
|
@ -15,14 +15,15 @@
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "webrtc/base/basictypes.h"
|
||||
#include "webrtc/p2p/base/candidate.h"
|
||||
#include "webrtc/p2p/base/constants.h"
|
||||
#include "webrtc/p2p/base/parsing.h"
|
||||
#include "webrtc/p2p/base/sessiondescription.h" // Needed to delete contents.
|
||||
#include "webrtc/p2p/base/transport.h"
|
||||
#include "webrtc/p2p/base/transportinfo.h"
|
||||
#include "webrtc/libjingle/session/transportparser.h"
|
||||
#include "webrtc/libjingle/xmllite/xmlelement.h"
|
||||
#include "webrtc/base/basictypes.h"
|
||||
|
||||
namespace cricket {
|
||||
|
||||
|
@ -12,12 +12,8 @@
|
||||
|
||||
#include "webrtc/p2p/base/candidate.h"
|
||||
#include "webrtc/p2p/base/constants.h"
|
||||
#include "webrtc/p2p/base/parsing.h"
|
||||
#include "webrtc/p2p/base/port.h"
|
||||
#include "webrtc/p2p/base/sessionmanager.h"
|
||||
#include "webrtc/p2p/base/transportchannelimpl.h"
|
||||
#include "webrtc/libjingle/xmllite/xmlelement.h"
|
||||
#include "webrtc/libjingle/xmpp/constants.h"
|
||||
#include "webrtc/base/bind.h"
|
||||
#include "webrtc/base/common.h"
|
||||
#include "webrtc/base/logging.h"
|
||||
@ -931,25 +927,6 @@ void Transport::OnMessage(rtc::Message* msg) {
|
||||
}
|
||||
}
|
||||
|
||||
bool TransportParser::ParseAddress(const buzz::XmlElement* elem,
|
||||
const buzz::QName& address_name,
|
||||
const buzz::QName& port_name,
|
||||
rtc::SocketAddress* address,
|
||||
ParseError* error) {
|
||||
if (!elem->HasAttr(address_name))
|
||||
return BadParse("address does not have " + address_name.LocalPart(), error);
|
||||
if (!elem->HasAttr(port_name))
|
||||
return BadParse("address does not have " + port_name.LocalPart(), error);
|
||||
|
||||
address->SetIP(elem->Attr(address_name));
|
||||
std::istringstream ist(elem->Attr(port_name));
|
||||
int port = 0;
|
||||
ist >> port;
|
||||
address->SetPort(port);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// We're GICE if the namespace is NS_GOOGLE_P2P, or if NS_JINGLE_ICE_UDP is
|
||||
// used and the GICE ice-option is set.
|
||||
TransportProtocol TransportProtocolFromDescription(
|
||||
|
@ -45,71 +45,14 @@ namespace rtc {
|
||||
class Thread;
|
||||
}
|
||||
|
||||
namespace buzz {
|
||||
class QName;
|
||||
class XmlElement;
|
||||
}
|
||||
|
||||
namespace cricket {
|
||||
|
||||
struct ParseError;
|
||||
struct WriteError;
|
||||
class CandidateTranslator;
|
||||
class PortAllocator;
|
||||
class TransportChannel;
|
||||
class TransportChannelImpl;
|
||||
|
||||
typedef std::vector<buzz::XmlElement*> XmlElements;
|
||||
typedef std::vector<Candidate> Candidates;
|
||||
|
||||
// Used to parse and serialize (write) transport candidates. For
|
||||
// convenience of old code, Transports will implement TransportParser.
|
||||
// Parse/Write seems better than Serialize/Deserialize or
|
||||
// Create/Translate.
|
||||
class TransportParser {
|
||||
public:
|
||||
// The incoming Translator value may be null, in which case
|
||||
// ParseCandidates should return false if there are candidates to
|
||||
// parse (indicating a failure to parse). If the Translator is null
|
||||
// and there are no candidates to parse, then return true,
|
||||
// indicating a successful parse of 0 candidates.
|
||||
|
||||
// Parse or write a transport description, including ICE credentials and
|
||||
// any DTLS fingerprint. Since only Jingle has transport descriptions, these
|
||||
// functions are only used when serializing to Jingle.
|
||||
virtual bool ParseTransportDescription(const buzz::XmlElement* elem,
|
||||
const CandidateTranslator* translator,
|
||||
TransportDescription* tdesc,
|
||||
ParseError* error) = 0;
|
||||
virtual bool WriteTransportDescription(const TransportDescription& tdesc,
|
||||
const CandidateTranslator* translator,
|
||||
buzz::XmlElement** tdesc_elem,
|
||||
WriteError* error) = 0;
|
||||
|
||||
|
||||
// Parse a single candidate. This must be used when parsing Gingle
|
||||
// candidates, since there is no enclosing transport description.
|
||||
virtual bool ParseGingleCandidate(const buzz::XmlElement* elem,
|
||||
const CandidateTranslator* translator,
|
||||
Candidate* candidates,
|
||||
ParseError* error) = 0;
|
||||
virtual bool WriteGingleCandidate(const Candidate& candidate,
|
||||
const CandidateTranslator* translator,
|
||||
buzz::XmlElement** candidate_elem,
|
||||
WriteError* error) = 0;
|
||||
|
||||
// Helper function to parse an element describing an address. This
|
||||
// retrieves the IP and port from the given element and verifies
|
||||
// that they look like plausible values.
|
||||
bool ParseAddress(const buzz::XmlElement* elem,
|
||||
const buzz::QName& address_name,
|
||||
const buzz::QName& port_name,
|
||||
rtc::SocketAddress* address,
|
||||
ParseError* error);
|
||||
|
||||
virtual ~TransportParser() {}
|
||||
};
|
||||
|
||||
// For "writable" and "readable", we need to differentiate between
|
||||
// none, all, and some.
|
||||
enum TransportState {
|
||||
@ -314,18 +257,6 @@ class Transport : public rtc::MessageHandler,
|
||||
int, // component
|
||||
const Candidate&> SignalRouteChange;
|
||||
|
||||
// A transport message has generated an transport-specific error. The
|
||||
// stanza that caused the error is available in session_msg. If false is
|
||||
// returned, the error is considered unrecoverable, and the session is
|
||||
// terminated.
|
||||
// TODO(juberti): Remove these obsolete functions once Session no longer
|
||||
// references them.
|
||||
virtual void OnTransportError(const buzz::XmlElement* error) {}
|
||||
sigslot::signal6<Transport*, const buzz::XmlElement*, const buzz::QName&,
|
||||
const std::string&, const std::string&,
|
||||
const buzz::XmlElement*>
|
||||
SignalTransportError;
|
||||
|
||||
// Forwards the signal from TransportChannel to BaseSession.
|
||||
sigslot::signal0<> SignalRoleConflict;
|
||||
|
||||
|
@ -8,18 +8,12 @@
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
#include "webrtc/p2p/base/constants.h"
|
||||
#include "webrtc/p2p/base/fakesession.h"
|
||||
#include "webrtc/p2p/base/p2ptransport.h"
|
||||
#include "webrtc/p2p/base/parsing.h"
|
||||
#include "webrtc/p2p/base/rawtransport.h"
|
||||
#include "webrtc/p2p/base/sessionmessages.h"
|
||||
#include "webrtc/libjingle/xmllite/xmlelement.h"
|
||||
#include "webrtc/libjingle/xmpp/constants.h"
|
||||
#include "webrtc/base/fakesslidentity.h"
|
||||
#include "webrtc/base/gunit.h"
|
||||
#include "webrtc/base/network.h"
|
||||
#include "webrtc/base/thread.h"
|
||||
#include "webrtc/p2p/base/fakesession.h"
|
||||
#include "webrtc/p2p/base/p2ptransport.h"
|
||||
|
||||
using cricket::Candidate;
|
||||
using cricket::Candidates;
|
||||
@ -29,8 +23,6 @@ using cricket::TransportChannel;
|
||||
using cricket::FakeTransportChannel;
|
||||
using cricket::IceRole;
|
||||
using cricket::TransportDescription;
|
||||
using cricket::WriteError;
|
||||
using cricket::ParseError;
|
||||
using rtc::SocketAddress;
|
||||
|
||||
static const char kIceUfrag1[] = "TESTICEUFRAG0001";
|
||||
@ -89,34 +81,6 @@ class TransportTest : public testing::Test,
|
||||
bool failed_;
|
||||
};
|
||||
|
||||
class FakeCandidateTranslator : public cricket::CandidateTranslator {
|
||||
public:
|
||||
void AddMapping(int component, const std::string& channel_name) {
|
||||
name_to_component[channel_name] = component;
|
||||
component_to_name[component] = channel_name;
|
||||
}
|
||||
|
||||
bool GetChannelNameFromComponent(
|
||||
int component, std::string* channel_name) const {
|
||||
if (component_to_name.find(component) == component_to_name.end()) {
|
||||
return false;
|
||||
}
|
||||
*channel_name = component_to_name.find(component)->second;
|
||||
return true;
|
||||
}
|
||||
bool GetComponentFromChannelName(
|
||||
const std::string& channel_name, int* component) const {
|
||||
if (name_to_component.find(channel_name) == name_to_component.end()) {
|
||||
return false;
|
||||
}
|
||||
*component = name_to_component.find(channel_name)->second;
|
||||
return true;
|
||||
}
|
||||
|
||||
std::map<std::string, int> name_to_component;
|
||||
std::map<int, std::string> component_to_name;
|
||||
};
|
||||
|
||||
// Test that calling ConnectChannels triggers an OnConnecting signal.
|
||||
TEST_F(TransportTest, TestConnectChannelsDoesSignal) {
|
||||
EXPECT_TRUE(SetupChannel());
|
||||
@ -345,86 +309,6 @@ TEST_F(TransportTest, TestSetRemoteIceLiteInAnswer) {
|
||||
EXPECT_EQ(cricket::ICEMODE_LITE, channel_->remote_ice_mode());
|
||||
}
|
||||
|
||||
// Tests that we can properly serialize/deserialize candidates.
|
||||
TEST_F(TransportTest, TestP2PTransportWriteAndParseCandidate) {
|
||||
Candidate test_candidate("", 1, "udp",
|
||||
rtc::SocketAddress("2001:db8:fefe::1", 9999),
|
||||
738197504, "abcdef", "ghijkl", "foo", 50, "");
|
||||
test_candidate.set_network_name("testnet");
|
||||
Candidate test_candidate2("", 2, "tcp",
|
||||
rtc::SocketAddress("192.168.7.1", 9999), 1107296256,
|
||||
"mnopqr", "stuvwx", "bar", 100, "");
|
||||
test_candidate2.set_network_name("testnet2");
|
||||
rtc::SocketAddress host_address("www.google.com", 24601);
|
||||
host_address.SetResolvedIP(rtc::IPAddress(0x0A000001));
|
||||
Candidate test_candidate3("", 3, "spdy", host_address, 1476395008, "yzabcd",
|
||||
"efghij", "baz", 150, "");
|
||||
test_candidate3.set_network_name("testnet3");
|
||||
WriteError write_error;
|
||||
ParseError parse_error;
|
||||
rtc::scoped_ptr<buzz::XmlElement> elem;
|
||||
cricket::Candidate parsed_candidate;
|
||||
cricket::P2PTransportParser parser;
|
||||
|
||||
FakeCandidateTranslator translator;
|
||||
translator.AddMapping(1, "test");
|
||||
translator.AddMapping(2, "test2");
|
||||
translator.AddMapping(3, "test3");
|
||||
|
||||
EXPECT_TRUE(parser.WriteGingleCandidate(test_candidate, &translator,
|
||||
elem.accept(), &write_error));
|
||||
EXPECT_EQ("", write_error.text);
|
||||
EXPECT_EQ("test", elem->Attr(buzz::QN_NAME));
|
||||
EXPECT_EQ("udp", elem->Attr(cricket::QN_PROTOCOL));
|
||||
EXPECT_EQ("2001:db8:fefe::1", elem->Attr(cricket::QN_ADDRESS));
|
||||
EXPECT_EQ("9999", elem->Attr(cricket::QN_PORT));
|
||||
EXPECT_EQ("0.34", elem->Attr(cricket::QN_PREFERENCE));
|
||||
EXPECT_EQ("abcdef", elem->Attr(cricket::QN_USERNAME));
|
||||
EXPECT_EQ("ghijkl", elem->Attr(cricket::QN_PASSWORD));
|
||||
EXPECT_EQ("foo", elem->Attr(cricket::QN_TYPE));
|
||||
EXPECT_EQ("testnet", elem->Attr(cricket::QN_NETWORK));
|
||||
EXPECT_EQ("50", elem->Attr(cricket::QN_GENERATION));
|
||||
|
||||
EXPECT_TRUE(parser.ParseGingleCandidate(elem.get(), &translator,
|
||||
&parsed_candidate, &parse_error));
|
||||
EXPECT_TRUE(test_candidate.IsEquivalent(parsed_candidate));
|
||||
|
||||
EXPECT_TRUE(parser.WriteGingleCandidate(test_candidate2, &translator,
|
||||
elem.accept(), &write_error));
|
||||
EXPECT_EQ("test2", elem->Attr(buzz::QN_NAME));
|
||||
EXPECT_EQ("tcp", elem->Attr(cricket::QN_PROTOCOL));
|
||||
EXPECT_EQ("192.168.7.1", elem->Attr(cricket::QN_ADDRESS));
|
||||
EXPECT_EQ("9999", elem->Attr(cricket::QN_PORT));
|
||||
EXPECT_EQ("0.51", elem->Attr(cricket::QN_PREFERENCE));
|
||||
EXPECT_EQ("mnopqr", elem->Attr(cricket::QN_USERNAME));
|
||||
EXPECT_EQ("stuvwx", elem->Attr(cricket::QN_PASSWORD));
|
||||
EXPECT_EQ("bar", elem->Attr(cricket::QN_TYPE));
|
||||
EXPECT_EQ("testnet2", elem->Attr(cricket::QN_NETWORK));
|
||||
EXPECT_EQ("100", elem->Attr(cricket::QN_GENERATION));
|
||||
|
||||
EXPECT_TRUE(parser.ParseGingleCandidate(elem.get(), &translator,
|
||||
&parsed_candidate, &parse_error));
|
||||
EXPECT_TRUE(test_candidate2.IsEquivalent(parsed_candidate));
|
||||
|
||||
// Check that an ip is preferred over hostname.
|
||||
EXPECT_TRUE(parser.WriteGingleCandidate(test_candidate3, &translator,
|
||||
elem.accept(), &write_error));
|
||||
EXPECT_EQ("test3", elem->Attr(cricket::QN_NAME));
|
||||
EXPECT_EQ("spdy", elem->Attr(cricket::QN_PROTOCOL));
|
||||
EXPECT_EQ("10.0.0.1", elem->Attr(cricket::QN_ADDRESS));
|
||||
EXPECT_EQ("24601", elem->Attr(cricket::QN_PORT));
|
||||
EXPECT_EQ("0.69", elem->Attr(cricket::QN_PREFERENCE));
|
||||
EXPECT_EQ("yzabcd", elem->Attr(cricket::QN_USERNAME));
|
||||
EXPECT_EQ("efghij", elem->Attr(cricket::QN_PASSWORD));
|
||||
EXPECT_EQ("baz", elem->Attr(cricket::QN_TYPE));
|
||||
EXPECT_EQ("testnet3", elem->Attr(cricket::QN_NETWORK));
|
||||
EXPECT_EQ("150", elem->Attr(cricket::QN_GENERATION));
|
||||
|
||||
EXPECT_TRUE(parser.ParseGingleCandidate(elem.get(), &translator,
|
||||
&parsed_candidate, &parse_error));
|
||||
EXPECT_TRUE(test_candidate3.IsEquivalent(parsed_candidate));
|
||||
}
|
||||
|
||||
TEST_F(TransportTest, TestGetStats) {
|
||||
EXPECT_TRUE(SetupChannel());
|
||||
cricket::TransportStats stats;
|
||||
|
@ -11,10 +11,10 @@
|
||||
#ifndef WEBRTC_P2P_CLIENT_SESSIONMANAGERTASK_H_
|
||||
#define WEBRTC_P2P_CLIENT_SESSIONMANAGERTASK_H_
|
||||
|
||||
#include "webrtc/p2p/base/sessionmanager.h"
|
||||
#include "webrtc/p2p/client/sessionsendtask.h"
|
||||
#include "webrtc/libjingle/session/sessionmanager.h"
|
||||
#include "webrtc/libjingle/xmpp/xmppengine.h"
|
||||
#include "webrtc/libjingle/xmpp/xmpptask.h"
|
||||
#include "webrtc/p2p/client/sessionsendtask.h"
|
||||
|
||||
namespace cricket {
|
||||
|
||||
|
@ -11,7 +11,7 @@
|
||||
#ifndef WEBRTC_P2P_CLIENT_SESSIONSENDTASK_H_
|
||||
#define WEBRTC_P2P_CLIENT_SESSIONSENDTASK_H_
|
||||
|
||||
#include "webrtc/p2p/base/sessionmanager.h"
|
||||
#include "webrtc/libjingle/session/sessionmanager.h"
|
||||
#include "webrtc/libjingle/xmpp/constants.h"
|
||||
#include "webrtc/libjingle/xmpp/xmppclient.h"
|
||||
#include "webrtc/libjingle/xmpp/xmppengine.h"
|
||||
|
@ -66,8 +66,6 @@
|
||||
'base/sessiondescription.cc',
|
||||
'base/sessiondescription.h',
|
||||
'base/sessionid.h',
|
||||
'base/sessionmanager.cc',
|
||||
'base/sessionmanager.h',
|
||||
'base/sessionmessages.cc',
|
||||
'base/sessionmessages.h',
|
||||
'base/stun.cc',
|
||||
|
@ -22,7 +22,6 @@
|
||||
'base/pseudotcp_unittest.cc',
|
||||
'base/relayport_unittest.cc',
|
||||
'base/relayserver_unittest.cc',
|
||||
'base/session_unittest.cc',
|
||||
'base/stun_unittest.cc',
|
||||
'base/stunport_unittest.cc',
|
||||
'base/stunrequest_unittest.cc',
|
||||
|
Loading…
x
Reference in New Issue
Block a user