Skip to content
Snippets Groups Projects
Select Git revision
  • 1eeff3c5a1cff8bd02ec561e46ed634e6ecb8162
  • master default protected
  • release/202005
  • release/202001
  • release/201912
  • release/201911
  • release/releaseWindowsTestOne
  • release/windowsReleaseTest
  • release/releaseTest
  • release/releaseWindowsTest
  • release/201910
  • release/qt/201910
  • release/windows-test/201910
  • release/201908
  • release/201906
  • release/201905
  • release/201904
  • release/201903
  • release/201902
  • release/201901
  • release/201812
  • 4.0.0
  • 2.2.0
  • 2.1.0
  • 2.0.1
  • 2.0.0
  • 1.4.1
  • 1.4.0
  • 1.3.0
  • 1.2.0
  • 1.1.0
31 results

socket_pair.h

Blame
  • Code owners
    Assign users and groups as approvers for specific file changes. Learn more.
    socket_pair.h 5.78 KiB
    /*
     *  Copyright (C) 2004-2019 Savoir-faire Linux Inc.
     *  Copyright (C) 2012 VLC authors and VideoLAN
     *
     *  Author: Tristan Matthews <tristan.matthews@savoirfairelinux.com>
     *
     *  This program is free software; you can redistribute it and/or modify
     *  it under the terms of the GNU General Public License as published by
     *  the Free Software Foundation; either version 3 of the License, or
     *  (at your option) any later version.
     *
     *  This program is distributed in the hope that it will be useful,
     *  but WITHOUT ANY WARRANTY; without even the implied warranty of
     *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     *  GNU General Public License for more details.
     *
     *  You should have received a copy of the GNU General Public License
     *  along with this program; if not, write to the Free Software
     *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA.
     */
    
    #pragma once
    
    #ifdef HAVE_CONFIG_H
    #include <config.h>
    #endif
    
    #include "ip_utils.h"
    #include "media_io_handle.h"
    
    #ifndef _WIN32
    #include <sys/socket.h>
    #include <netdb.h>
    #include <poll.h>
    #else
    #include <winsock2.h>
    #include <ws2tcpip.h>
    using socklen_t = int;
    #endif
    
    #include <cstdint>
    #include <mutex>
    #include <memory>
    #include <atomic>
    #include <list>
    #include <vector>
    #include <condition_variable>
    
    
    namespace jami {
    
    class IceSocket;
    class SRTPProtoContext;
    
    typedef struct {
    #ifdef WORDS_BIGENDIAN
        uint32_t version:2; /* protocol version */
        uint32_t p:1;       /* padding flag */
        uint32_t rc:5;      /* reception report count must be 201 for report */
    
    #else
        uint32_t rc:5;      /* reception report count must be 201 for report */
        uint32_t p:1;       /* padding flag */
        uint32_t version:2; /* protocol version */
    #endif
        uint32_t pt:8;      /* payload type */
        uint32_t len:16;    /* length of RTCP packet */
        uint32_t ssrc;      /* synchronization source identifier of packet send */
        uint32_t id;        /* synchronization source identifier of first source */
        uint32_t fraction_lost:8;       /* 8 bits of fraction, 24 bits of total packets lost */
        uint32_t cum_lost_packet:24;    /* cumulative number packet lost */
        uint32_t ext_high;  /* Extended highest sequence number received */
        uint32_t jitter;    /* jitter */
        uint32_t lsr;       /* last SR timestamp */
        uint32_t dlsr;      /* Delay since last SR timestamp */
    } rtcpRRHeader;
    
    typedef struct {
    #ifdef WORDS_BIGENDIAN
        uint32_t version:2; /* protocol version */
        uint32_t p:1;       /* padding flag */
        uint32_t rc:5;      /* reception report count must be 201 for report */
    
    #else
        uint32_t rc:5;      /* reception report count must be 201 for report */
        uint32_t p:1;       /* padding flag */
        uint32_t version:2; /* protocol version */
    #endif
        uint32_t pt:8;      /* payload type */
        uint32_t len:16;    /* length of RTCP packet */
        uint32_t ssrc;      /* synchronization source identifier of packet send */
        uint32_t timestampMSB;      /* timestamp MSB */
        uint32_t timestampLSB;      /* timestamp LSB */
        uint32_t timestampRTP;      /* RTP timestamp */
        uint32_t spc;       /* Sender's packet count */
        uint32_t soc;       /* Sender's octet count */
    } rtcpSRHeader;
    
    
    class SocketPair {
        public:
            SocketPair(const char* uri, int localPort);
            SocketPair(std::unique_ptr<IceSocket> rtp_sock,
                       std::unique_ptr<IceSocket> rtcp_sock);
            ~SocketPair();
    
            void interrupt();
    
            MediaIOHandle* createIOContext(const uint16_t mtu);
    
            void openSockets(const char* uri, int localPort);
            void closeSockets();
    
            /*
               Supported suites are:
    
               AES_CM_128_HMAC_SHA1_80
               SRTP_AES128_CM_HMAC_SHA1_80
               AES_CM_128_HMAC_SHA1_32
               SRTP_AES128_CM_HMAC_SHA1_3
    
               Example (unsecure) usage:
               createSRTP("AES_CM_128_HMAC_SHA1_80",
                          "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmn",
                          "AES_CM_128_HMAC_SHA1_80",
                          "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmn");
    
               Will throw an std::runtime_error on failure, should be handled at a higher level
            */
            void createSRTP(const char* out_suite, const char* out_params,
                            const char* in_suite, const char* in_params);
    
            void stopSendOp(bool state = true);
            std::list<rtcpRRHeader> getRtcpInfo();
    
            bool waitForRTCP(std::chrono::seconds interval);
            double getLastLatency();
    
        private:
            NON_COPYABLE(SocketPair);
    
            int readCallback(uint8_t* buf, int buf_size);
            int writeCallback(uint8_t* buf, int buf_size);
    
            int waitForData();
            int readRtpData(void* buf, int buf_size);
            int readRtcpData(void* buf, int buf_size);
            int writeData(uint8_t* buf, int buf_size);
            void saveRtcpPacket(uint8_t* buf, size_t len);
    
            std::mutex dataBuffMutex_;
            std::condition_variable cv_;
            std::list<std::vector<uint8_t>> rtpDataBuff_;
            std::list<std::vector<uint8_t>> rtcpDataBuff_;
    
            std::unique_ptr<IceSocket> rtp_sock_;
            std::unique_ptr<IceSocket> rtcp_sock_;
    
            int rtpHandle_ {-1};
            int rtcpHandle_ {-1};
            IpAddr rtpDestAddr_;
            IpAddr rtcpDestAddr_;
            std::atomic_bool interrupted_ {false};
            std::atomic_bool noWrite_ {false};
            std::unique_ptr<SRTPProtoContext> srtpContext_;
    
            std::list<rtcpRRHeader> listRtcpHeader_;
            std::mutex rtcpInfo_mutex_;
            std::condition_variable cvRtcpPacketReadyToRead_;
            static constexpr unsigned MAX_LIST_SIZE {10};
    
            mutable std::atomic_bool rtcpPacketLoss_ {false};
            double lastSRTS_;
            uint32_t lastDLSR_;
    
            std::list<double> histoLatency_;
    
            std::chrono::steady_clock::time_point lastRR_time;
    };
    
    
    } // namespace jami