IceServer.hpp 4.81 KB
Newer Older
xiongziliang committed
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
/**
ISC License

Copyright © 2015, Iñaki Baz Castillo <ibc@aliax.net>

Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.

THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 */

#ifndef MS_RTC_ICE_SERVER_HPP
ziyue committed
20
#define MS_RTC_ICE_SERVER_HPP
21

ziyue committed
22
#include "StunPacket.hpp"
23
#include "Network/Session.h"
ziyue committed
24
#include "logger.h"
ziyue committed
25
#include "Utils.hpp"
ziyue committed
26 27
#include <list>
#include <string>
28 29 30
#include <functional>
#include <memory>

ziyue committed
31 32
namespace RTC
{
ziyue committed
33 34 35 36 37 38 39 40 41 42 43
    using TransportTuple = toolkit::Session;
    class IceServer
    {
    public:
        enum class IceState
        {
            NEW = 1,
            CONNECTED,
            COMPLETED,
            DISCONNECTED
        };
ziyue committed
44

ziyue committed
45 46 47 48 49
    public:
        class Listener
        {
        public:
            virtual ~Listener() = default;
ziyue committed
50

ziyue committed
51 52 53 54 55 56 57 58 59 60 61 62 63
        public:
            /**
             * These callbacks are guaranteed to be called before ProcessStunPacket()
             * returns, so the given pointers are still usable.
             */
            virtual void OnIceServerSendStunPacket(
              const RTC::IceServer* iceServer, const RTC::StunPacket* packet, RTC::TransportTuple* tuple) = 0;
            virtual void OnIceServerSelectedTuple(
              const RTC::IceServer* iceServer, RTC::TransportTuple* tuple)        = 0;
            virtual void OnIceServerConnected(const RTC::IceServer* iceServer)    = 0;
            virtual void OnIceServerCompleted(const RTC::IceServer* iceServer)    = 0;
            virtual void OnIceServerDisconnected(const RTC::IceServer* iceServer) = 0;
        };
ziyue committed
64

ziyue committed
65 66
    public:
        IceServer(Listener* listener, const std::string& usernameFragment, const std::string& password);
ziyue committed
67

ziyue committed
68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83
    public:
        void ProcessStunPacket(RTC::StunPacket* packet, RTC::TransportTuple* tuple);
        const std::string& GetUsernameFragment() const
        {
            return this->usernameFragment;
        }
        const std::string& GetPassword() const
        {
            return this->password;
        }
        IceState GetState() const
        {
            return this->state;
        }
        RTC::TransportTuple* GetSelectedTuple(bool try_last_tuple = false) const
        {
84 85
            return try_last_tuple ? this->lastSelectedTuple.lock().get() : this->selectedTuple;
        }
ziyue committed
86 87 88 89 90 91 92 93 94 95 96 97 98 99 100
        void SetUsernameFragment(const std::string& usernameFragment)
        {
            this->oldUsernameFragment = this->usernameFragment;
            this->usernameFragment    = usernameFragment;
        }
        void SetPassword(const std::string& password)
        {
            this->oldPassword = this->password;
            this->password    = password;
        }
        bool IsValidTuple(const RTC::TransportTuple* tuple) const;
        void RemoveTuple(RTC::TransportTuple* tuple);
        // This should be just called in 'connected' or completed' state
        // and the given tuple must be an already valid tuple.
        void ForceSelectedTuple(const RTC::TransportTuple* tuple);
ziyue committed
101

102 103 104
        const std::list<RTC::TransportTuple *>& GetTuples() const { return tuples; }

    private:
ziyue committed
105 106 107 108 109 110 111 112 113 114 115 116 117 118
        void HandleTuple(RTC::TransportTuple* tuple, bool hasUseCandidate);
        /**
         * Store the given tuple and return its stored address.
         */
        RTC::TransportTuple* AddTuple(RTC::TransportTuple* tuple);
        /**
         * If the given tuple exists return its stored address, nullptr otherwise.
         */
        RTC::TransportTuple* HasTuple(const RTC::TransportTuple* tuple) const;
        /**
         * Set the given tuple as the selected tuple.
         * NOTE: The given tuple MUST be already stored within the list.
         */
        void SetSelectedTuple(RTC::TransportTuple* storedTuple);
ziyue committed
119

ziyue committed
120 121 122 123 124 125 126 127 128 129
    private:
        // Passed by argument.
        Listener* listener{ nullptr };
        // Others.
        std::string usernameFragment;
        std::string password;
        std::string oldUsernameFragment;
        std::string oldPassword;
        IceState state{ IceState::NEW };
        std::list<RTC::TransportTuple *> tuples;
130
        RTC::TransportTuple *selectedTuple { nullptr };
131
        std::weak_ptr<RTC::TransportTuple> lastSelectedTuple;
ziyue committed
132
        //最大不超过mtu
ziyue committed
133 134
        static constexpr size_t StunSerializeBufferSize{ 1600 };
        uint8_t StunSerializeBuffer[StunSerializeBufferSize];
ziyue committed
135
    };
ziyue committed
136
} // namespace RTC
137

ziyue committed
138
#endif