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:
pthatcher@webrtc.org 2014-12-19 03:32:59 +00:00
parent 0c39e91cc8
commit 5647877b2d
37 changed files with 2320 additions and 2183 deletions

View File

@ -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',

View File

@ -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',

View File

@ -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 {

View File

@ -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 {

View File

@ -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',

View 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

View 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_

View 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)

View 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_

View File

@ -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;

File diff suppressed because it is too large Load Diff

View 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_

View 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

View 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_

View 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));
}

View File

@ -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_

View File

@ -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_

View File

@ -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 {

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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

View File

@ -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_

View File

@ -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(),

View File

@ -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);

View File

@ -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)

View File

@ -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

View File

@ -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.

View File

@ -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 {

View File

@ -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(

View File

@ -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;

View File

@ -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;

View File

@ -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 {

View File

@ -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"

View File

@ -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',

View File

@ -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',