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;
|
||||
HANDLE hdl = FindFirstFile(path.c_str(), &FindFileData);
|
||||
while (hdl != INVALID_HANDLE_VALUE){
|
||||
execs.push_back(FindFileData.cFileName);
|
||||
if (!(FindFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)){
|
||||
execs.push_back(FindFileData.cFileName);
|
||||
}
|
||||
if (!FindNextFile(hdl, &FindFileData)){
|
||||
FindClose(hdl);
|
||||
hdl = INVALID_HANDLE_VALUE;
|
||||
|
|
|
@ -13,7 +13,6 @@ headers = [
|
|||
'config.h',
|
||||
'defines.h',
|
||||
'dtsc.h',
|
||||
'encryption.h',
|
||||
'flv_tag.h',
|
||||
'h264.h',
|
||||
'h265.h',
|
||||
|
@ -63,14 +62,15 @@ if have_srt
|
|||
headers += 'socket_srt.h'
|
||||
endif
|
||||
|
||||
install_headers(headers, subdir: 'mist')
|
||||
|
||||
extra_code = []
|
||||
|
||||
if usessl
|
||||
headers += 'encryption.h'
|
||||
extra_code += ['stun.cpp', 'certificate.cpp', 'encryption.cpp',]
|
||||
endif
|
||||
|
||||
install_headers(headers, subdir: 'mist')
|
||||
|
||||
libmist = library('mist',
|
||||
'adts.cpp',
|
||||
'amf.cpp',
|
||||
|
|
|
@ -592,7 +592,7 @@ namespace IPC{
|
|||
unmap();
|
||||
if (handle > 0){
|
||||
::close(handle);
|
||||
if (master && name != ""){unlink(name.c_str());}
|
||||
if (master && name != ""){unlink(std::string(Util::getTmpFolder() + name).c_str());}
|
||||
handle = 0;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1605,6 +1605,7 @@ int Socket::Server::getSocket(){
|
|||
}
|
||||
|
||||
|
||||
#ifdef SSL
|
||||
static int dTLS_recv(void *s, unsigned char *buf, size_t 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){
|
||||
return ((Socket::UDPConnection*)s)->dTLSWrite(buf, len);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/// Create a new UDP Socket.
|
||||
|
@ -1680,6 +1682,7 @@ static int dtlsExtractKeyData( void *user, const unsigned char *ms, const unsign
|
|||
}
|
||||
#endif
|
||||
|
||||
#ifdef SSL
|
||||
void Socket::UDPConnection::initDTLS(mbedtls_x509_crt *cert, mbedtls_pk_context *key){
|
||||
hasDTLS = true;
|
||||
nextDTLSRead = 0;
|
||||
|
@ -1825,6 +1828,7 @@ void Socket::UDPConnection::dTLSReset(){
|
|||
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.
|
||||
void Socket::UDPConnection::checkRecvBuf(){
|
||||
|
@ -1913,7 +1917,9 @@ Socket::UDPConnection::~UDPConnection(){
|
|||
free(recvAddr);
|
||||
recvAddr = 0;
|
||||
}
|
||||
#ifdef SSL
|
||||
deinitDTLS();
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
@ -2175,6 +2181,7 @@ void Socket::UDPConnection::SendNow(const char *sdata, size_t len, sockaddr * dA
|
|||
}
|
||||
return;
|
||||
}
|
||||
#if !defined(__CYGWIN__) && !defined(_WIN32)
|
||||
if (hasReceiveData && recvAddr){
|
||||
msghdr mHdr;
|
||||
char msg_control[0x100];
|
||||
|
@ -2209,13 +2216,16 @@ void Socket::UDPConnection::SendNow(const char *sdata, size_t len, sockaddr * dA
|
|||
}
|
||||
return;
|
||||
}else{
|
||||
#endif
|
||||
int r = sendto(sock, sdata, len, 0, dAddr, dAddrLen);
|
||||
if (r > 0){
|
||||
up += r;
|
||||
}else{
|
||||
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.
|
||||
|
@ -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!
|
||||
/// Note: Only actually encrypts if initDTLS was called in the past.
|
||||
void Socket::UDPConnection::sendPaced(const char *sdata, size_t len, bool encrypt){
|
||||
#ifdef SSL
|
||||
if (hasDTLS && encrypt){
|
||||
#if MBEDTLS_VERSION_MAJOR > 2
|
||||
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);
|
||||
if (write <= 0){WARN_MSG("Could not write DTLS packet!");}
|
||||
}else{
|
||||
#endif
|
||||
if (!paceQueue.size() && (!lastPace || Util::getMicros(lastPace) > 10000)){
|
||||
SendNow(sdata, len);
|
||||
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
|
||||
//sendPaced(0);
|
||||
}
|
||||
#ifdef SSL
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
// Gets time in microseconds until next sendPaced call would send something
|
||||
|
@ -2621,6 +2635,7 @@ bool Socket::UDPConnection::Receive(){
|
|||
return false;
|
||||
}
|
||||
if (destAddr && destsize && destAddr_size >= destsize){memcpy(destAddr, &addr, destsize);}
|
||||
#if !defined(__CYGWIN__) && !defined(_WIN32)
|
||||
if (recvAddr){
|
||||
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;}
|
||||
|
@ -2633,6 +2648,7 @@ bool Socket::UDPConnection::Receive(){
|
|||
hasReceiveData = true;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
data.append(0, r);
|
||||
down += r;
|
||||
//Handle UDP packets that are too large
|
||||
|
@ -2646,8 +2662,9 @@ bool Socket::UDPConnection::Receive(){
|
|||
bool Socket::UDPConnection::onData(){
|
||||
wasEncrypted = false;
|
||||
if (!data.size()){return false;}
|
||||
uint8_t fb = 0;
|
||||
int r = data.size();
|
||||
#ifdef SSL
|
||||
uint8_t fb = 0;
|
||||
if (r){fb = (uint8_t)data[0];}
|
||||
if (r && hasDTLS && fb > 19 && fb < 64){
|
||||
if (nextDTLSReadLen){
|
||||
|
@ -2761,6 +2778,7 @@ bool Socket::UDPConnection::onData(){
|
|||
return true;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
return r > 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -237,12 +237,14 @@ namespace Socket{
|
|||
bool hasDTLS; ///< True if dTLS is enabled
|
||||
void * nextDTLSRead;
|
||||
size_t nextDTLSReadLen;
|
||||
#ifdef SSL
|
||||
mbedtls_entropy_context entropy_ctx;
|
||||
mbedtls_ctr_drbg_context rand_ctx;
|
||||
mbedtls_ssl_context ssl_ctx;
|
||||
mbedtls_ssl_config ssl_conf;
|
||||
mbedtls_ssl_cookie_ctx cookie_ctx;
|
||||
mbedtls_timing_delay_context timer_ctx;
|
||||
#endif
|
||||
|
||||
public:
|
||||
Util::ResizeablePointer data;
|
||||
|
@ -251,11 +253,13 @@ namespace Socket{
|
|||
~UDPConnection();
|
||||
bool operator==(const UDPConnection& b) const;
|
||||
operator bool() const;
|
||||
#ifdef SSL
|
||||
void initDTLS(mbedtls_x509_crt *cert, mbedtls_pk_context *key);
|
||||
void deinitDTLS();
|
||||
int dTLSRead(unsigned char *buf, size_t len);
|
||||
int dTLSWrite(const unsigned char *buf, size_t len);
|
||||
void dTLSReset();
|
||||
#endif
|
||||
bool wasEncrypted;
|
||||
void close();
|
||||
int getSock();
|
||||
|
@ -281,12 +285,15 @@ namespace Socket{
|
|||
size_t timeToNextPace(uint64_t uTime = 0);
|
||||
void setSocketFamily(int AF_TYPE);
|
||||
|
||||
|
||||
#ifdef SSL
|
||||
// dTLS-related public members
|
||||
std::string cipher, remote_key, local_key, remote_salt, local_salt;
|
||||
#if HAVE_UPSTREAM_MBEDTLS_SRTP
|
||||
unsigned char master_secret[48];
|
||||
unsigned char randbytes[64];
|
||||
mbedtls_tls_prf_types tls_prf_type;
|
||||
#endif
|
||||
#endif
|
||||
};
|
||||
}// namespace Socket
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/// \file timing.cpp
|
||||
/// Utilities for handling time and timestamps.
|
||||
|
||||
#define _XOPEN_SOURCE // Ensures strptime works in Cygwin
|
||||
#include "timing.h"
|
||||
#include <cstdio>
|
||||
#include <cstring>
|
||||
|
|
17
lib/util.cpp
17
lib/util.cpp
|
@ -302,6 +302,16 @@ namespace Util{
|
|||
DONTEVEN_MSG("Waiting %" PRId64 " ms out of %" PRId64 " for iteration %zu/%zu", w, maxWait, currIter, maxIter);
|
||||
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
|
||||
uint64_t ftell(FILE *stream){
|
||||
|
@ -374,7 +384,12 @@ namespace Util{
|
|||
|
||||
bool ResizeablePointer::allocate(uint32_t l){
|
||||
if (l > maxSize){
|
||||
void *tmp = realloc(ptr, l);
|
||||
void *tmp = 0;
|
||||
if (!ptr){
|
||||
tmp = malloc(l);
|
||||
}else{
|
||||
tmp = realloc(ptr, l);
|
||||
}
|
||||
if (!tmp){
|
||||
FAIL_MSG("Could not allocate %" PRIu32 " bytes of memory", l);
|
||||
return false;
|
||||
|
|
|
@ -20,6 +20,8 @@ namespace Util{
|
|||
|
||||
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 fseek(FILE *stream, uint64_t offset, int whence);
|
||||
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
#include "mbedtls/sha1.h"
|
||||
#endif
|
||||
|
||||
#ifdef SSL
|
||||
// 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){
|
||||
client_key += "258EAFA5-E914-47DA-95CA-C5AB0DC85B11";
|
||||
|
@ -18,6 +19,7 @@ static std::string calculateKeyAccept(std::string client_key){
|
|||
mbedtls_sha1_finish(&ctx, outdata);
|
||||
return Encodings::Base64::encode(std::string((const char *)outdata, 20));
|
||||
}
|
||||
#endif
|
||||
|
||||
namespace HTTP{
|
||||
|
||||
|
@ -33,12 +35,9 @@ namespace HTTP{
|
|||
//Ensure our passed socket gets used by the downloader class
|
||||
d.setSocket(&C);
|
||||
|
||||
//Generate a random nonce based on the current process ID
|
||||
//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.
|
||||
//Generate a random nonce
|
||||
char nonce[16];
|
||||
unsigned int state = getpid();
|
||||
for (size_t i = 0; i < 16; ++i){nonce[i] = rand_r(&state) % 255;}
|
||||
Util::getRandomBytes(nonce, 16);
|
||||
std::string handshakeKey = Encodings::Base64::encode(std::string(nonce, 16));
|
||||
|
||||
//Prepare the headers
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue