#ifndef RTC_DTLS_TRANSPORT_H
#define RTC_DTLS_TRANSPORT_H
#include "certificate.hpp"
#include "include.hpp"
#include "peerconnection.hpp"
#include "queue.hpp"
#include "tls.hpp"
#include "transport.hpp"
#include <atomic>
#include <functional>
#include <memory>
#include <mutex>
#include <thread>
namespace rtc {
class IceTransport;
class DtlsTransport : public Transport {
public:
static void Init();
static void Cleanup();
using verifier_callback = std::function<bool(const std::string &fingerprint)>;
DtlsTransport(std::shared_ptr<IceTransport> lower, certificate_ptr certificate,
verifier_callback verifierCallback, state_callback stateChangeCallback);
~DtlsTransport();
virtual void start() override;
virtual bool stop() override;
virtual bool send(message_ptr message) override;
protected:
virtual void incoming(message_ptr message) override;
virtual bool outgoing(message_ptr message) override;
virtual void postHandshake();
void runRecvLoop();
const certificate_ptr mCertificate;
const verifier_callback mVerifierCallback;
const bool mIsClient;
Queue<message_ptr> mIncomingQueue;
std::thread mRecvThread;
std::atomic<unsigned int> mCurrentDscp;
#if USE_GNUTLS
gnutls_session_t mSession;
static int CertificateCallback(gnutls_session_t session);
static ssize_t WriteCallback(gnutls_transport_ptr_t ptr, const void *data, size_t len);
static ssize_t ReadCallback(gnutls_transport_ptr_t ptr, void *data, size_t maxlen);
static int TimeoutCallback(gnutls_transport_ptr_t ptr, unsigned int ms);
#else
SSL_CTX *mCtx = NULL;
SSL *mSsl = NULL;
BIO *mInBio, *mOutBio;
static BIO_METHOD *BioMethods;
static int TransportExIndex;
static std::mutex GlobalMutex;
static int CertificateCallback(int preverify_ok, X509_STORE_CTX *ctx);
static void InfoCallback(const SSL *ssl, int where, int ret);
static int BioMethodNew(BIO *bio);
static int BioMethodFree(BIO *bio);
static int BioMethodWrite(BIO *bio, const char *in, int inl);
static long BioMethodCtrl(BIO *bio, int cmd, long num, void *ptr);
#endif
};
}
#endif