1 /* 2 * libjingle 3 * Copyright 2004--2008, Google Inc. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions are met: 7 * 8 * 1. Redistributions of source code must retain the above copyright notice, 9 * this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright notice, 11 * this list of conditions and the following disclaimer in the documentation 12 * and/or other materials provided with the distribution. 13 * 3. The name of the author may not be used to endorse or promote products 14 * derived from this software without specific prior written permission. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED 17 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 18 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO 19 * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 20 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 21 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 22 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 23 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 24 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 25 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 */ 27 28 #ifndef __TUNNELSESSIONCLIENT_H__ 29 #define __TUNNELSESSIONCLIENT_H__ 30 31 #include <vector> 32 33 #include "talk/p2p/base/constants.h" 34 #include "talk/p2p/base/pseudotcp.h" 35 #include "talk/p2p/base/session.h" 36 #include "talk/p2p/base/sessionclient.h" 37 #include "talk/p2p/base/sessiondescription.h" 38 #include "talk/p2p/base/sessionmanager.h" 39 #include "webrtc/libjingle/xmllite/qname.h" 40 #include "talk/xmpp/constants.h" 41 #include "webrtc/base/criticalsection.h" 42 #include "webrtc/base/stream.h" 43 44 namespace cricket { 45 46 class TunnelSession; 47 class TunnelStream; 48 49 enum TunnelSessionRole { INITIATOR, RESPONDER }; 50 51 /////////////////////////////////////////////////////////////////////////////// 52 // TunnelSessionClient 53 /////////////////////////////////////////////////////////////////////////////// 54 55 // Base class is still abstract 56 class TunnelSessionClientBase 57 : public SessionClient, public rtc::MessageHandler { 58 public: 59 TunnelSessionClientBase(const buzz::Jid& jid, SessionManager* manager, 60 const std::string &ns); 61 virtual ~TunnelSessionClientBase(); 62 63 const buzz::Jid& jid() const { return jid_; } 64 SessionManager* session_manager() const { return session_manager_; } 65 66 void OnSessionCreate(Session* session, bool received); 67 void OnSessionDestroy(Session* session); 68 69 // This can be called on any thread. The stream interface is 70 // thread-safe, but notifications must be registered on the creating 71 // thread. 72 rtc::StreamInterface* CreateTunnel(const buzz::Jid& to, 73 const std::string& description); 74 75 rtc::StreamInterface* AcceptTunnel(Session* session); 76 void DeclineTunnel(Session* session); 77 78 // Invoked on an incoming tunnel 79 virtual void OnIncomingTunnel(const buzz::Jid &jid, Session *session) = 0; 80 81 // Invoked on an outgoing session request 82 virtual SessionDescription* CreateOffer( 83 const buzz::Jid &jid, const std::string &description) = 0; 84 // Invoked on a session request accept to create 85 // the local-side session description 86 virtual SessionDescription* CreateAnswer( 87 const SessionDescription* offer) = 0; 88 89 protected: 90 91 void OnMessage(rtc::Message* pmsg); 92 93 // helper method to instantiate TunnelSession. By overriding this, 94 // subclasses of TunnelSessionClient are able to instantiate 95 // subclasses of TunnelSession instead. 96 virtual TunnelSession* MakeTunnelSession(Session* session, 97 rtc::Thread* stream_thread, 98 TunnelSessionRole role); 99 100 buzz::Jid jid_; 101 SessionManager* session_manager_; 102 std::vector<TunnelSession*> sessions_; 103 std::string namespace_; 104 bool shutdown_; 105 }; 106 107 class TunnelSessionClient 108 : public TunnelSessionClientBase, public sigslot::has_slots<> { 109 public: 110 TunnelSessionClient(const buzz::Jid& jid, SessionManager* manager); 111 TunnelSessionClient(const buzz::Jid& jid, SessionManager* manager, 112 const std::string &ns); 113 virtual ~TunnelSessionClient(); 114 115 virtual bool ParseContent(SignalingProtocol protocol, 116 const buzz::XmlElement* elem, 117 ContentDescription** content, 118 ParseError* error); 119 virtual bool WriteContent(SignalingProtocol protocol, 120 const ContentDescription* content, 121 buzz::XmlElement** elem, 122 WriteError* error); 123 124 // Signal arguments are this, initiator, description, session 125 sigslot::signal4<TunnelSessionClient*, buzz::Jid, std::string, Session*> 126 SignalIncomingTunnel; 127 128 virtual void OnIncomingTunnel(const buzz::Jid &jid, 129 Session *session); 130 virtual SessionDescription* CreateOffer( 131 const buzz::Jid &jid, const std::string &description); 132 virtual SessionDescription* CreateAnswer( 133 const SessionDescription* offer); 134 }; 135 136 /////////////////////////////////////////////////////////////////////////////// 137 // TunnelSession 138 // Note: The lifetime of TunnelSession is complicated. It needs to survive 139 // until the following three conditions are true: 140 // 1) TunnelStream has called Close (tracked via non-null stream_) 141 // 2) PseudoTcp has completed (tracked via non-null tcp_) 142 // 3) Session has been destroyed (tracked via non-null session_) 143 // This is accomplished by calling CheckDestroy after these indicators change. 144 /////////////////////////////////////////////////////////////////////////////// 145 /////////////////////////////////////////////////////////////////////////////// 146 // TunnelStream 147 // Note: Because TunnelStream provides a stream interface, its lifetime is 148 // controlled by the owner of the stream pointer. As a result, we must support 149 // both the TunnelSession disappearing before TunnelStream, and vice versa. 150 /////////////////////////////////////////////////////////////////////////////// 151 152 class PseudoTcpChannel; 153 154 class TunnelSession : public sigslot::has_slots<> { 155 public: 156 // Signalling thread methods 157 TunnelSession(TunnelSessionClientBase* client, Session* session, 158 rtc::Thread* stream_thread); 159 160 virtual rtc::StreamInterface* GetStream(); 161 bool HasSession(Session* session); 162 Session* ReleaseSession(bool channel_exists); 163 164 protected: 165 virtual ~TunnelSession(); 166 167 virtual void OnSessionState(BaseSession* session, BaseSession::State state); 168 virtual void OnInitiate(); 169 virtual void OnAccept(); 170 virtual void OnTerminate(); 171 virtual void OnChannelClosed(PseudoTcpChannel* channel); 172 173 TunnelSessionClientBase* client_; 174 Session* session_; 175 PseudoTcpChannel* channel_; 176 }; 177 178 /////////////////////////////////////////////////////////////////////////////// 179 180 } // namespace cricket 181 182 #endif // __TUNNELSESSIONCLIENT_H__ 183