Fix Cygwin compilation:
- Fix various incompatibilities and differences between Linux and Cygwin builds - Make usrsctp an optional dependency - Fix building without SSL - Add new secure random bytes function, use it for websockets - Switch to libsrtp2 v2.6.0 (currently latest release) - Add patch that makes latest libsrtp2 build in latest Cygwin - Add patch that makes srt build in latest Cygwin - Correctly allow linking libsrtp2 and srt to local mbedtls version
This commit is contained in:
parent
db30be38c5
commit
dbafa808b8
23 changed files with 131 additions and 23 deletions
|
@ -927,7 +927,9 @@ void Util::getMyExec(std::deque<std::string> &execs){
|
||||||
WIN32_FIND_DATA FindFileData;
|
WIN32_FIND_DATA FindFileData;
|
||||||
HANDLE hdl = FindFirstFile(path.c_str(), &FindFileData);
|
HANDLE hdl = FindFirstFile(path.c_str(), &FindFileData);
|
||||||
while (hdl != INVALID_HANDLE_VALUE){
|
while (hdl != INVALID_HANDLE_VALUE){
|
||||||
|
if (!(FindFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)){
|
||||||
execs.push_back(FindFileData.cFileName);
|
execs.push_back(FindFileData.cFileName);
|
||||||
|
}
|
||||||
if (!FindNextFile(hdl, &FindFileData)){
|
if (!FindNextFile(hdl, &FindFileData)){
|
||||||
FindClose(hdl);
|
FindClose(hdl);
|
||||||
hdl = INVALID_HANDLE_VALUE;
|
hdl = INVALID_HANDLE_VALUE;
|
||||||
|
|
|
@ -13,7 +13,6 @@ headers = [
|
||||||
'config.h',
|
'config.h',
|
||||||
'defines.h',
|
'defines.h',
|
||||||
'dtsc.h',
|
'dtsc.h',
|
||||||
'encryption.h',
|
|
||||||
'flv_tag.h',
|
'flv_tag.h',
|
||||||
'h264.h',
|
'h264.h',
|
||||||
'h265.h',
|
'h265.h',
|
||||||
|
@ -63,14 +62,15 @@ if have_srt
|
||||||
headers += 'socket_srt.h'
|
headers += 'socket_srt.h'
|
||||||
endif
|
endif
|
||||||
|
|
||||||
install_headers(headers, subdir: 'mist')
|
|
||||||
|
|
||||||
extra_code = []
|
extra_code = []
|
||||||
|
|
||||||
if usessl
|
if usessl
|
||||||
|
headers += 'encryption.h'
|
||||||
extra_code += ['stun.cpp', 'certificate.cpp', 'encryption.cpp',]
|
extra_code += ['stun.cpp', 'certificate.cpp', 'encryption.cpp',]
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
install_headers(headers, subdir: 'mist')
|
||||||
|
|
||||||
libmist = library('mist',
|
libmist = library('mist',
|
||||||
'adts.cpp',
|
'adts.cpp',
|
||||||
'amf.cpp',
|
'amf.cpp',
|
||||||
|
|
|
@ -592,7 +592,7 @@ namespace IPC{
|
||||||
unmap();
|
unmap();
|
||||||
if (handle > 0){
|
if (handle > 0){
|
||||||
::close(handle);
|
::close(handle);
|
||||||
if (master && name != ""){unlink(name.c_str());}
|
if (master && name != ""){unlink(std::string(Util::getTmpFolder() + name).c_str());}
|
||||||
handle = 0;
|
handle = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1605,6 +1605,7 @@ int Socket::Server::getSocket(){
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef SSL
|
||||||
static int dTLS_recv(void *s, unsigned char *buf, size_t len){
|
static int dTLS_recv(void *s, unsigned char *buf, size_t len){
|
||||||
return ((Socket::UDPConnection*)s)->dTLSRead(buf, len);
|
return ((Socket::UDPConnection*)s)->dTLSRead(buf, len);
|
||||||
}
|
}
|
||||||
|
@ -1612,6 +1613,7 @@ static int dTLS_recv(void *s, unsigned char *buf, size_t len){
|
||||||
static int dTLS_send(void *s, const unsigned char *buf, size_t len){
|
static int dTLS_send(void *s, const unsigned char *buf, size_t len){
|
||||||
return ((Socket::UDPConnection*)s)->dTLSWrite(buf, len);
|
return ((Socket::UDPConnection*)s)->dTLSWrite(buf, len);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/// Create a new UDP Socket.
|
/// Create a new UDP Socket.
|
||||||
|
@ -1680,6 +1682,7 @@ static int dtlsExtractKeyData( void *user, const unsigned char *ms, const unsign
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef SSL
|
||||||
void Socket::UDPConnection::initDTLS(mbedtls_x509_crt *cert, mbedtls_pk_context *key){
|
void Socket::UDPConnection::initDTLS(mbedtls_x509_crt *cert, mbedtls_pk_context *key){
|
||||||
hasDTLS = true;
|
hasDTLS = true;
|
||||||
nextDTLSRead = 0;
|
nextDTLSRead = 0;
|
||||||
|
@ -1825,6 +1828,7 @@ void Socket::UDPConnection::dTLSReset(){
|
||||||
WARN_MSG("dTLS could not set transport ID: %s", mbedtls_msg);
|
WARN_MSG("dTLS could not set transport ID: %s", mbedtls_msg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif //if SSL
|
||||||
|
|
||||||
///Checks if the UDP receive buffer is at least 1 mbyte, attempts to increase and warns user through log message on failure.
|
///Checks if the UDP receive buffer is at least 1 mbyte, attempts to increase and warns user through log message on failure.
|
||||||
void Socket::UDPConnection::checkRecvBuf(){
|
void Socket::UDPConnection::checkRecvBuf(){
|
||||||
|
@ -1913,7 +1917,9 @@ Socket::UDPConnection::~UDPConnection(){
|
||||||
free(recvAddr);
|
free(recvAddr);
|
||||||
recvAddr = 0;
|
recvAddr = 0;
|
||||||
}
|
}
|
||||||
|
#ifdef SSL
|
||||||
deinitDTLS();
|
deinitDTLS();
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -2175,6 +2181,7 @@ void Socket::UDPConnection::SendNow(const char *sdata, size_t len, sockaddr * dA
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
#if !defined(__CYGWIN__) && !defined(_WIN32)
|
||||||
if (hasReceiveData && recvAddr){
|
if (hasReceiveData && recvAddr){
|
||||||
msghdr mHdr;
|
msghdr mHdr;
|
||||||
char msg_control[0x100];
|
char msg_control[0x100];
|
||||||
|
@ -2209,13 +2216,16 @@ void Socket::UDPConnection::SendNow(const char *sdata, size_t len, sockaddr * dA
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}else{
|
}else{
|
||||||
|
#endif
|
||||||
int r = sendto(sock, sdata, len, 0, dAddr, dAddrLen);
|
int r = sendto(sock, sdata, len, 0, dAddr, dAddrLen);
|
||||||
if (r > 0){
|
if (r > 0){
|
||||||
up += r;
|
up += r;
|
||||||
}else{
|
}else{
|
||||||
FAIL_MSG("Could not send UDP data through %d: %s", sock, strerror(errno));
|
FAIL_MSG("Could not send UDP data through %d: %s", sock, strerror(errno));
|
||||||
}
|
}
|
||||||
|
#if !defined(__CYGWIN__) && !defined(_WIN32)
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Queues sdata, len for sending over this socket.
|
/// Queues sdata, len for sending over this socket.
|
||||||
|
@ -2223,6 +2233,7 @@ void Socket::UDPConnection::SendNow(const char *sdata, size_t len, sockaddr * dA
|
||||||
/// Warning: never call sendPaced for the same socket from a different thread!
|
/// Warning: never call sendPaced for the same socket from a different thread!
|
||||||
/// Note: Only actually encrypts if initDTLS was called in the past.
|
/// Note: Only actually encrypts if initDTLS was called in the past.
|
||||||
void Socket::UDPConnection::sendPaced(const char *sdata, size_t len, bool encrypt){
|
void Socket::UDPConnection::sendPaced(const char *sdata, size_t len, bool encrypt){
|
||||||
|
#ifdef SSL
|
||||||
if (hasDTLS && encrypt){
|
if (hasDTLS && encrypt){
|
||||||
#if MBEDTLS_VERSION_MAJOR > 2
|
#if MBEDTLS_VERSION_MAJOR > 2
|
||||||
if (!mbedtls_ssl_is_handshake_over(&ssl_ctx)){
|
if (!mbedtls_ssl_is_handshake_over(&ssl_ctx)){
|
||||||
|
@ -2235,6 +2246,7 @@ void Socket::UDPConnection::sendPaced(const char *sdata, size_t len, bool encryp
|
||||||
int write = mbedtls_ssl_write(&ssl_ctx, (unsigned char*)sdata, len);
|
int write = mbedtls_ssl_write(&ssl_ctx, (unsigned char*)sdata, len);
|
||||||
if (write <= 0){WARN_MSG("Could not write DTLS packet!");}
|
if (write <= 0){WARN_MSG("Could not write DTLS packet!");}
|
||||||
}else{
|
}else{
|
||||||
|
#endif
|
||||||
if (!paceQueue.size() && (!lastPace || Util::getMicros(lastPace) > 10000)){
|
if (!paceQueue.size() && (!lastPace || Util::getMicros(lastPace) > 10000)){
|
||||||
SendNow(sdata, len);
|
SendNow(sdata, len);
|
||||||
lastPace = Util::getMicros();
|
lastPace = Util::getMicros();
|
||||||
|
@ -2244,7 +2256,9 @@ void Socket::UDPConnection::sendPaced(const char *sdata, size_t len, bool encryp
|
||||||
// Try to send a packet, if time allows
|
// Try to send a packet, if time allows
|
||||||
//sendPaced(0);
|
//sendPaced(0);
|
||||||
}
|
}
|
||||||
|
#ifdef SSL
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
// Gets time in microseconds until next sendPaced call would send something
|
// Gets time in microseconds until next sendPaced call would send something
|
||||||
|
@ -2621,6 +2635,7 @@ bool Socket::UDPConnection::Receive(){
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (destAddr && destsize && destAddr_size >= destsize){memcpy(destAddr, &addr, destsize);}
|
if (destAddr && destsize && destAddr_size >= destsize){memcpy(destAddr, &addr, destsize);}
|
||||||
|
#if !defined(__CYGWIN__) && !defined(_WIN32)
|
||||||
if (recvAddr){
|
if (recvAddr){
|
||||||
for ( struct cmsghdr *cmsg = CMSG_FIRSTHDR(&mHdr); cmsg != NULL; cmsg = CMSG_NXTHDR(&mHdr, cmsg)){
|
for ( struct cmsghdr *cmsg = CMSG_FIRSTHDR(&mHdr); cmsg != NULL; cmsg = CMSG_NXTHDR(&mHdr, cmsg)){
|
||||||
if (cmsg->cmsg_level != IPPROTO_IP || cmsg->cmsg_type != IP_PKTINFO){continue;}
|
if (cmsg->cmsg_level != IPPROTO_IP || cmsg->cmsg_type != IP_PKTINFO){continue;}
|
||||||
|
@ -2633,6 +2648,7 @@ bool Socket::UDPConnection::Receive(){
|
||||||
hasReceiveData = true;
|
hasReceiveData = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
data.append(0, r);
|
data.append(0, r);
|
||||||
down += r;
|
down += r;
|
||||||
//Handle UDP packets that are too large
|
//Handle UDP packets that are too large
|
||||||
|
@ -2646,8 +2662,9 @@ bool Socket::UDPConnection::Receive(){
|
||||||
bool Socket::UDPConnection::onData(){
|
bool Socket::UDPConnection::onData(){
|
||||||
wasEncrypted = false;
|
wasEncrypted = false;
|
||||||
if (!data.size()){return false;}
|
if (!data.size()){return false;}
|
||||||
uint8_t fb = 0;
|
|
||||||
int r = data.size();
|
int r = data.size();
|
||||||
|
#ifdef SSL
|
||||||
|
uint8_t fb = 0;
|
||||||
if (r){fb = (uint8_t)data[0];}
|
if (r){fb = (uint8_t)data[0];}
|
||||||
if (r && hasDTLS && fb > 19 && fb < 64){
|
if (r && hasDTLS && fb > 19 && fb < 64){
|
||||||
if (nextDTLSReadLen){
|
if (nextDTLSReadLen){
|
||||||
|
@ -2761,6 +2778,7 @@ bool Socket::UDPConnection::onData(){
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
return r > 0;
|
return r > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -237,12 +237,14 @@ namespace Socket{
|
||||||
bool hasDTLS; ///< True if dTLS is enabled
|
bool hasDTLS; ///< True if dTLS is enabled
|
||||||
void * nextDTLSRead;
|
void * nextDTLSRead;
|
||||||
size_t nextDTLSReadLen;
|
size_t nextDTLSReadLen;
|
||||||
|
#ifdef SSL
|
||||||
mbedtls_entropy_context entropy_ctx;
|
mbedtls_entropy_context entropy_ctx;
|
||||||
mbedtls_ctr_drbg_context rand_ctx;
|
mbedtls_ctr_drbg_context rand_ctx;
|
||||||
mbedtls_ssl_context ssl_ctx;
|
mbedtls_ssl_context ssl_ctx;
|
||||||
mbedtls_ssl_config ssl_conf;
|
mbedtls_ssl_config ssl_conf;
|
||||||
mbedtls_ssl_cookie_ctx cookie_ctx;
|
mbedtls_ssl_cookie_ctx cookie_ctx;
|
||||||
mbedtls_timing_delay_context timer_ctx;
|
mbedtls_timing_delay_context timer_ctx;
|
||||||
|
#endif
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Util::ResizeablePointer data;
|
Util::ResizeablePointer data;
|
||||||
|
@ -251,11 +253,13 @@ namespace Socket{
|
||||||
~UDPConnection();
|
~UDPConnection();
|
||||||
bool operator==(const UDPConnection& b) const;
|
bool operator==(const UDPConnection& b) const;
|
||||||
operator bool() const;
|
operator bool() const;
|
||||||
|
#ifdef SSL
|
||||||
void initDTLS(mbedtls_x509_crt *cert, mbedtls_pk_context *key);
|
void initDTLS(mbedtls_x509_crt *cert, mbedtls_pk_context *key);
|
||||||
void deinitDTLS();
|
void deinitDTLS();
|
||||||
int dTLSRead(unsigned char *buf, size_t len);
|
int dTLSRead(unsigned char *buf, size_t len);
|
||||||
int dTLSWrite(const unsigned char *buf, size_t len);
|
int dTLSWrite(const unsigned char *buf, size_t len);
|
||||||
void dTLSReset();
|
void dTLSReset();
|
||||||
|
#endif
|
||||||
bool wasEncrypted;
|
bool wasEncrypted;
|
||||||
void close();
|
void close();
|
||||||
int getSock();
|
int getSock();
|
||||||
|
@ -281,12 +285,15 @@ namespace Socket{
|
||||||
size_t timeToNextPace(uint64_t uTime = 0);
|
size_t timeToNextPace(uint64_t uTime = 0);
|
||||||
void setSocketFamily(int AF_TYPE);
|
void setSocketFamily(int AF_TYPE);
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef SSL
|
||||||
// dTLS-related public members
|
// dTLS-related public members
|
||||||
std::string cipher, remote_key, local_key, remote_salt, local_salt;
|
std::string cipher, remote_key, local_key, remote_salt, local_salt;
|
||||||
#if HAVE_UPSTREAM_MBEDTLS_SRTP
|
#if HAVE_UPSTREAM_MBEDTLS_SRTP
|
||||||
unsigned char master_secret[48];
|
unsigned char master_secret[48];
|
||||||
unsigned char randbytes[64];
|
unsigned char randbytes[64];
|
||||||
mbedtls_tls_prf_types tls_prf_type;
|
mbedtls_tls_prf_types tls_prf_type;
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
}// namespace Socket
|
}// namespace Socket
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/// \file timing.cpp
|
/// \file timing.cpp
|
||||||
/// Utilities for handling time and timestamps.
|
/// Utilities for handling time and timestamps.
|
||||||
|
#define _XOPEN_SOURCE // Ensures strptime works in Cygwin
|
||||||
#include "timing.h"
|
#include "timing.h"
|
||||||
#include <cstdio>
|
#include <cstdio>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
|
|
17
lib/util.cpp
17
lib/util.cpp
|
@ -303,6 +303,16 @@ namespace Util{
|
||||||
return w;
|
return w;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Secure random bytes generator
|
||||||
|
/// Uses /dev/urandom internally
|
||||||
|
void getRandomBytes(void * dest, size_t len){
|
||||||
|
static FILE * randSource = fopen("/dev/urandom", "rb");
|
||||||
|
if (fread((void *)dest, len, 1, randSource) != 1){
|
||||||
|
WARN_MSG("Reading random data failed - generating using rand() as backup");
|
||||||
|
for (size_t i = 0; i < len; ++i){((char*)dest)[i] = rand() % 255;}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// 64-bits version of ftell
|
/// 64-bits version of ftell
|
||||||
uint64_t ftell(FILE *stream){
|
uint64_t ftell(FILE *stream){
|
||||||
/// \TODO Windows implementation (e.g. _ftelli64 ?)
|
/// \TODO Windows implementation (e.g. _ftelli64 ?)
|
||||||
|
@ -374,7 +384,12 @@ namespace Util{
|
||||||
|
|
||||||
bool ResizeablePointer::allocate(uint32_t l){
|
bool ResizeablePointer::allocate(uint32_t l){
|
||||||
if (l > maxSize){
|
if (l > maxSize){
|
||||||
void *tmp = realloc(ptr, l);
|
void *tmp = 0;
|
||||||
|
if (!ptr){
|
||||||
|
tmp = malloc(l);
|
||||||
|
}else{
|
||||||
|
tmp = realloc(ptr, l);
|
||||||
|
}
|
||||||
if (!tmp){
|
if (!tmp){
|
||||||
FAIL_MSG("Could not allocate %" PRIu32 " bytes of memory", l);
|
FAIL_MSG("Could not allocate %" PRIu32 " bytes of memory", l);
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -20,6 +20,8 @@ namespace Util{
|
||||||
|
|
||||||
int64_t expBackoffMs(const size_t currIter, const size_t maxIter, const int64_t maxWait);
|
int64_t expBackoffMs(const size_t currIter, const size_t maxIter, const int64_t maxWait);
|
||||||
|
|
||||||
|
void getRandomBytes(void * dest, size_t len);
|
||||||
|
|
||||||
uint64_t ftell(FILE *stream);
|
uint64_t ftell(FILE *stream);
|
||||||
uint64_t fseek(FILE *stream, uint64_t offset, int whence);
|
uint64_t fseek(FILE *stream, uint64_t offset, int whence);
|
||||||
|
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
#include "mbedtls/sha1.h"
|
#include "mbedtls/sha1.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef SSL
|
||||||
// Takes the data from a Sec-WebSocket-Key header, and returns the corresponding data for a Sec-WebSocket-Accept header
|
// Takes the data from a Sec-WebSocket-Key header, and returns the corresponding data for a Sec-WebSocket-Accept header
|
||||||
static std::string calculateKeyAccept(std::string client_key){
|
static std::string calculateKeyAccept(std::string client_key){
|
||||||
client_key += "258EAFA5-E914-47DA-95CA-C5AB0DC85B11";
|
client_key += "258EAFA5-E914-47DA-95CA-C5AB0DC85B11";
|
||||||
|
@ -18,6 +19,7 @@ static std::string calculateKeyAccept(std::string client_key){
|
||||||
mbedtls_sha1_finish(&ctx, outdata);
|
mbedtls_sha1_finish(&ctx, outdata);
|
||||||
return Encodings::Base64::encode(std::string((const char *)outdata, 20));
|
return Encodings::Base64::encode(std::string((const char *)outdata, 20));
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
namespace HTTP{
|
namespace HTTP{
|
||||||
|
|
||||||
|
@ -33,12 +35,9 @@ namespace HTTP{
|
||||||
//Ensure our passed socket gets used by the downloader class
|
//Ensure our passed socket gets used by the downloader class
|
||||||
d.setSocket(&C);
|
d.setSocket(&C);
|
||||||
|
|
||||||
//Generate a random nonce based on the current process ID
|
//Generate a random nonce
|
||||||
//Note: This is not cryptographically secure, nor intended to be.
|
|
||||||
//It does make it possible to trace which stream came from which PID, if needed.
|
|
||||||
char nonce[16];
|
char nonce[16];
|
||||||
unsigned int state = getpid();
|
Util::getRandomBytes(nonce, 16);
|
||||||
for (size_t i = 0; i < 16; ++i){nonce[i] = rand_r(&state) % 255;}
|
|
||||||
std::string handshakeKey = Encodings::Base64::encode(std::string(nonce, 16));
|
std::string handshakeKey = Encodings::Base64::encode(std::string(nonce, 16));
|
||||||
|
|
||||||
//Prepare the headers
|
//Prepare the headers
|
||||||
|
|
17
meson.build
17
meson.build
|
@ -99,9 +99,9 @@ message('Building release @0@ for version @1@ @ debug level @2@'.format(release,
|
||||||
# Set dependencies
|
# Set dependencies
|
||||||
|
|
||||||
mist_deps = []
|
mist_deps = []
|
||||||
|
ccpp = meson.get_compiler('cpp')
|
||||||
|
|
||||||
if usessl
|
if usessl
|
||||||
ccpp = meson.get_compiler('cpp')
|
|
||||||
mbedtls = ccpp.find_library('mbedtls', required: false)
|
mbedtls = ccpp.find_library('mbedtls', required: false)
|
||||||
mbedx509 = ccpp.find_library('mbedx509', required: false)
|
mbedx509 = ccpp.find_library('mbedx509', required: false)
|
||||||
mbedcrypto = ccpp.find_library('mbedcrypto', required: false)
|
mbedcrypto = ccpp.find_library('mbedcrypto', required: false)
|
||||||
|
@ -141,9 +141,16 @@ if usessl
|
||||||
|
|
||||||
endif
|
endif
|
||||||
mist_deps += [mbedtls, mbedx509, mbedcrypto]
|
mist_deps += [mbedtls, mbedx509, mbedcrypto]
|
||||||
mist_deps += dependency('libsrtp2', default_options: ['tests=disabled'], fallback: ['libsrtp2', 'libsrtp2_dep'])
|
mist_deps += dependency('libsrtp2', default_options: ['tests=disabled', 'crypto-library=mbedtls'], fallback: ['libsrtp2', 'libsrtp2_dep'])
|
||||||
|
|
||||||
|
usrsctp_dep = false
|
||||||
|
if not get_option('NOUSRSCTP') and host_machine.system() != 'cygwin'
|
||||||
usrsctp_dep = dependency('usrsctp', fallback: ['usrsctp', 'usrsctp_dep'])
|
usrsctp_dep = dependency('usrsctp', fallback: ['usrsctp', 'usrsctp_dep'])
|
||||||
|
endif
|
||||||
|
have_usrsctp = not get_option('NOUSRSCTP') and host_machine.system() != 'cygwin' and usrsctp_dep.found()
|
||||||
|
if have_usrsctp
|
||||||
|
option_defines += '-DWITH_DATACHANNELS'
|
||||||
|
endif
|
||||||
endif
|
endif
|
||||||
|
|
||||||
libsrt = false
|
libsrt = false
|
||||||
|
@ -169,6 +176,12 @@ if not get_option('NOSHM') and host_machine.system() != 'darwin'
|
||||||
mist_deps += ccpp.find_library('rt', required : true)
|
mist_deps += ccpp.find_library('rt', required : true)
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
#
|
||||||
|
if host_machine.system() == 'cygwin'
|
||||||
|
option_defines += ['-D_POSIX_C_SOURCE=200112L', '-D_GNU_SOURCE', '-D_TTHREAD_POSIX_', '-D_TTHREAD_PLATFORM_DEFINED_']
|
||||||
|
option_defines += '-D_GNU_SOURCE'
|
||||||
|
endif
|
||||||
|
|
||||||
# Set defines from active options
|
# Set defines from active options
|
||||||
add_project_arguments(option_defines, language: 'cpp')
|
add_project_arguments(option_defines, language: 'cpp')
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
option('NOSHM', description: 'Disabled shared memory (falling back to shared temporary files)', type : 'boolean', value : false)
|
option('NOSHM', description: 'Disabled shared memory (falling back to shared temporary files)', type : 'boolean', value : false)
|
||||||
option('NOSSL', description: 'Disable SSL/TLS support', type : 'boolean', value : false)
|
option('NOSSL', description: 'Disable SSL/TLS support', type : 'boolean', value : false)
|
||||||
|
option('NOUSRSCTP', description: 'Disable usrsctp (WebRTC data channels) support', type : 'boolean', value : false)
|
||||||
option('NOUPDATE', description: 'Disable the updater', type : 'boolean', value : false)
|
option('NOUPDATE', description: 'Disable the updater', type : 'boolean', value : false)
|
||||||
option('NOAUTH', description: 'Disable API authentication entirely (insecure!)', type : 'boolean', value : false)
|
option('NOAUTH', description: 'Disable API authentication entirely (insecure!)', type : 'boolean', value : false)
|
||||||
option('WITH_THREADNAMES', description: 'Enable fancy names for threads (not supported on all platforms)', type : 'boolean', value : false)
|
option('WITH_THREADNAMES', description: 'Enable fancy names for threads (not supported on all platforms)', type : 'boolean', value : false)
|
||||||
|
|
|
@ -1121,7 +1121,7 @@ void Controller::statOnDisconnect(size_t id){
|
||||||
dataPage.init(userPageName, 1, false, false);
|
dataPage.init(userPageName, 1, false, false);
|
||||||
if(dataPage){
|
if(dataPage){
|
||||||
// Session likely crashed while it was running
|
// Session likely crashed while it was running
|
||||||
dataPage.init(userPageName, 1, true);
|
dataPage.master = true;
|
||||||
FAIL_MSG("Session '%s' got cancelled unexpectedly. Cleaning up the leftovers...", thisSessionId.c_str());
|
FAIL_MSG("Session '%s' got cancelled unexpectedly. Cleaning up the leftovers...", thisSessionId.c_str());
|
||||||
}
|
}
|
||||||
// Finally remove the session lock which was created on bootup of the session
|
// Finally remove the session lock which was created on bootup of the session
|
||||||
|
|
|
@ -1604,6 +1604,7 @@ namespace Mist{
|
||||||
if (connectedUsers || isAlwaysOn()){activityCounter = Util::bootSecs();}
|
if (connectedUsers || isAlwaysOn()){activityCounter = Util::bootSecs();}
|
||||||
if (thisTime >= lastBuffered){
|
if (thisTime >= lastBuffered){
|
||||||
if (sourceIdx != idx){
|
if (sourceIdx != idx){
|
||||||
|
#ifdef SSL
|
||||||
if (encryption.find(":") != std::string::npos || M.getEncryption(idx).find(":") != std::string::npos){
|
if (encryption.find(":") != std::string::npos || M.getEncryption(idx).find(":") != std::string::npos){
|
||||||
if (encryption == ""){
|
if (encryption == ""){
|
||||||
encryption = M.getEncryption(idx);
|
encryption = M.getEncryption(idx);
|
||||||
|
@ -1622,8 +1623,11 @@ namespace Mist{
|
||||||
thisPacket = encPacket;
|
thisPacket = encPacket;
|
||||||
}
|
}
|
||||||
}else{
|
}else{
|
||||||
|
#endif
|
||||||
thisPacket = DTSC::Packet(thisPacket, idx);
|
thisPacket = DTSC::Packet(thisPacket, idx);
|
||||||
|
#ifdef SSL
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
//Sanity check: are we matching the key's data size?
|
//Sanity check: are we matching the key's data size?
|
||||||
if (thisPacket.getFlag("keyframe")){
|
if (thisPacket.getFlag("keyframe")){
|
||||||
|
|
|
@ -5,13 +5,16 @@
|
||||||
#include <mist/config.h>
|
#include <mist/config.h>
|
||||||
#include <mist/defines.h>
|
#include <mist/defines.h>
|
||||||
#include <mist/dtsc.h>
|
#include <mist/dtsc.h>
|
||||||
#include <mist/encryption.h>
|
|
||||||
#include <mist/json.h>
|
#include <mist/json.h>
|
||||||
#include <mist/shared_memory.h>
|
#include <mist/shared_memory.h>
|
||||||
#include <mist/timing.h>
|
#include <mist/timing.h>
|
||||||
#include <mist/url.h>
|
#include <mist/url.h>
|
||||||
#include <set>
|
#include <set>
|
||||||
|
|
||||||
|
#ifdef SSL
|
||||||
|
#include <mist/encryption.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "../io.h"
|
#include "../io.h"
|
||||||
|
|
||||||
namespace Mist{
|
namespace Mist{
|
||||||
|
@ -110,7 +113,9 @@ namespace Mist{
|
||||||
Comms::Users users;
|
Comms::Users users;
|
||||||
size_t connectedUsers;
|
size_t connectedUsers;
|
||||||
|
|
||||||
|
#ifdef SSL
|
||||||
Encryption::AES aesCipher;
|
Encryption::AES aesCipher;
|
||||||
|
#endif
|
||||||
|
|
||||||
IPC::sharedPage streamStatus;
|
IPC::sharedPage streamStatus;
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
#include "input_hls.h"
|
#include "input_hls.h"
|
||||||
|
#ifdef SSL
|
||||||
#include "mbedtls/aes.h"
|
#include "mbedtls/aes.h"
|
||||||
|
#endif
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <cerrno>
|
#include <cerrno>
|
||||||
#include <cstdio>
|
#include <cstdio>
|
||||||
|
|
|
@ -67,7 +67,9 @@ namespace Mist{
|
||||||
Util::ResizeablePointer * currBuf;
|
Util::ResizeablePointer * currBuf;
|
||||||
size_t encOffset;
|
size_t encOffset;
|
||||||
unsigned char tmpIvec[16];
|
unsigned char tmpIvec[16];
|
||||||
|
#ifdef SSL
|
||||||
mbedtls_aes_context aes;
|
mbedtls_aes_context aes;
|
||||||
|
#endif
|
||||||
bool isOpen;
|
bool isOpen;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -91,8 +91,10 @@ foreach output : outputs
|
||||||
endif
|
endif
|
||||||
if extra.contains('srtp')
|
if extra.contains('srtp')
|
||||||
sources += files('output_webrtc_srtp.cpp', 'output_webrtc_srtp.h')
|
sources += files('output_webrtc_srtp.cpp', 'output_webrtc_srtp.h')
|
||||||
|
if have_usrsctp
|
||||||
deps += usrsctp_dep
|
deps += usrsctp_dep
|
||||||
endif
|
endif
|
||||||
|
endif
|
||||||
if extra.contains('embed')
|
if extra.contains('embed')
|
||||||
sources += embed_tgts
|
sources += embed_tgts
|
||||||
endif
|
endif
|
||||||
|
|
|
@ -36,6 +36,7 @@ namespace Mist{
|
||||||
static void onRTPPacketizerHasDataCallback(void *socket, const char *data, size_t len, uint8_t channel);
|
static void onRTPPacketizerHasDataCallback(void *socket, const char *data, size_t len, uint8_t channel);
|
||||||
static void onRTPPacketizerHasRTCPDataCallback(void *socket, const char *data, size_t nbytes, uint8_t channel);
|
static void onRTPPacketizerHasRTCPDataCallback(void *socket, const char *data, size_t nbytes, uint8_t channel);
|
||||||
|
|
||||||
|
#ifdef WITH_DATACHANNELS
|
||||||
static int sctp_recv_cb(struct socket *s, union sctp_sockstore addr, void *data, size_t datalen, struct sctp_rcvinfo rcv, int flags, void *ulp_info){
|
static int sctp_recv_cb(struct socket *s, union sctp_sockstore addr, void *data, size_t datalen, struct sctp_rcvinfo rcv, int flags, void *ulp_info){
|
||||||
if (data) {
|
if (data) {
|
||||||
if (!(flags & MSG_NOTIFICATION)){
|
if (!(flags & MSG_NOTIFICATION)){
|
||||||
|
@ -61,6 +62,7 @@ namespace Mist{
|
||||||
va_end(args);
|
va_end(args);
|
||||||
INFO_MSG("sctp: %s", msg);
|
INFO_MSG("sctp: %s", msg);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
WebRTCSocket::WebRTCSocket(){
|
WebRTCSocket::WebRTCSocket(){
|
||||||
udpSock = 0;
|
udpSock = 0;
|
||||||
|
@ -132,8 +134,10 @@ namespace Mist{
|
||||||
/* ------------------------------------------------ */
|
/* ------------------------------------------------ */
|
||||||
|
|
||||||
OutWebRTC::OutWebRTC(Socket::Connection &myConn) : HTTPOutput(myConn){
|
OutWebRTC::OutWebRTC(Socket::Connection &myConn) : HTTPOutput(myConn){
|
||||||
|
#ifdef WITH_DATACHANNELS
|
||||||
sctpInited = false;
|
sctpInited = false;
|
||||||
sctpConnected = false;
|
sctpConnected = false;
|
||||||
|
#endif
|
||||||
noSignalling = false;
|
noSignalling = false;
|
||||||
totalPkts = 0;
|
totalPkts = 0;
|
||||||
totalLoss = 0;
|
totalLoss = 0;
|
||||||
|
@ -1170,6 +1174,7 @@ namespace Mist{
|
||||||
|
|
||||||
if (wSock.udpSock->data.size() && wSock.udpSock->wasEncrypted){
|
if (wSock.udpSock->data.size() && wSock.udpSock->wasEncrypted){
|
||||||
lastRecv = Util::bootMS();
|
lastRecv = Util::bootMS();
|
||||||
|
#ifdef WITH_DATACHANNELS
|
||||||
if (packetLog.is_open()){
|
if (packetLog.is_open()){
|
||||||
packetLog << "[" << Util::bootMS() << "]" << "SCTP packet (" << wSock.udpSock->data.size() << "b): " << std::endl;
|
packetLog << "[" << Util::bootMS() << "]" << "SCTP packet (" << wSock.udpSock->data.size() << "b): " << std::endl;
|
||||||
char * buffer = usrsctp_dumppacket(wSock.udpSock->data, wSock.udpSock->data.size(), SCTP_DUMP_INBOUND);
|
char * buffer = usrsctp_dumppacket(wSock.udpSock->data, wSock.udpSock->data.size(), SCTP_DUMP_INBOUND);
|
||||||
|
@ -1200,6 +1205,7 @@ namespace Mist{
|
||||||
}
|
}
|
||||||
usrsctp_conninput(this, wSock.udpSock->data, wSock.udpSock->data.size(), 0);
|
usrsctp_conninput(this, wSock.udpSock->data, wSock.udpSock->data.size(), 0);
|
||||||
//usrsctp_accept(sctp_sock, 0, 0);
|
//usrsctp_accept(sctp_sock, 0, 0);
|
||||||
|
#endif
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1636,6 +1642,7 @@ namespace Mist{
|
||||||
}
|
}
|
||||||
|
|
||||||
void OutWebRTC::onSCTP(const char * data, size_t len, uint16_t stream, uint32_t ppid){
|
void OutWebRTC::onSCTP(const char * data, size_t len, uint16_t stream, uint32_t ppid){
|
||||||
|
#ifdef WITH_DATACHANNELS
|
||||||
if (!sctpConnected){
|
if (!sctpConnected){
|
||||||
// We have to call accept (at least) once, otherwise the SCTP library considers our socket not connected
|
// We have to call accept (at least) once, otherwise the SCTP library considers our socket not connected
|
||||||
// Accept blocks if there is no peer, so we do this as soon as the first message is received, which means we have a peer.
|
// Accept blocks if there is no peer, so we do this as soon as the first message is received, which means we have a peer.
|
||||||
|
@ -1723,6 +1730,7 @@ namespace Mist{
|
||||||
packetLog << std::dec << std::endl;
|
packetLog << std::dec << std::endl;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void OutWebRTC::onDTSCConverterHasPacket(const DTSC::Packet &pkt){
|
void OutWebRTC::onDTSCConverterHasPacket(const DTSC::Packet &pkt){
|
||||||
|
@ -1894,6 +1902,7 @@ namespace Mist{
|
||||||
|
|
||||||
|
|
||||||
if (M.getType(thisIdx) == "meta"){
|
if (M.getType(thisIdx) == "meta"){
|
||||||
|
#ifdef WITH_DATACHANNELS
|
||||||
JSON::Value jPack;
|
JSON::Value jPack;
|
||||||
if (M.getCodec(thisIdx) == "JSON"){
|
if (M.getCodec(thisIdx) == "JSON"){
|
||||||
if (dataLen == 0 || (dataLen == 1 && dataPointer[0] == ' ')){return;}
|
if (dataLen == 0 || (dataLen == 1 && dataPointer[0] == ' ')){return;}
|
||||||
|
@ -1938,6 +1947,7 @@ namespace Mist{
|
||||||
WARN_MSG("I don't have a data channel for %s data!", M.getCodec(thisIdx).c_str());
|
WARN_MSG("I don't have a data channel for %s data!", M.getCodec(thisIdx).c_str());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -12,7 +12,10 @@
|
||||||
#include <mist/websocket.h>
|
#include <mist/websocket.h>
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include "output_webrtc_srtp.h"
|
#include "output_webrtc_srtp.h"
|
||||||
#include <usrsctp.h>
|
|
||||||
|
#ifdef WITH_DATACHANNELS
|
||||||
|
#include <usrsctp.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#define NACK_BUFFER_SIZE 1024
|
#define NACK_BUFFER_SIZE 1024
|
||||||
|
|
||||||
|
@ -206,11 +209,13 @@ namespace Mist{
|
||||||
int64_t ntpClockDifference;
|
int64_t ntpClockDifference;
|
||||||
bool syncedNTPClock;
|
bool syncedNTPClock;
|
||||||
|
|
||||||
|
#ifdef WITH_DATACHANNELS
|
||||||
bool sctpInited;
|
bool sctpInited;
|
||||||
bool sctpConnected;
|
bool sctpConnected;
|
||||||
struct socket * sctp_sock;
|
struct socket * sctp_sock;
|
||||||
std::map<std::string, uint16_t> dataChannels;
|
std::map<std::string, uint16_t> dataChannels;
|
||||||
std::deque<std::string> queuedJSON;
|
std::deque<std::string> queuedJSON;
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
}// namespace Mist
|
}// namespace Mist
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,8 @@
|
||||||
[wrap-git]
|
[wrap-git]
|
||||||
directory = libsrtp
|
directory = libsrtp
|
||||||
url = https://github.com/cisco/libsrtp.git
|
url = https://github.com/cisco/libsrtp.git
|
||||||
revision = 1b6deccb216e3cd88bf7ce563b34557b3897c2dd
|
revision = v2.6.0
|
||||||
|
diff_files = libsrtp_cygwin_patch
|
||||||
|
|
||||||
[provide]
|
[provide]
|
||||||
libsrtp2 = libsrtp2_dep
|
libsrtp2 = libsrtp2_dep
|
||||||
|
|
|
@ -1,6 +1,11 @@
|
||||||
project('SRT', 'cpp', 'c', version: '1.5.1')
|
project('SRT', 'cpp', 'c', version: '1.5.1')
|
||||||
|
|
||||||
add_project_arguments(['-DENABLE_LOGGING=1', '-O3', '-DNDEBUG', '-DENABLE_MONOTONIC_CLOCK=1', '-DENABLE_NEW_RCVBUFFER=1', '-DENABLE_SOCK_CLOEXEC=1', '-DHAI_ENABLE_SRT=1', '-DHAI_PATCH=1', '-DHAVE_INET_PTON=1', '-DHAVE_PTHREAD_GETNAME_NP=1', '-DHAVE_PTHREAD_SETNAME_NP=1', '-DLINUX=1', '-DNDEBUG', '-DSRT_DYNAMIC', '-DSRT_ENABLE_APP_READER', '-DSRT_ENABLE_BINDTODEVICE', '-DSRT_ENABLE_CLOSE_SYNCH', '-DSRT_ENABLE_ENCRYPTION', '-DSRT_EXPORTS', '-DSRT_VERSION="1.5.1"', '-DUSE_MBEDTLS=1', '-D_GNU_SOURCE'], language: ['cpp','c'])
|
if host_machine.system() == 'cygwin'
|
||||||
|
add_project_arguments(['-DENABLE_LOGGING=1', '-O3', '-DNDEBUG', '-DENABLE_MONOTONIC_CLOCK=1', '-DENABLE_NEW_RCVBUFFER=1', '-DENABLE_SOCK_CLOEXEC=1', '-DHAI_ENABLE_SRT=1', '-DHAI_PATCH=1', '-DHAVE_INET_PTON=1', '-DHAVE_PTHREAD_GETNAME_NP=1', '-DHAVE_PTHREAD_SETNAME_NP=1', '-DCYGWIN=1', '-DCYGWIN_USE_POSIX', '-DNDEBUG', '-DSRT_DYNAMIC', '-DSRT_ENABLE_APP_READER', '-DSRT_ENABLE_CLOSE_SYNCH', '-DSRT_ENABLE_ENCRYPTION', '-DSRT_EXPORTS', '-DSRT_VERSION="1.5.1"', '-DUSE_MBEDTLS=1', '-D_GNU_SOURCE'], language: ['cpp','c'])
|
||||||
|
else
|
||||||
|
add_project_arguments(['-DENABLE_LOGGING=1', '-O3', '-DNDEBUG', '-DENABLE_MONOTONIC_CLOCK=1', '-DENABLE_NEW_RCVBUFFER=1', '-DENABLE_SOCK_CLOEXEC=1', '-DHAI_ENABLE_SRT=1', '-DHAI_PATCH=1', '-DHAVE_INET_PTON=1', '-DHAVE_PTHREAD_GETNAME_NP=1', '-DHAVE_PTHREAD_SETNAME_NP=1', '-DLINUX=1', '-DNDEBUG', '-DSRT_DYNAMIC', '-DSRT_ENABLE_APP_READER', '-DSRT_ENABLE_BINDTODEVICE', '-DSRT_ENABLE_CLOSE_SYNCH', '-DSRT_ENABLE_ENCRYPTION', '-DSRT_EXPORTS', '-DSRT_VERSION="1.5.1"', '-DUSE_MBEDTLS=1', '-D_GNU_SOURCE'], language: ['cpp','c'])
|
||||||
|
endif
|
||||||
|
|
||||||
|
|
||||||
mbedcrypto_lib = dependency('mbedcrypto', required: false)
|
mbedcrypto_lib = dependency('mbedcrypto', required: false)
|
||||||
mbedx509_lib = dependency('mbedx509', required: false)
|
mbedx509_lib = dependency('mbedx509', required: false)
|
||||||
|
|
15
subprojects/packagefiles/libsrtp_cygwin_patch
Normal file
15
subprojects/packagefiles/libsrtp_cygwin_patch
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
diff --git a/meson.build b/meson.build
|
||||||
|
index 81a232e..1f15de9 100644
|
||||||
|
--- a/meson.build
|
||||||
|
+++ b/meson.build
|
||||||
|
@@ -43,6 +43,10 @@ foreach h : check_headers
|
||||||
|
endif
|
||||||
|
endforeach
|
||||||
|
|
||||||
|
+if (host_system == 'cygwin')
|
||||||
|
+ cdata.set('HAVE_MACHINE_TYPES_H', false)
|
||||||
|
+endif
|
||||||
|
+
|
||||||
|
check_functions = [
|
||||||
|
'sigaction',
|
||||||
|
'inet_aton',
|
|
@ -106,7 +106,7 @@ libmbedtls = library('mbedtls',
|
||||||
)
|
)
|
||||||
|
|
||||||
mbedtls_dep = declare_dependency(
|
mbedtls_dep = declare_dependency(
|
||||||
link_with: [libmbedtls],
|
link_with: [libmbedtls, libmbedx509, libmbedcrypto],
|
||||||
include_directories: incl,
|
include_directories: incl,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue