1 /*
2  * libjingle
3  * Copyright 2004--2005, 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 TALK_P2P_BASE_SESSION_H_
29 #define TALK_P2P_BASE_SESSION_H_
30 
31 #include <list>
32 #include <map>
33 #include <string>
34 #include <vector>
35 
36 #include "talk/base/refcount.h"
37 #include "talk/base/scoped_ptr.h"
38 #include "talk/base/scoped_ref_ptr.h"
39 #include "talk/base/socketaddress.h"
40 #include "talk/p2p/base/parsing.h"
41 #include "talk/p2p/base/port.h"
42 #include "talk/p2p/base/sessionclient.h"
43 #include "talk/p2p/base/sessionmanager.h"
44 #include "talk/p2p/base/sessionmessages.h"
45 #include "talk/p2p/base/transport.h"
46 #include "talk/xmllite/xmlelement.h"
47 #include "talk/xmpp/constants.h"
48 
49 namespace cricket {
50 
51 class P2PTransportChannel;
52 class Transport;
53 class TransportChannel;
54 class TransportChannelProxy;
55 class TransportChannelImpl;
56 
57 typedef talk_base::RefCountedObject<talk_base::scoped_ptr<Transport> >
58 TransportWrapper;
59 
60 // Used for errors that will send back a specific error message to the
61 // remote peer.  We add "type" to the errors because it's needed for
62 // SignalErrorMessage.
63 struct MessageError : ParseError {
64   buzz::QName type;
65 
66   // if unset, assume type is a parse error
MessageErrorMessageError67   MessageError() : ParseError(), type(buzz::QN_STANZA_BAD_REQUEST) {}
68 
SetTypeMessageError69   void SetType(const buzz::QName type) {
70     this->type = type;
71   }
72 };
73 
74 // Used for errors that may be returned by public session methods that
75 // can fail.
76 // TODO: Use this error in Session::Initiate and
77 // Session::Accept.
78 struct SessionError : WriteError {
79 };
80 
81 // Bundles a Transport and ChannelMap together. ChannelMap is used to
82 // create transport channels before receiving or sending a session
83 // initiate, and for speculatively connecting channels.  Previously, a
84 // session had one ChannelMap and transport.  Now, with multiple
85 // transports per session, we need multiple ChannelMaps as well.
86 
87 typedef std::map<std::string, TransportChannelProxy*> ChannelMap;
88 
89 class TransportProxy {
90  public:
TransportProxy(const std::string & sid,const std::string & content_name,TransportWrapper * transport)91   TransportProxy(
92       const std::string& sid,
93       const std::string& content_name,
94       TransportWrapper* transport)
95       : sid_(sid),
96         content_name_(content_name),
97         transport_(transport),
98         state_(STATE_INIT),
99         sent_candidates_(false),
100         candidates_allocated_(false) {}
101   ~TransportProxy();
102 
content_name()103   std::string content_name() const { return content_name_; }
impl()104   Transport* impl() const { return transport_->get(); }
105 
106   void SetImplementation(TransportWrapper* impl);
107   std::string type() const;
negotiated()108   bool negotiated() const { return state_ == STATE_NEGOTIATED; }
sent_candidates()109   const Candidates& sent_candidates() const { return sent_candidates_; }
unsent_candidates()110   const Candidates& unsent_candidates() const { return unsent_candidates_; }
111 
112   TransportChannel* GetChannel(const std::string& name);
113   TransportChannel* CreateChannel(const std::string& name,
114                                   const std::string& content_type);
115   void DestroyChannel(const std::string& name);
116   void AddSentCandidates(const Candidates& candidates);
117   void AddUnsentCandidates(const Candidates& candidates);
ClearSentCandidates()118   void ClearSentCandidates() { sent_candidates_.clear(); }
ClearUnsentCandidates()119   void ClearUnsentCandidates() { unsent_candidates_.clear(); }
120   void SpeculativelyConnectChannels();
121   void CompleteNegotiation();
122   void SetupMux(TransportProxy* proxy);
channels()123   const ChannelMap& channels() { return channels_; }
set_candidates_allocated(bool allocated)124   void set_candidates_allocated(bool allocated) {
125     candidates_allocated_ = allocated;
126   }
candidates_allocated()127   bool candidates_allocated() { return candidates_allocated_; }
128 
129  private:
130   enum TransportState {
131     STATE_INIT,
132     STATE_CONNECTING,
133     STATE_NEGOTIATED
134   };
135 
136   TransportChannelProxy* GetProxy(const std::string& name);
137   void ReplaceImpl(TransportChannelProxy* channel_proxy, size_t index);
138   TransportChannelImpl* GetOrCreateImpl(const std::string& name,
139                                         const std::string& content_type);
140   void SetProxyImpl(const std::string& name, TransportChannelProxy* proxy);
141 
142   std::string sid_;
143   std::string content_name_;
144   talk_base::scoped_refptr<TransportWrapper> transport_;
145   TransportState state_;
146   ChannelMap channels_;
147   Candidates sent_candidates_;
148   Candidates unsent_candidates_;
149   bool candidates_allocated_;
150 };
151 
152 typedef std::map<std::string, TransportProxy*> TransportMap;
153 
154 // A BaseSession manages general session state. This includes negotiation
155 // of both the application-level and network-level protocols:  the former
156 // defines what will be sent and the latter defines how it will be sent.  Each
157 // network-level protocol is represented by a Transport object.  Each Transport
158 // participates in the network-level negotiation.  The individual streams of
159 // packets are represented by TransportChannels.  The application-level protocol
160 // is represented by SessionDecription objects.
161 class BaseSession : public sigslot::has_slots<>,
162                     public talk_base::MessageHandler {
163  public:
164   enum State {
165     STATE_INIT = 0,
166     STATE_SENTINITIATE,       // sent initiate, waiting for Accept or Reject
167     STATE_RECEIVEDINITIATE,   // received an initiate. Call Accept or Reject
168     STATE_SENTACCEPT,         // sent accept. begin connecting transport
169     STATE_RECEIVEDACCEPT,     // received accept. begin connecting transport
170     STATE_SENTMODIFY,         // sent modify, waiting for Accept or Reject
171     STATE_RECEIVEDMODIFY,     // received modify, call Accept or Reject
172     STATE_SENTREJECT,         // sent reject after receiving initiate
173     STATE_RECEIVEDREJECT,     // received reject after sending initiate
174     STATE_SENTREDIRECT,       // sent direct after receiving initiate
175     STATE_SENTTERMINATE,      // sent terminate (any time / either side)
176     STATE_RECEIVEDTERMINATE,  // received terminate (any time / either side)
177     STATE_INPROGRESS,         // session accepted and in progress
178     STATE_DEINIT,             // session is being destroyed
179   };
180 
181   enum Error {
182     ERROR_NONE = 0,      // no error
183     ERROR_TIME = 1,      // no response to signaling
184     ERROR_RESPONSE = 2,  // error during signaling
185     ERROR_NETWORK = 3,   // network error, could not allocate network resources
186     ERROR_CONTENT = 4,   // channel errors in SetLocalContent/SetRemoteContent
187   };
188 
189   // Convert State to a readable string.
190   static std::string StateToString(State state);
191 
192   BaseSession(talk_base::Thread* signaling_thread,
193               talk_base::Thread* worker_thread,
194               PortAllocator* port_allocator,
195               const std::string& sid,
196               const std::string& content_type,
197               bool initiator);
198   virtual ~BaseSession();
199 
signaling_thread()200   talk_base::Thread* signaling_thread() { return signaling_thread_; }
worker_thread()201   talk_base::Thread* worker_thread() { return worker_thread_; }
port_allocator()202   PortAllocator* port_allocator() { return port_allocator_; }
203 
204   // The ID of this session.
id()205   const std::string& id() const { return sid_; }
206 
207   // Returns the XML namespace identifying the type of this session.
content_type()208   const std::string& content_type() const { return content_type_; }
209 
210   // Returns the XML namespace identifying the transport used for this session.
transport_type()211   const std::string& transport_type() const { return transport_type_; }
212 
213   // Indicates whether we initiated this session.
initiator()214   bool initiator() const { return initiator_; }
215 
216   // Returns the application-level description given by our client.
217   // If we are the recipient, this will be NULL until we send an accept.
local_description()218   const SessionDescription* local_description() const {
219     return local_description_;
220   }
221   // Returns the application-level description given by the other client.
222   // If we are the initiator, this will be NULL until we receive an accept.
remote_description()223   const SessionDescription* remote_description() const {
224     return remote_description_;
225   }
remote_description()226   SessionDescription* remote_description() {
227     return remote_description_;
228   }
229 
230   // Takes ownership of SessionDescription*
set_local_description(const SessionDescription * sdesc)231   bool set_local_description(const SessionDescription* sdesc) {
232     if (sdesc != local_description_) {
233       delete local_description_;
234       local_description_ = sdesc;
235     }
236     return true;
237   }
238 
239   // Takes ownership of SessionDescription*
set_remote_description(SessionDescription * sdesc)240   bool set_remote_description(SessionDescription* sdesc) {
241     if (sdesc != remote_description_) {
242       delete remote_description_;
243       remote_description_ = sdesc;
244     }
245     return true;
246   }
247 
initiator_description()248   const SessionDescription* initiator_description() const {
249     if (initiator_) {
250       return local_description_;
251     } else {
252       return remote_description_;
253     }
254   }
255 
256   void set_allow_local_ips(bool allow);
257 
258   // Returns the current state of the session.  See the enum above for details.
259   // Each time the state changes, we will fire this signal.
state()260   State state() const { return state_; }
261   sigslot::signal2<BaseSession* , State> SignalState;
262 
263   // Returns the last error in the session.  See the enum above for details.
264   // Each time the an error occurs, we will fire this signal.
error()265   Error error() const { return error_; }
266   sigslot::signal2<BaseSession* , Error> SignalError;
267 
268   // Updates the state, signaling if necessary.
269   virtual void SetState(State state);
270 
271   // Updates the error state, signaling if necessary.
272   virtual void SetError(Error error);
273 
274   // Fired when the remote description is updated, with the updated
275   // contents.
276   sigslot::signal2<BaseSession* , const ContentInfos&>
277       SignalRemoteDescriptionUpdate;
278 
279   // Returns the transport that has been negotiated or NULL if
280   // negotiation is still in progress.
281   Transport* GetTransport(const std::string& content_name);
282 
283   // Creates a new channel with the given names.  This method may be called
284   // immediately after creating the session.  However, the actual
285   // implementation may not be fixed until transport negotiation completes.
286   // This will usually be called from the worker thread, but that
287   // shouldn't be an issue since the main thread will be blocked in
288   // Send when doing so.
289   virtual TransportChannel* CreateChannel(const std::string& content_name,
290                                           const std::string& channel_name);
291 
292   // Returns the channel with the given names.
293   virtual TransportChannel* GetChannel(const std::string& content_name,
294                                        const std::string& channel_name);
295 
296   // Destroys the channel with the given names.
297   // This will usually be called from the worker thread, but that
298   // shouldn't be an issue since the main thread will be blocked in
299   // Send when doing so.
300   virtual void DestroyChannel(const std::string& content_name,
301                               const std::string& channel_name);
302 
303  protected:
transport_proxies()304   const TransportMap& transport_proxies() const { return transports_; }
305 
306   // Get a TransportProxy by content_name or transport. NULL if not found.
307   TransportProxy* GetTransportProxy(const std::string& content_name);
308   TransportProxy* GetTransportProxy(const Transport* transport);
309   TransportProxy* GetFirstTransportProxy();
310   void DestroyTransportProxy(const std::string& content_name);
311   // TransportProxy is owned by session.  Return proxy just for convenience.
312   TransportProxy* GetOrCreateTransportProxy(const std::string& content_name);
313   // Creates the actual transport object. Overridable for testing.
314   virtual Transport* CreateTransport();
315 
316   void OnSignalingReady();
317   void SpeculativelyConnectAllTransportChannels();
318   // This method will mux transport channels by content_name.
319   // First content is used for muxing.
320   bool MaybeEnableMuxingSupport();
321 
322   // Called when a transport requests signaling.
OnTransportRequestSignaling(Transport * transport)323   virtual void OnTransportRequestSignaling(Transport* transport) {
324   }
325 
326   // Called when the first channel of a transport begins connecting.  We use
327   // this to start a timer, to make sure that the connection completes in a
328   // reasonable amount of time.
OnTransportConnecting(Transport * transport)329   virtual void OnTransportConnecting(Transport* transport) {
330   }
331 
332   // Called when a transport changes its writable state.  We track this to make
333   // sure that the transport becomes writable within a reasonable amount of
334   // time.  If this does not occur, we signal an error.
OnTransportWritable(Transport * transport)335   virtual void OnTransportWritable(Transport* transport) {
336   }
337 
338   // Called when a transport signals that it has new candidates.
OnTransportCandidatesReady(Transport * transport,const Candidates & candidates)339   virtual void OnTransportCandidatesReady(Transport* transport,
340                                           const Candidates& candidates) {
341   }
342 
343   // Called when a transport signals that it found an error in an incoming
344   // message.
OnTransportSendError(Transport * transport,const buzz::XmlElement * stanza,const buzz::QName & name,const std::string & type,const std::string & text,const buzz::XmlElement * extra_info)345   virtual void OnTransportSendError(Transport* transport,
346                                     const buzz::XmlElement* stanza,
347                                     const buzz::QName& name,
348                                     const std::string& type,
349                                     const std::string& text,
350                                     const buzz::XmlElement* extra_info) {
351   }
352 
353   // Called when we notice that one of our local channels has no peer, so it
354   // should be destroyed.
OnTransportChannelGone(Transport * transport,const std::string & name)355   virtual void OnTransportChannelGone(Transport* transport,
356                                       const std::string& name) {
357   }
358 
OnTransportRouteChange(Transport * transport,const std::string & name,const cricket::Candidate & remote_candidate)359   virtual void OnTransportRouteChange(
360       Transport* transport,
361       const std::string& name,
362       const cricket::Candidate& remote_candidate) {
363   }
364 
365   virtual void OnTransportCandidatesAllocationDone(Transport* transport);
366 
367   // Called when all transport channels allocated required candidates.
368   // This method should be used as an indication of candidates gathering process
369   // is completed and application can now send local candidates list to remote.
OnCandidatesAllocationDone()370   virtual void OnCandidatesAllocationDone() {
371   }
372 
373   // Handles messages posted to us.
374   virtual void OnMessage(talk_base::Message *pmsg);
375 
376  protected:
377   State state_;
378   Error error_;
379 
380  private:
381   // This method will check GroupInfo in local and remote SessionDescriptions.
382   bool ContentsGrouped();
383   // This method will delete the Transport and TransportChannelImpl's and
384   // replace those with the selected Transport objects. Selection is done
385   // based on the content_name and in this case first MediaContent information
386   // is used for mux.
387   void SetSelectedProxy(const std::string& content_name,
388                         const ContentGroup* muxed_group);
389   // Log session state.
390   void LogState(State old_state, State new_state);
391 
392   talk_base::Thread* signaling_thread_;
393   talk_base::Thread* worker_thread_;
394   PortAllocator* port_allocator_;
395   std::string sid_;
396   std::string content_type_;
397   std::string transport_type_;
398   bool initiator_;
399   const SessionDescription* local_description_;
400   SessionDescription* remote_description_;
401   // This is transport-specific but required so much by unit tests
402   // that it's much easier to put it here.
403   bool allow_local_ips_;
404   TransportMap transports_;
405 };
406 
407 // A specific Session created by the SessionManager, using XMPP for protocol.
408 class Session : public BaseSession {
409  public:
410   // Returns the manager that created and owns this session.
session_manager()411   SessionManager* session_manager() const { return session_manager_; }
412 
413   // Returns the client that is handling the application data of this session.
client()414   SessionClient* client() const { return client_; }
415 
416     // Returns the JID of this client.
local_name()417   const std::string& local_name() const { return local_name_; }
418 
419   // Returns the JID of the other peer in this session.
remote_name()420   const std::string& remote_name() const { return remote_name_; }
421 
422   // Set the JID of the other peer in this session.
423   // Typically the remote_name_ is set when the session is initiated.
424   // However, sometimes (e.g when a proxy is used) the peer name is
425   // known after the BaseSession has been initiated and it must be updated
426   // explicitly.
set_remote_name(const std::string & name)427   void set_remote_name(const std::string& name) { remote_name_ = name; }
428 
429   // Indicates the JID of the entity who initiated this session.
430   // In special cases, may be different than both local_name and remote_name.
initiator_name()431   const std::string& initiator_name() const { return initiator_name_; }
432 
current_protocol()433   SignalingProtocol current_protocol() const { return current_protocol_; }
434 
set_current_protocol(SignalingProtocol protocol)435   void set_current_protocol(SignalingProtocol protocol) {
436     current_protocol_ = protocol;
437   }
438 
439   // Updates the error state, signaling if necessary.
440   virtual void SetError(Error error);
441 
442   // When the session needs to send signaling messages, it beings by requesting
443   // signaling.  The client should handle this by calling OnSignalingReady once
444   // it is ready to send the messages.
445   // (These are called only by SessionManager.)
446   sigslot::signal1<Session*> SignalRequestSignaling;
OnSignalingReady()447   void OnSignalingReady() { BaseSession::OnSignalingReady(); }
448 
449   // Invoked when we notice that there is no matching channel on our peer.
450   sigslot::signal2<Session*, const std::string&> SignalChannelGone;
451 
452   // Takes ownership of session description.
453   // TODO: Add an error argument to pass back to the caller.
454   bool Initiate(const std::string& to,
455                 const SessionDescription* sdesc);
456 
457   // When we receive an initiate, we create a session in the
458   // RECEIVEDINITIATE state and respond by accepting or rejecting.
459   // Takes ownership of session description.
460   // TODO: Add an error argument to pass back to the caller.
461   bool Accept(const SessionDescription* sdesc);
462   bool Reject(const std::string& reason);
Terminate()463   bool Terminate() {
464     return TerminateWithReason(STR_TERMINATE_SUCCESS);
465   }
466   bool TerminateWithReason(const std::string& reason);
467   // Fired whenever we receive a terminate message along with a reason
468   sigslot::signal2<Session*, const std::string&> SignalReceivedTerminateReason;
469 
470   // The two clients in the session may also send one another
471   // arbitrary XML messages, which are called "info" messages. Sending
472   // takes ownership of the given elements.  The signal does not; the
473   // parent element will be deleted after the signal.
474   bool SendInfoMessage(const XmlElements& elems);
475   sigslot::signal2<Session*, const buzz::XmlElement*> SignalInfoMessage;
476 
477  private:
478   // Creates or destroys a session.  (These are called only SessionManager.)
479   Session(SessionManager *session_manager,
480           const std::string& local_name, const std::string& initiator_name,
481           const std::string& sid, const std::string& content_type,
482           SessionClient* client);
483   ~Session();
484   // For each transport info, create a transport proxy.  Can fail for
485   // incompatible transport types.
486   bool CreateTransportProxies(const TransportInfos& tinfos,
487                               SessionError* error);
488   bool OnRemoteCandidates(const TransportInfos& tinfos,
489                           ParseError* error);
490   // Returns a TransportInfo without candidates for each content name.
491   // Uses the transport_type_ of the session.
492   TransportInfos GetEmptyTransportInfos(const ContentInfos& contents) const;
493 
494     // Maps passed to serialization functions.
495   TransportParserMap GetTransportParsers();
496   ContentParserMap GetContentParsers();
497 
498   virtual void OnTransportRequestSignaling(Transport* transport);
499   virtual void OnTransportConnecting(Transport* transport);
500   virtual void OnTransportWritable(Transport* transport);
501   virtual void OnTransportCandidatesReady(Transport* transport,
502                                           const Candidates& candidates);
503   virtual void OnTransportSendError(Transport* transport,
504                                     const buzz::XmlElement* stanza,
505                                     const buzz::QName& name,
506                                     const std::string& type,
507                                     const std::string& text,
508                                     const buzz::XmlElement* extra_info);
509   virtual void OnTransportChannelGone(Transport* transport,
510                                       const std::string& name);
511 
512   virtual void OnMessage(talk_base::Message *pmsg);
513 
514   // Send various kinds of session messages.
515   bool SendInitiateMessage(const SessionDescription* sdesc,
516                            SessionError* error);
517   bool SendAcceptMessage(const SessionDescription* sdesc, SessionError* error);
518   bool SendRejectMessage(const std::string& reason, SessionError* error);
519   bool SendTerminateMessage(const std::string& reason, SessionError* error);
520   bool SendTransportInfoMessage(const TransportInfo& tinfo,
521                                 SessionError* error);
522   bool SendTransportInfoMessage(const TransportProxy* transproxy,
523                                 const Candidates& candidates,
524                                 SessionError* error);
525 
526   bool ResendAllTransportInfoMessages(SessionError* error);
527   bool SendAllUnsentTransportInfoMessages(SessionError* error);
528 
529   // Both versions of SendMessage send a message of the given type to
530   // the other client.  Can pass either a set of elements or an
531   // "action", which must have a WriteSessionAction method to go along
532   // with it.  Sending with an action supports sending a "hybrid"
533   // message.  Sending with elements must be sent as Jingle or Gingle.
534 
535   // When passing elems, must be either Jingle or Gingle protocol.
536   // Takes ownership of action_elems.
537   bool SendMessage(ActionType type, const XmlElements& action_elems,
538                    SessionError* error);
539   // When passing an action, may be Hybrid protocol.
540   template <typename Action>
541   bool SendMessage(ActionType type, const Action& action,
542                    SessionError* error);
543 
544   // Helper methods to write the session message stanza.
545   template <typename Action>
546   bool WriteActionMessage(ActionType type, const Action& action,
547                           buzz::XmlElement* stanza, WriteError* error);
548   template <typename Action>
549   bool WriteActionMessage(SignalingProtocol protocol,
550                           ActionType type, const Action& action,
551                           buzz::XmlElement* stanza, WriteError* error);
552 
553   // Sending messages in hybrid form requires being able to write them
554   // on a per-protocol basis with a common method signature, which all
555   // of these have.
556   bool WriteSessionAction(SignalingProtocol protocol,
557                           const SessionInitiate& init,
558                           XmlElements* elems, WriteError* error);
559   bool WriteSessionAction(SignalingProtocol protocol,
560                           const TransportInfo& tinfo,
561                           XmlElements* elems, WriteError* error);
562   bool WriteSessionAction(SignalingProtocol protocol,
563                           const SessionTerminate& term,
564                           XmlElements* elems, WriteError* error);
565 
566   // Sends a message back to the other client indicating that we have received
567   // and accepted their message.
568   void SendAcknowledgementMessage(const buzz::XmlElement* stanza);
569 
570   // Once signaling is ready, the session will use this signal to request the
571   // sending of each message.  When messages are received by the other client,
572   // they should be handed to OnIncomingMessage.
573   // (These are called only by SessionManager.)
574   sigslot::signal2<Session* , const buzz::XmlElement*> SignalOutgoingMessage;
575   void OnIncomingMessage(const SessionMessage& msg);
576 
577   void OnIncomingResponse(const buzz::XmlElement* orig_stanza,
578                           const buzz::XmlElement* response_stanza,
579                           const SessionMessage& msg);
580   void OnInitiateAcked();
581   void OnFailedSend(const buzz::XmlElement* orig_stanza,
582                     const buzz::XmlElement* error_stanza);
583 
584   // Invoked when an error is found in an incoming message.  This is translated
585   // into the appropriate XMPP response by SessionManager.
586   sigslot::signal6<BaseSession*,
587                    const buzz::XmlElement*,
588                    const buzz::QName&,
589                    const std::string&,
590                    const std::string&,
591                    const buzz::XmlElement*> SignalErrorMessage;
592 
593   // Handlers for the various types of messages.  These functions may take
594   // pointers to the whole stanza or to just the session element.
595   bool OnInitiateMessage(const SessionMessage& msg, MessageError* error);
596   bool OnAcceptMessage(const SessionMessage& msg, MessageError* error);
597   bool OnRejectMessage(const SessionMessage& msg, MessageError* error);
598   bool OnInfoMessage(const SessionMessage& msg);
599   bool OnTerminateMessage(const SessionMessage& msg, MessageError* error);
600   bool OnTransportInfoMessage(const SessionMessage& msg, MessageError* error);
601   bool OnTransportAcceptMessage(const SessionMessage& msg, MessageError* error);
602   bool OnDescriptionInfoMessage(const SessionMessage& msg, MessageError* error);
603   bool OnRedirectError(const SessionRedirect& redirect, SessionError* error);
604 
605   // Verifies that we are in the appropriate state to receive this message.
606   bool CheckState(State state, MessageError* error);
607 
608   SessionManager* session_manager_;
609   bool initiate_acked_;
610   std::string local_name_;
611   std::string initiator_name_;
612   std::string remote_name_;
613   SessionClient* client_;
614   TransportParser* transport_parser_;
615   // Keeps track of what protocol we are speaking.
616   SignalingProtocol current_protocol_;
617 
618   friend class SessionManager;  // For access to constructor, destructor,
619                                 // and signaling related methods.
620 };
621 
622 }  // namespace cricket
623 
624 #endif  // TALK_P2P_BASE_SESSION_H_
625