⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 tunnelsessionclient.cc

📁 本人收集整理的一份c/c++跨平台网络库
💻 CC
字号:
/* * libjingle * Copyright 2004--2006, Google Inc. * * Redistribution and use in source and binary forms, with or without  * modification, are permitted provided that the following conditions are met: * *  1. Redistributions of source code must retain the above copyright notice,  *     this list of conditions and the following disclaimer. *  2. Redistributions in binary form must reproduce the above copyright notice, *     this list of conditions and the following disclaimer in the documentation *     and/or other materials provided with the distribution. *  3. The name of the author may not be used to endorse or promote products  *     derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */#include "talk/base/basicdefs.h"#include "talk/base/basictypes.h"#include "talk/base/common.h"#include "talk/base/helpers.h"#include "talk/base/logging.h"#include "talk/base/stringutils.h"#include "talk/p2p/base/transportchannel.h"#include "talk/xmllite/xmlelement.h"#include "pseudotcpchannel.h"#include "tunnelsessionclient.h"namespace cricket {const std::string NS_TUNNEL("http://www.google.com/talk/tunnel");const buzz::QName QN_TUNNEL_DESCRIPTION(NS_TUNNEL, "description");const buzz::QName QN_TUNNEL_TYPE(NS_TUNNEL, "type");enum {  MSG_CLOCK = 1,  MSG_DESTROY,  MSG_TERMINATE,  MSG_EVENT,  MSG_CREATE_TUNNEL,};struct EventData : public talk_base::MessageData {  int event, error;  EventData(int ev, int err = 0) : event(ev), error(err) { }};struct CreateTunnelData : public talk_base::MessageData {  buzz::Jid jid;  std::string description;  talk_base::Thread* thread;  talk_base::StreamInterface* stream;};extern const talk_base::ConstantLabel SESSION_STATES[];const talk_base::ConstantLabel SESSION_STATES[] = {  KLABEL(Session::STATE_INIT),  KLABEL(Session::STATE_SENTINITIATE),  KLABEL(Session::STATE_RECEIVEDINITIATE),  KLABEL(Session::STATE_SENTACCEPT),  KLABEL(Session::STATE_RECEIVEDACCEPT),  KLABEL(Session::STATE_SENTMODIFY),  KLABEL(Session::STATE_RECEIVEDMODIFY),  KLABEL(Session::STATE_SENTREJECT),  KLABEL(Session::STATE_RECEIVEDREJECT),  KLABEL(Session::STATE_SENTREDIRECT),  KLABEL(Session::STATE_SENTTERMINATE),  KLABEL(Session::STATE_RECEIVEDTERMINATE),  KLABEL(Session::STATE_INPROGRESS),  KLABEL(Session::STATE_DEINIT),  LASTLABEL};///////////////////////////////////////////////////////////////////////////////// TunnelSessionDescription///////////////////////////////////////////////////////////////////////////////struct TunnelSessionDescription : public SessionDescription {  std::string description;  TunnelSessionDescription(const std::string& desc) : description(desc) { }};///////////////////////////////////////////////////////////////////////////////// TunnelSessionClient///////////////////////////////////////////////////////////////////////////////TunnelSessionClient::TunnelSessionClient(const buzz::Jid& jid,                                         SessionManager* manager)  : jid_(jid), session_manager_(manager), shutdown_(false) {  // Register ourselves as the handler of tunnel sessions.  session_manager_->AddClient(NS_TUNNEL, this);}TunnelSessionClient::~TunnelSessionClient() {  shutdown_ = true;  for (std::vector<TunnelSession*>::iterator it = sessions_.begin();       it != sessions_.end();       ++it) {     Session* session = (*it)->ReleaseSession(true);     session_manager_->DestroySession(session);  }  session_manager_->RemoveClient(NS_TUNNEL);}const SessionDescription* TunnelSessionClient::CreateSessionDescription(    const buzz::XmlElement* element) {  if (const buzz::XmlElement* type_elem = element->FirstNamed(QN_TUNNEL_TYPE)) {    return new TunnelSessionDescription(type_elem->BodyText());  }  ASSERT(false);  return 0;}buzz::XmlElement* TunnelSessionClient::TranslateSessionDescription(    const SessionDescription* description) {  const TunnelSessionDescription* desc =      static_cast<const TunnelSessionDescription*>(description);  buzz::XmlElement* root = new buzz::XmlElement(QN_TUNNEL_DESCRIPTION, true);  buzz::XmlElement* type_elem = new buzz::XmlElement(QN_TUNNEL_TYPE);  type_elem->SetBodyText(desc->description);  root->AddElement(type_elem);  return root;}void TunnelSessionClient::OnSessionCreate(Session* session, bool received) {  LOG(LS_INFO) << "TunnelSessionClient::OnSessionCreate: received=" << received;  ASSERT(session_manager_->signaling_thread()->IsCurrent());  if (received)    sessions_.push_back(      new TunnelSession(this, session, talk_base::Thread::Current()));}void TunnelSessionClient::OnSessionDestroy(Session* session) {  LOG(LS_INFO) << "TunnelSessionClient::OnSessionDestroy";  ASSERT(session_manager_->signaling_thread()->IsCurrent());  if (shutdown_)    return;  for (std::vector<TunnelSession*>::iterator it = sessions_.begin();       it != sessions_.end();       ++it) {    if ((*it)->HasSession(session)) {      VERIFY((*it)->ReleaseSession(false) == session);      sessions_.erase(it);      return;    }  }}talk_base::StreamInterface* TunnelSessionClient::CreateTunnel(    const buzz::Jid& to, const std::string& description) {  // Valid from any thread  CreateTunnelData data;  data.jid = to;  data.description = description;  data.thread = talk_base::Thread::Current();  session_manager_->signaling_thread()->Send(this, MSG_CREATE_TUNNEL, &data);  return data.stream;}talk_base::StreamInterface* TunnelSessionClient::AcceptTunnel(    Session* session) {  ASSERT(session_manager_->signaling_thread()->IsCurrent());  TunnelSession* tunnel = NULL;  for (std::vector<TunnelSession*>::iterator it = sessions_.begin();       it != sessions_.end();       ++it) {    if ((*it)->HasSession(session)) {      tunnel = *it;      break;    }  }  ASSERT(tunnel != NULL);  const TunnelSessionDescription* in_desc =    static_cast<const TunnelSessionDescription*>(      session->remote_description());  TunnelSessionDescription* out_desc = new TunnelSessionDescription(    in_desc->description);  session->Accept(out_desc);  return tunnel->GetStream();}void TunnelSessionClient::DeclineTunnel(Session* session) {  ASSERT(session_manager_->signaling_thread()->IsCurrent());  session->Reject();}void TunnelSessionClient::OnMessage(talk_base::Message* pmsg) {  if (pmsg->message_id == MSG_CREATE_TUNNEL) {    ASSERT(session_manager_->signaling_thread()->IsCurrent());    CreateTunnelData* data = static_cast<CreateTunnelData*>(pmsg->pdata);    Session* session = session_manager_->CreateSession(jid_.Str(), NS_TUNNEL);    TunnelSession* tunnel = new TunnelSession(this, session, data->thread);    sessions_.push_back(tunnel);    TunnelSessionDescription* desc = new TunnelSessionDescription(data->description);    session->Initiate(data->jid.Str(), NULL, desc);    data->stream = tunnel->GetStream();  }}///////////////////////////////////////////////////////////////////////////////// TunnelSession/////////////////////////////////////////////////////////////////////////////////// Signalling thread methods//TunnelSession::TunnelSession(TunnelSessionClient* client, Session* session,                             talk_base::Thread* stream_thread)    : client_(client), session_(session), channel_(NULL) {  ASSERT(client_ != NULL);  ASSERT(session_ != NULL);  session_->SignalState.connect(this, &TunnelSession::OnSessionState);  channel_ = new PseudoTcpChannel(stream_thread, session_);  channel_->SignalChannelClosed.connect(this, &TunnelSession::OnChannelClosed);}TunnelSession::~TunnelSession() {  ASSERT(client_ != NULL);  ASSERT(session_ == NULL);  ASSERT(channel_ == NULL);}talk_base::StreamInterface* TunnelSession::GetStream() {  ASSERT(channel_ != NULL);  return channel_->GetStream();}bool TunnelSession::HasSession(Session* session) {  ASSERT(NULL != session_);  return (session_ == session);}Session* TunnelSession::ReleaseSession(bool channel_exists) {  ASSERT(NULL != session_);  ASSERT(NULL != channel_);  Session* session = session_;  session_->SignalState.disconnect(this);  session_ = NULL;  if (channel_exists)    channel_->SignalChannelClosed.disconnect(this);  channel_ = NULL;  delete this;  return session;}void TunnelSession::OnSessionState(Session* session, Session::State state) {  LOG(LS_INFO) << "TunnelSession::OnSessionState("               << talk_base::nonnull(                    talk_base::FindLabel(state, SESSION_STATES), "Unknown")               << ")";  ASSERT(session == session_);  switch (state) {  case Session::STATE_RECEIVEDINITIATE:    OnInitiate();    break;  case Session::STATE_SENTACCEPT:  case Session::STATE_RECEIVEDACCEPT:    OnAccept();    break;  case Session::STATE_SENTTERMINATE:  case Session::STATE_RECEIVEDTERMINATE:    OnTerminate();    break;  case Session::STATE_DEINIT:    // ReleaseSession should have been called before this.    ASSERT(false);    break;  }}void TunnelSession::OnInitiate() {  const TunnelSessionDescription* in_desc =    static_cast<const TunnelSessionDescription*>(      session_->remote_description());  ASSERT(client_ != NULL);  ASSERT(session_ != NULL);  client_->SignalIncomingTunnel(client_,                                buzz::Jid(session_->remote_name()),                                in_desc->description,                                session_);}void TunnelSession::OnAccept() {  ASSERT(channel_ != NULL);  VERIFY(channel_->Connect("tcp"));}void TunnelSession::OnTerminate() {}void TunnelSession::OnChannelClosed(PseudoTcpChannel* channel) {  ASSERT(channel_ == channel);  ASSERT(session_ != NULL);  session_->Terminate();}///////////////////////////////////////////////////////////////////////////////} // namespace cricket

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -