Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fixed StreamID and Smoother name swapping for big endian machines #644

Merged
merged 2 commits into from
Apr 29, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions srtcore/core.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1764,6 +1764,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 @@ -1791,7 +1793,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 @@ -2608,6 +2613,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 @@ -2624,6 +2633,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