diff --git a/srtcore/core.cpp b/srtcore/core.cpp index 1fb75c946..4a07303ff 100644 --- a/srtcore/core.cpp +++ b/srtcore/core.cpp @@ -1778,6 +1778,8 @@ bool CUDT::createSrtHandshake(ref_t r_pkt, ref_t 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); @@ -1805,7 +1807,10 @@ bool CUDT::createSrtHandshake(ref_t r_pkt, ref_t 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); @@ -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 << ")"); } @@ -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, diff --git a/srtcore/utilities.h b/srtcore/utilities.h index a6b24b29c..b69e49b3e 100644 --- a/srtcore/utilities.h +++ b/srtcore/utilities.h @@ -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 + +#elif defined(__APPLE__) + +# include + +# 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 + +#elif defined(__NetBSD__) || defined(__FreeBSD__) || defined(__DragonFly__) + +# include + +# 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 + +# 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. @@ -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.