Skip to content

Commit

Permalink
Fixed StreamID and Smoother name swapping for big endian machines (#644)
Browse files Browse the repository at this point in the history
* Fixed big-endian swapping for little-endian transport
  • Loading branch information
ethouris authored and rndi committed Apr 29, 2019
1 parent c05ca7d commit 7c19251
Show file tree
Hide file tree
Showing 2 changed files with 149 additions and 12 deletions.
12 changes: 12 additions & 0 deletions srtcore/core.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1778,6 +1778,8 @@ bool CUDT::createSrtHandshake(ref_t<CPacket> r_pkt, ref_t<CHandShake> r_hs,

memset(p+offset, 0, aligned_bytesize);
memcpy(p+offset, m_sStreamName.data(), m_sStreamName.size());
// Preswap to little endian (in place due to possible padding zeros)
HtoILA((uint32_t*)(p+offset), (uint32_t*)(p+offset), wordsize);

ra_size = wordsize;
*pcmdspec = HS_CMDSPEC_CMD::wrap(SRT_CMD_SID) | HS_CMDSPEC_SIZE::wrap(ra_size);
Expand Down Expand Up @@ -1805,7 +1807,10 @@ bool CUDT::createSrtHandshake(ref_t<CPacket> r_pkt, ref_t<CHandShake> r_hs,
size_t aligned_bytesize = wordsize*4;

memset(p+offset, 0, aligned_bytesize);

memcpy(p+offset, sm.data(), sm.size());
// Preswap to little endian (in place due to possible padding zeros)
HtoILA((uint32_t*)(p+offset), (uint32_t*)(p+offset), wordsize);

ra_size = wordsize;
*pcmdspec = HS_CMDSPEC_CMD::wrap(SRT_CMD_SMOOTHER) | HS_CMDSPEC_SIZE::wrap(ra_size);
Expand Down Expand Up @@ -2622,6 +2627,10 @@ bool CUDT::interpretSrtHandshake(const CHandShake& hs, const CPacket& hspkt, uin
char target[MAX_SID_LENGTH+1];
memset(target, 0, MAX_SID_LENGTH+1);
memcpy(target, begin+1, bytelen);

// Un-swap on big endian machines
ItoHLA((uint32_t*)target, (uint32_t*)target, bytelen/sizeof(uint32_t));

m_sStreamName = target;
HLOGC(mglog.Debug, log << "CONNECTOR'S REQUESTED SID [" << m_sStreamName << "] (bytelen=" << bytelen << " blocklen=" << blocklen << ")");
}
Expand All @@ -2638,6 +2647,9 @@ bool CUDT::interpretSrtHandshake(const CHandShake& hs, const CPacket& hspkt, uin
char target[MAX_SID_LENGTH+1];
memset(target, 0, MAX_SID_LENGTH+1);
memcpy(target, begin+1, bytelen);
// Un-swap on big endian machines
ItoHLA((uint32_t*)target, (uint32_t*)target, bytelen/sizeof(uint32_t));

string sm = target;

// As the smoother has been declared by the peer,
Expand Down
149 changes: 137 additions & 12 deletions srtcore/utilities.h
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,143 @@ written by

// -------------- UTILITIES ------------------------

// --- ENDIAN ---
// Copied from: https://gist.github.com/panzi/6856583
// License: Public Domain.

#if (defined(_WIN16) || defined(_WIN32) || defined(_WIN64)) && !defined(__WINDOWS__)

# define __WINDOWS__

#endif

#if defined(__linux__) || defined(__CYGWIN__)

# include <endian.h>

#elif defined(__APPLE__)

# include <libkern/OSByteOrder.h>

# define htobe16(x) OSSwapHostToBigInt16(x)
# define htole16(x) OSSwapHostToLittleInt16(x)
# define be16toh(x) OSSwapBigToHostInt16(x)
# define le16toh(x) OSSwapLittleToHostInt16(x)

# define htobe32(x) OSSwapHostToBigInt32(x)
# define htole32(x) OSSwapHostToLittleInt32(x)
# define be32toh(x) OSSwapBigToHostInt32(x)
# define le32toh(x) OSSwapLittleToHostInt32(x)

# define htobe64(x) OSSwapHostToBigInt64(x)
# define htole64(x) OSSwapHostToLittleInt64(x)
# define be64toh(x) OSSwapBigToHostInt64(x)
# define le64toh(x) OSSwapLittleToHostInt64(x)

# define __BYTE_ORDER BYTE_ORDER
# define __BIG_ENDIAN BIG_ENDIAN
# define __LITTLE_ENDIAN LITTLE_ENDIAN
# define __PDP_ENDIAN PDP_ENDIAN

#elif defined(__OpenBSD__)

# include <sys/endian.h>

#elif defined(__NetBSD__) || defined(__FreeBSD__) || defined(__DragonFly__)

# include <sys/endian.h>

# define be16toh(x) betoh16(x)
# define le16toh(x) letoh16(x)

# define be32toh(x) betoh32(x)
# define le32toh(x) letoh32(x)

# define be64toh(x) betoh64(x)
# define le64toh(x) letoh64(x)

#elif defined(__WINDOWS__)

# include <winsock2.h>

# if BYTE_ORDER == LITTLE_ENDIAN

# define htobe16(x) htons(x)
# define htole16(x) (x)
# define be16toh(x) ntohs(x)
# define le16toh(x) (x)

# define htobe32(x) htonl(x)
# define htole32(x) (x)
# define be32toh(x) ntohl(x)
# define le32toh(x) (x)

# define htobe64(x) htonll(x)
# define htole64(x) (x)
# define be64toh(x) ntohll(x)
# define le64toh(x) (x)

# elif BYTE_ORDER == BIG_ENDIAN

/* that would be xbox 360 */
# define htobe16(x) (x)
# define htole16(x) __builtin_bswap16(x)
# define be16toh(x) (x)
# define le16toh(x) __builtin_bswap16(x)

# define htobe32(x) (x)
# define htole32(x) __builtin_bswap32(x)
# define be32toh(x) (x)
# define le32toh(x) __builtin_bswap32(x)

# define htobe64(x) (x)
# define htole64(x) __builtin_bswap64(x)
# define be64toh(x) (x)
# define le64toh(x) __builtin_bswap64(x)

# else

# error byte order not supported

# endif

# define __BYTE_ORDER BYTE_ORDER
# define __BIG_ENDIAN BIG_ENDIAN
# define __LITTLE_ENDIAN LITTLE_ENDIAN
# define __PDP_ENDIAN PDP_ENDIAN

#else

# error Endian: platform not supported

#endif

// Hardware <--> Network (big endian) convention
inline void HtoNLA(uint32_t* dst, const uint32_t* src, size_t size)
{
for (size_t i = 0; i < size; ++ i)
dst[i] = htonl(src[i]);
}

inline void NtoHLA(uint32_t* dst, const uint32_t* src, size_t size)
{
for (size_t i = 0; i < size; ++ i)
dst[i] = ntohl(src[i]);
}

// Hardware <--> Intel (little endian) convention
inline void HtoILA(uint32_t* dst, const uint32_t* src, size_t size)
{
for (size_t i = 0; i < size; ++ i)
dst[i] = htole32(src[i]);
}

inline void ItoHLA(uint32_t* dst, const uint32_t* src, size_t size)
{
for (size_t i = 0; i < size; ++ i)
dst[i] = le32toh(src[i]);
}

// Bit numbering utility.
//
// This is something that allows you to turn 32-bit integers into bit fields.
Expand Down Expand Up @@ -233,18 +370,6 @@ inline bool IsSet(int32_t bitset, int32_t flagset)
return (bitset & flagset) == flagset;
}

inline void HtoNLA(uint32_t* dst, const uint32_t* src, size_t size)
{
for (size_t i = 0; i < size; ++ i)
dst[i] = htonl(src[i]);
}

inline void NtoHLA(uint32_t* dst, const uint32_t* src, size_t size)
{
for (size_t i = 0; i < size; ++ i)
dst[i] = ntohl(src[i]);
}

// Homecooked version of ref_t. It's a copy of std::reference_wrapper
// voided of unwanted properties and renamed to ref_t.

Expand Down

0 comments on commit 7c19251

Please sign in to comment.