diff --git a/lib/adts.cpp b/lib/adts.cpp index ae41f04f..82092394 100644 --- a/lib/adts.cpp +++ b/lib/adts.cpp @@ -6,133 +6,110 @@ #include "defines.h" -namespace aac { +namespace aac{ adts::adts(){ data = NULL; len = 0; } - adts::adts(const char * _data, unsigned long _len){ + adts::adts(const char *_data, unsigned long _len){ len = _len; - data = (char*)malloc(len); + data = (char *)malloc(len); memcpy(data, _data, len); } - - bool adts::sameHeader(const adts & rhs) const { + bool adts::sameHeader(const adts &rhs) const{ if (!rhs || !*this){return false;} - return (getAACProfile() == rhs.getAACProfile() && getFrequencyIndex() == rhs.getFrequencyIndex() && getChannelConfig() == rhs.getChannelConfig()); + return (getAACProfile() == rhs.getAACProfile() && getFrequencyIndex() == rhs.getFrequencyIndex() && + getChannelConfig() == rhs.getChannelConfig()); } - adts::adts(const adts & rhs){ + adts::adts(const adts &rhs){ data = NULL; len = 0; *this = rhs; } - adts& adts::operator = (const adts & rhs){ - if (data){ - free(data); - } + adts &adts::operator=(const adts &rhs){ + if (data){free(data);} len = rhs.len; - data = (char*)malloc(len); + data = (char *)malloc(len); memcpy(data, rhs.data, len); - return * this; + return *this; } adts::~adts(){ - if (data){ - free(data); - } + if (data){free(data);} } unsigned long adts::getAACProfile() const{ - if (!data || !len){ - return 0; - } + if (!data || !len){return 0;} return ((data[2] >> 6) & 0x03) + 1; } unsigned long adts::getFrequencyIndex() const{ - if (!data || !len){ - return 0; - } + if (!data || !len){return 0;} return ((data[2] >> 2) & 0x0F); - } unsigned long adts::getFrequency() const{ - if (!data || len < 3){ - return 0; - } - switch(getFrequencyIndex()){ - case 0: return 96000; break; - case 1: return 88200; break; - case 2: return 64000; break; - case 3: return 48000; break; - case 4: return 44100; break; - case 5: return 32000; break; - case 6: return 24000; break; - case 7: return 22050; break; - case 8: return 16000; break; - case 9: return 12000; break; - case 10: return 11025; break; - case 11: return 8000; break; - case 12: return 7350; break; - default: return 0; break; + if (!data || len < 3){return 0;} + switch (getFrequencyIndex()){ + case 0: return 96000; break; + case 1: return 88200; break; + case 2: return 64000; break; + case 3: return 48000; break; + case 4: return 44100; break; + case 5: return 32000; break; + case 6: return 24000; break; + case 7: return 22050; break; + case 8: return 16000; break; + case 9: return 12000; break; + case 10: return 11025; break; + case 11: return 8000; break; + case 12: return 7350; break; + default: return 0; break; } } unsigned long adts::getChannelConfig() const{ - if (!data || !len){ - return 0; - } + if (!data || !len){return 0;} return ((data[2] & 0x01) << 2) | ((data[3] >> 6) & 0x03); } unsigned long adts::getChannelCount() const{ - if (!data || !len){ - return 0; - } + if (!data || !len){return 0;} return (getChannelConfig() == 7 ? 8 : getChannelConfig()); } unsigned long adts::getHeaderSize() const{ - if (!data || !len){ - return 0; - } + if (!data || !len){return 0;} return (data[1] & 0x01 ? 7 : 9); } unsigned long adts::getCompleteSize() const{ - if (!data || len < 6){ - return 0; - } + if (!data || len < 6){return 0;} return (((data[3] & 0x03) << 11) | (data[4] << 3) | ((data[5] >> 5) & 0x07)); } unsigned long adts::getPayloadSize() const{ unsigned long ret = getCompleteSize(); - if (!ret){return ret;}//catch zero length + if (!ret){return ret;}// catch zero length if (ret >= getHeaderSize()){ ret -= getHeaderSize(); }else{ - return 0;//catch size less than header size (corrupt data) + return 0; // catch size less than header size (corrupt data) } return ret; } unsigned long adts::getSampleCount() const{ - if (!data || len < 7){ - return 0; - } - return ((data[6] & 0x03) + 1) * 1024;//Number of samples in this frame * 1024 + if (!data || len < 7){return 0;} + return ((data[6] & 0x03) + 1) * 1024; // Number of samples in this frame * 1024 } - - char * adts::getPayload() { - if (!data || !len){ - return 0; - } + + char *adts::getPayload(){ + if (!data || !len){return 0;} return data + getHeaderSize(); } std::string adts::toPrettyString() const{ @@ -147,12 +124,8 @@ namespace aac { }else{ res << " MPEG-4" << std::endl; } - if ((data[1] & 0x6) != 0){ - res << " Non-zero layer!" << std::endl; - } - if ((data[1] & 0x1) == 0x0){ - res << " CRC present" << std::endl; - } + if ((data[1] & 0x6) != 0){res << " Non-zero layer!" << std::endl;} + if ((data[1] & 0x1) == 0x0){res << " CRC present" << std::endl;} res << " MPEG-4 audio object type: " << getAACProfile() << std::endl; res << " Frequency: " << getFrequency() << "Hz" << std::endl; res << " Channels: " << getChannelCount() << std::endl; @@ -161,9 +134,10 @@ namespace aac { return res.str(); } adts::operator bool() const{ - return hasSync() && len && len >= getHeaderSize() && getFrequency() && getChannelCount() && getSampleCount(); + return hasSync() && len && len >= getHeaderSize() && getFrequency() && getChannelCount() && + getSampleCount(); } bool adts::hasSync() const{ return len && (((int)data[0] << 4) | ((data[1] >> 4) & 0x0F)) == 0xfff; } -} +}// namespace aac diff --git a/lib/adts.h b/lib/adts.h index 1725fbc8..09c99c99 100644 --- a/lib/adts.h +++ b/lib/adts.h @@ -1,96 +1,95 @@ +#include "bitstream.h" #include #include -#include "bitstream.h" -namespace aac { - class adts { - public: - adts(); - adts(const char * _data, unsigned long _len); - adts(const adts & rhs); - ~adts(); - adts& operator = (const adts & rhs); - bool sameHeader(const adts & rhs) const; - unsigned long getAACProfile() const; - unsigned long getFrequencyIndex() const; - unsigned long getFrequency() const; - unsigned long getChannelConfig() const; - unsigned long getChannelCount() const; - unsigned long getHeaderSize() const; - unsigned long getPayloadSize() const; - unsigned long getCompleteSize() const; - unsigned long getSampleCount() const; - bool hasSync() const; - char * getPayload(); - std::string toPrettyString() const; - operator bool() const; - private: - char * data; - unsigned long len; +namespace aac{ + class adts{ + public: + adts(); + adts(const char *_data, unsigned long _len); + adts(const adts &rhs); + ~adts(); + adts &operator=(const adts &rhs); + bool sameHeader(const adts &rhs) const; + unsigned long getAACProfile() const; + unsigned long getFrequencyIndex() const; + unsigned long getFrequency() const; + unsigned long getChannelConfig() const; + unsigned long getChannelCount() const; + unsigned long getHeaderSize() const; + unsigned long getPayloadSize() const; + unsigned long getCompleteSize() const; + unsigned long getSampleCount() const; + bool hasSync() const; + char *getPayload(); + std::string toPrettyString() const; + operator bool() const; + + private: + char *data; + unsigned long len; }; class AudSpecConf{ - public: - static inline uint32_t rate(const std::string & conf){ - Utils::bitstream bs; - bs.append(conf.data(), conf.size()); - if (bs.get(5) == 31){bs.skip(6);}//skip object type - switch (bs.get(4)){//frequency index - case 0: return 96000; - case 1: return 88200; - case 2: return 64000; - case 3: return 48000; - case 4: return 44100; - case 5: return 32000; - case 6: return 24000; - case 7: return 22050; - case 8: return 16000; - case 9: return 12000; - case 10: return 11025; - case 11: return 8000; - case 12: return 7350; - case 15: return bs.get(24); - default: return 0; - } + public: + static inline uint32_t rate(const std::string &conf){ + Utils::bitstream bs; + bs.append(conf.data(), conf.size()); + if (bs.get(5) == 31){bs.skip(6);}// skip object type + switch (bs.get(4)){// frequency index + case 0: return 96000; + case 1: return 88200; + case 2: return 64000; + case 3: return 48000; + case 4: return 44100; + case 5: return 32000; + case 6: return 24000; + case 7: return 22050; + case 8: return 16000; + case 9: return 12000; + case 10: return 11025; + case 11: return 8000; + case 12: return 7350; + case 15: return bs.get(24); + default: return 0; } - static inline uint16_t channels(const std::string &conf){ - Utils::bitstream bs; - bs.append(conf.data(), conf.size()); - if (bs.get(5) == 31){bs.skip(6);}// skip object type - if (bs.get(4) == 15){bs.skip(24);}// frequency index - uint8_t chanConfig = bs.get(4); - if (chanConfig == 0){ - WARN_MSG("Unimplemented AAC AOT Specific Config parsing"); - return 8; - } - if (chanConfig > 7){ - WARN_MSG("Unimplemented AAC channel configuration %" PRIu8, chanConfig); - return 8; - } - if (chanConfig == 7){return 8;} - return chanConfig; + } + static inline uint16_t channels(const std::string &conf){ + Utils::bitstream bs; + bs.append(conf.data(), conf.size()); + if (bs.get(5) == 31){bs.skip(6);}// skip object type + if (bs.get(4) == 15){bs.skip(24);}// frequency index + uint8_t chanConfig = bs.get(4); + if (chanConfig == 0){ + WARN_MSG("Unimplemented AAC AOT Specific Config parsing"); + return 8; } - static inline uint8_t objtype(const std::string &conf){ - Utils::bitstream bs; - bs.append(conf.data(), conf.size()); - uint8_t ot = bs.get(5); - if (ot == 31){return bs.get(6) + 32;} - return ot; + if (chanConfig > 7){ + WARN_MSG("Unimplemented AAC channel configuration %" PRIu8, chanConfig); + return 8; } - static inline uint16_t samples(const std::string &conf){ - Utils::bitstream bs; - bs.append(conf.data(), conf.size()); - if (bs.get(5) == 31){bs.skip(6);}// skip object type - if (bs.get(4) == 15){bs.skip(24);}// frequency index - bs.skip(4); // channel configuration - if (bs.get(1)){ - return 960; - }else{ - return 1024; - } + if (chanConfig == 7){return 8;} + return chanConfig; + } + static inline uint8_t objtype(const std::string &conf){ + Utils::bitstream bs; + bs.append(conf.data(), conf.size()); + uint8_t ot = bs.get(5); + if (ot == 31){return bs.get(6) + 32;} + return ot; + } + static inline uint16_t samples(const std::string &conf){ + Utils::bitstream bs; + bs.append(conf.data(), conf.size()); + if (bs.get(5) == 31){bs.skip(6);}// skip object type + if (bs.get(4) == 15){bs.skip(24);}// frequency index + bs.skip(4); // channel configuration + if (bs.get(1)){ + return 960; + }else{ + return 1024; } + } }; - - -} +}// namespace aac diff --git a/lib/amf.cpp b/lib/amf.cpp index db12e679..33e3c9ae 100644 --- a/lib/amf.cpp +++ b/lib/amf.cpp @@ -328,8 +328,7 @@ std::string AMF::Object::Pack(){ /// \param i Current parsing position in the raw data. /// \param name Indice name for any new object created. /// \returns A single AMF::Object, parsed from the raw data. -AMF::Object AMF::parseOne(const unsigned char *&data, unsigned int &len, unsigned int &i, - std::string name){ +AMF::Object AMF::parseOne(const unsigned char *&data, unsigned int &len, unsigned int &i, std::string name){ std::string tmpstr; unsigned int tmpi = 0; unsigned char tmpdbl[8]; @@ -375,16 +374,14 @@ AMF::Object AMF::parseOne(const unsigned char *&data, unsigned int &len, unsigne return AMF::Object(name, (double)tmpi, AMF::AMF0_REFERENCE); break; case AMF::AMF0_XMLDOC: - tmpi = data[i + 1] * 256 * 256 * 256 + data[i + 2] * 256 * 256 + data[i + 3] * 256 + - data[i + 4]; // set tmpi to UTF-8-long length + tmpi = data[i + 1] * 256 * 256 * 256 + data[i + 2] * 256 * 256 + data[i + 3] * 256 + data[i + 4]; // set tmpi to UTF-8-long length tmpstr.clear(); // clean tmpstr, just to be sure tmpstr.append((const char *)data + i + 5, (size_t)tmpi); // add the string data i += tmpi + 5; // skip length+size+1 forwards return AMF::Object(name, tmpstr, AMF::AMF0_XMLDOC); break; case AMF::AMF0_LONGSTRING: - tmpi = data[i + 1] * 256 * 256 * 256 + data[i + 2] * 256 * 256 + data[i + 3] * 256 + - data[i + 4]; // set tmpi to UTF-8-long length + tmpi = data[i + 1] * 256 * 256 * 256 + data[i + 2] * 256 * 256 + data[i + 3] * 256 + data[i + 4]; // set tmpi to UTF-8-long length tmpstr.clear(); // clean tmpstr, just to be sure tmpstr.append((const char *)data + i + 5, (size_t)tmpi); // add the string data i += tmpi + 5; // skip length+size+1 forwards @@ -411,9 +408,8 @@ AMF::Object AMF::parseOne(const unsigned char *&data, unsigned int &len, unsigne tmpstr.clear(); // clean tmpstr, just to be sure tmpstr.append((const char *)data + i + 2, (size_t)tmpi); // add the string data i += tmpi + 2; // skip length+size forwards - ret.addContent(AMF::parseOne( - data, len, i, - tmpstr)); // add content, recursively parsed, updating i, setting indice to tmpstr + ret.addContent(AMF::parseOne(data, len, i, + tmpstr)); // add content, recursively parsed, updating i, setting indice to tmpstr } i += 3; // skip 0x000009 return ret; @@ -429,9 +425,8 @@ AMF::Object AMF::parseOne(const unsigned char *&data, unsigned int &len, unsigne tmpstr.clear(); // clean tmpstr, just to be sure tmpstr.append((const char *)data + i + 2, (size_t)tmpi); // add the string data i += tmpi + 2; // skip length+size forwards - ret.addContent(AMF::parseOne( - data, len, i, - tmpstr)); // add content, recursively parsed, updating i, setting indice to tmpstr + ret.addContent(AMF::parseOne(data, len, i, + tmpstr)); // add content, recursively parsed, updating i, setting indice to tmpstr } i += 3; // skip 0x000009 return ret; @@ -445,21 +440,18 @@ AMF::Object AMF::parseOne(const unsigned char *&data, unsigned int &len, unsigne tmpstr.clear(); // clean tmpstr, just to be sure tmpstr.append((const char *)data + i + 2, (size_t)tmpi); // add the string data i += tmpi + 2; // skip length+size forwards - ret.addContent(AMF::parseOne( - data, len, i, - tmpstr)); // add content, recursively parsed, updating i, setting indice to tmpstr + ret.addContent(AMF::parseOne(data, len, i, + tmpstr)); // add content, recursively parsed, updating i, setting indice to tmpstr } i += 3; // skip 0x000009 return ret; }break; case AMF::AMF0_STRICT_ARRAY:{ AMF::Object ret(name, AMF::AMF0_STRICT_ARRAY); - tmpi = data[i + 1] * 256 * 256 * 256 + data[i + 2] * 256 * 256 + data[i + 3] * 256 + - data[i + 4]; // set tmpi to array length - i += 5; // skip size+1 forwards + tmpi = data[i + 1] * 256 * 256 * 256 + data[i + 2] * 256 * 256 + data[i + 3] * 256 + data[i + 4]; // set tmpi to array length + i += 5; // skip size+1 forwards while (tmpi > 0){// while not done parsing array - ret.addContent( - AMF::parseOne(data, len, i, "arrVal")); // add content, recursively parsed, updating i + ret.addContent(AMF::parseOne(data, len, i, "arrVal")); // add content, recursively parsed, updating i --tmpi; } return ret; @@ -712,8 +704,7 @@ std::string AMF::Object3::Pack(){ /// \param i Current parsing position in the raw data. /// \param name Indice name for any new object created. /// \returns A single AMF::Object3, parsed from the raw data. -AMF::Object3 AMF::parseOne3(const unsigned char *&data, unsigned int &len, unsigned int &i, - std::string name){ +AMF::Object3 AMF::parseOne3(const unsigned char *&data, unsigned int &len, unsigned int &i, std::string name){ std::string tmpstr; unsigned int tmpi = 0; unsigned int arrsize = 0; @@ -974,13 +965,11 @@ AMF::Object3 AMF::parseOne3(const unsigned char *&data, unsigned int &len, unsig if (tmpi > 0){ tmpstr.clear(); // clean tmpstr, just to be sure tmpstr.append((const char *)data + i, (size_t)tmpi); // add the string data - ret.addContent( - AMF::parseOne3(data, len, i, tmpstr)); // add content, recursively parsed, updating i + ret.addContent(AMF::parseOne3(data, len, i, tmpstr)); // add content, recursively parsed, updating i } }while (tmpi > 0); while (arrsize > 0){// while not done parsing array - ret.addContent( - AMF::parseOne3(data, len, i, "arrVal")); // add content, recursively parsed, updating i + ret.addContent(AMF::parseOne3(data, len, i, "arrVal")); // add content, recursively parsed, updating i --arrsize; } return ret; @@ -1046,8 +1035,7 @@ AMF::Object3 AMF::parseOne3(const unsigned char *&data, unsigned int &len, unsig if (tmpi > 0){ tmpstr.clear(); // clean tmpstr, just to be sure tmpstr.append((const char *)data + i, (size_t)tmpi); // add the string data - ret.addContent( - AMF::parseOne3(data, len, i, tmpstr)); // add content, recursively parsed, updating i + ret.addContent(AMF::parseOne3(data, len, i, tmpstr)); // add content, recursively parsed, updating i } }while (tmpi > 0); // keep reading dynamic values until empty string }// dynamic types @@ -1081,4 +1069,3 @@ AMF::Object3 AMF::parse3(const unsigned char *data, unsigned int len){ AMF::Object3 AMF::parse3(std::string data){ return AMF::parse3((const unsigned char *)data.c_str(), data.size()); }// parse - diff --git a/lib/amf.h b/lib/amf.h index 37483601..0777dae9 100644 --- a/lib/amf.h +++ b/lib/amf.h @@ -130,8 +130,6 @@ namespace AMF{ /// Parses a std::string to a valid AMF::Object3. Object3 parse3(std::string data); /// Parses a single AMF3 type - used recursively by the AMF::parse3() functions. - Object3 parseOne3(const unsigned char *&data, unsigned int &len, unsigned int &i, - std::string name); + Object3 parseOne3(const unsigned char *&data, unsigned int &len, unsigned int &i, std::string name); }// namespace AMF - diff --git a/lib/auth.cpp b/lib/auth.cpp index b6c01a6d..468cd381 100644 --- a/lib/auth.cpp +++ b/lib/auth.cpp @@ -1,19 +1,17 @@ #include "auth.h" -#include -#include #include -#include #include +#include +#include +#include -namespace Secure { +namespace Secure{ /// Calculates a MD5 digest as per rfc1321, returning it as a hexadecimal alphanumeric string. - std::string md5(std::string input) { - return md5(input.data(), input.size()); - } + std::string md5(std::string input){return md5(input.data(), input.size());} /// Calculates a MD5 digest as per rfc1321, returning it as a hexadecimal alphanumeric string. - std::string md5(const char * input, const unsigned int in_len){ + std::string md5(const char *input, const unsigned int in_len){ char output[16]; md5bin(input, in_len, output); std::stringstream outStr; @@ -24,12 +22,10 @@ namespace Secure { } /// Calculates a SHA256 digest as per NSAs SHA-2, returning it as a hexadecimal alphanumeric string. - std::string sha256(std::string input) { - return sha256(input.data(), input.size()); - } + std::string sha256(std::string input){return sha256(input.data(), input.size());} /// Calculates a SHA256 digest as per NSAs SHA-2, returning it as a hexadecimal alphanumeric string. - std::string sha256(const char * input, const unsigned int in_len){ + std::string sha256(const char *input, const unsigned int in_len){ char output[32]; sha256bin(input, in_len, output); std::stringstream outStr; @@ -42,14 +38,28 @@ namespace Secure { /// Adds 64 bytes of data to the current MD5 hash. /// hash is the current hash, represented by 4 unsigned longs. /// data is the 64 bytes of data that need to be added. - static inline void md5_add64(uint32_t * hash, const char * data){ - //Inspired by the pseudocode as available on Wikipedia on March 2nd, 2015. + static inline void md5_add64(uint32_t *hash, const char *data){ + // Inspired by the pseudocode as available on Wikipedia on March 2nd, 2015. uint32_t M[16]; for (unsigned int i = 0; i < 16; ++i){ - M[i] = data[i << 2] | (data[(i<<2)+1] << 8) | (data[(i<<2)+2] << 16) | (data[(i<<2)+3] << 24); + M[i] = data[i << 2] | (data[(i << 2) + 1] << 8) | (data[(i << 2) + 2] << 16) | + (data[(i << 2) + 3] << 24); } - static unsigned char shift[] = {7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21}; - static uint32_t K[] = { 0xd76aa478, 0xe8c7b756, 0x242070db, 0xc1bdceee, 0xf57c0faf, 0x4787c62a, 0xa8304613, 0xfd469501, 0x698098d8, 0x8b44f7af, 0xffff5bb1, 0x895cd7be, 0x6b901122, 0xfd987193, 0xa679438e, 0x49b40821, 0xf61e2562, 0xc040b340, 0x265e5a51, 0xe9b6c7aa, 0xd62f105d, 0x02441453, 0xd8a1e681, 0xe7d3fbc8, 0x21e1cde6, 0xc33707d6, 0xf4d50d87, 0x455a14ed, 0xa9e3e905, 0xfcefa3f8, 0x676f02d9, 0x8d2a4c8a, 0xfffa3942, 0x8771f681, 0x6d9d6122, 0xfde5380c, 0xa4beea44, 0x4bdecfa9, 0xf6bb4b60, 0xbebfbc70, 0x289b7ec6, 0xeaa127fa, 0xd4ef3085, 0x04881d05, 0xd9d4d039, 0xe6db99e5, 0x1fa27cf8, 0xc4ac5665, 0xf4292244, 0x432aff97, 0xab9423a7, 0xfc93a039, 0x655b59c3, 0x8f0ccc92, 0xffeff47d, 0x85845dd1, 0x6fa87e4f, 0xfe2ce6e0, 0xa3014314, 0x4e0811a1, 0xf7537e82, 0xbd3af235, 0x2ad7d2bb, 0xeb86d391}; + static unsigned char shift[] ={7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, + 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, + 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, + 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21}; + static uint32_t K[] ={0xd76aa478, 0xe8c7b756, 0x242070db, 0xc1bdceee, 0xf57c0faf, 0x4787c62a, + 0xa8304613, 0xfd469501, 0x698098d8, 0x8b44f7af, 0xffff5bb1, 0x895cd7be, + 0x6b901122, 0xfd987193, 0xa679438e, 0x49b40821, 0xf61e2562, 0xc040b340, + 0x265e5a51, 0xe9b6c7aa, 0xd62f105d, 0x02441453, 0xd8a1e681, 0xe7d3fbc8, + 0x21e1cde6, 0xc33707d6, 0xf4d50d87, 0x455a14ed, 0xa9e3e905, 0xfcefa3f8, + 0x676f02d9, 0x8d2a4c8a, 0xfffa3942, 0x8771f681, 0x6d9d6122, 0xfde5380c, + 0xa4beea44, 0x4bdecfa9, 0xf6bb4b60, 0xbebfbc70, 0x289b7ec6, 0xeaa127fa, + 0xd4ef3085, 0x04881d05, 0xd9d4d039, 0xe6db99e5, 0x1fa27cf8, 0xc4ac5665, + 0xf4292244, 0x432aff97, 0xab9423a7, 0xfc93a039, 0x655b59c3, 0x8f0ccc92, + 0xffeff47d, 0x85845dd1, 0x6fa87e4f, 0xfe2ce6e0, 0xa3014314, 0x4e0811a1, + 0xf7537e82, 0xbd3af235, 0x2ad7d2bb, 0xeb86d391}; uint32_t A = hash[0]; uint32_t B = hash[1]; uint32_t C = hash[2]; @@ -61,19 +71,19 @@ namespace Secure { g = i; }else if (i < 32){ F = (D & B) | ((~D) & C); - g = (5*i + 1) % 16; + g = (5 * i + 1) % 16; }else if (i < 48){ F = B ^ C ^ D; - g = (3*i + 5) % 16; + g = (3 * i + 5) % 16; }else{ F = C ^ (B | (~D)); - g = (7*i) % 16; + g = (7 * i) % 16; } uint32_t dTemp = D; D = C; C = B; uint32_t x = A + F + K[i] + M[g]; - B += (x << shift[i] | (x >> (32-shift[i]))); + B += (x << shift[i] | (x >> (32 - shift[i]))); A = dTemp; } hash[0] += A; @@ -84,31 +94,31 @@ namespace Secure { /// Calculates a MD5 digest as per rfc1321, returning it as binary. /// Assumes output is big enough to contain 16 bytes of data. - void md5bin(const char * input, const unsigned int in_len, char * output){ - //Initialize the hash, according to MD5 spec. - uint32_t hash[] = {0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476}; - //Add as many whole blocks of 64 bytes as possible from the input, until < 64 are left. + void md5bin(const char *input, const unsigned int in_len, char *output){ + // Initialize the hash, according to MD5 spec. + uint32_t hash[] ={0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476}; + // Add as many whole blocks of 64 bytes as possible from the input, until < 64 are left. unsigned int offset = 0; - while (offset+64 <= in_len){ - md5_add64(hash, input+offset); + while (offset + 64 <= in_len){ + md5_add64(hash, input + offset); offset += 64; } - //now, copy the remainder to a 64 byte buffer. + // now, copy the remainder to a 64 byte buffer. char buffer[64]; - memcpy(buffer, input+offset, in_len-offset); - //Calculate how much we've filled in that buffer + memcpy(buffer, input + offset, in_len - offset); + // Calculate how much we've filled in that buffer offset = in_len - offset; - //We know at least 1 byte must be empty, so we can safely do this - buffer[offset] = 0x80;//append 0x80 - //fill to the end of the buffer with zeroes - memset(buffer+offset+1, 0, 64-offset-1); + // We know at least 1 byte must be empty, so we can safely do this + buffer[offset] = 0x80; // append 0x80 + // fill to the end of the buffer with zeroes + memset(buffer + offset + 1, 0, 64 - offset - 1); if (offset > 55){ - //There's no space for the length, add what we have and zero it + // There's no space for the length, add what we have and zero it md5_add64(hash, buffer); memset(buffer, 0, 64); } unsigned long long bit_len = in_len << 3; - //Write the length into the last 8 bytes + // Write the length into the last 8 bytes buffer[56] = (bit_len >> 0) & 0xff; buffer[57] = (bit_len >> 8) & 0xff; buffer[58] = (bit_len >> 16) & 0xff; @@ -117,24 +127,24 @@ namespace Secure { buffer[61] = (bit_len >> 40) & 0xff; buffer[62] = (bit_len >> 48) & 0xff; buffer[63] = (bit_len >> 54) & 0xff; - //Add the last bit of buffer + // Add the last bit of buffer md5_add64(hash, buffer); - //Write to output - //convert hash to hexadecimal string - output[0 ] = (hash[0] >> 0 ) & 0xff; - output[1 ] = (hash[0] >> 8 ) & 0xff; - output[2 ] = (hash[0] >> 16) & 0xff; - output[3 ] = (hash[0] >> 24) & 0xff; - output[4 ] = (hash[1] >> 0 ) & 0xff; - output[5 ] = (hash[1] >> 8 ) & 0xff; - output[6 ] = (hash[1] >> 16) & 0xff; - output[7 ] = (hash[1] >> 24) & 0xff; - output[8 ] = (hash[2] >> 0 ) & 0xff; - output[9 ] = (hash[2] >> 8 ) & 0xff; + // Write to output + // convert hash to hexadecimal string + output[0] = (hash[0] >> 0) & 0xff; + output[1] = (hash[0] >> 8) & 0xff; + output[2] = (hash[0] >> 16) & 0xff; + output[3] = (hash[0] >> 24) & 0xff; + output[4] = (hash[1] >> 0) & 0xff; + output[5] = (hash[1] >> 8) & 0xff; + output[6] = (hash[1] >> 16) & 0xff; + output[7] = (hash[1] >> 24) & 0xff; + output[8] = (hash[2] >> 0) & 0xff; + output[9] = (hash[2] >> 8) & 0xff; output[10] = (hash[2] >> 16) & 0xff; output[11] = (hash[2] >> 24) & 0xff; - output[12] = (hash[3] >> 0 ) & 0xff; - output[13] = (hash[3] >> 8 ) & 0xff; + output[12] = (hash[3] >> 0) & 0xff; + output[13] = (hash[3] >> 8) & 0xff; output[14] = (hash[3] >> 16) & 0xff; output[15] = (hash[3] >> 24) & 0xff; } @@ -147,20 +157,31 @@ namespace Secure { /// Adds 64 bytes of data to the current SHA256 hash. /// hash is the current hash, represented by 8 unsigned longs. /// data is the 64 bytes of data that need to be added. - static inline void sha256_add64(uint32_t * hash, const char * data){ - //Inspired by the pseudocode as available on Wikipedia on March 3rd, 2015. + static inline void sha256_add64(uint32_t *hash, const char *data){ + // Inspired by the pseudocode as available on Wikipedia on March 3rd, 2015. uint32_t w[64]; for (unsigned int i = 0; i < 16; ++i){ - w[i] = (uint32_t)data[(i<<2)+3] | ((uint32_t)data[(i<<2)+2] << 8) | ((uint32_t)data[(i<<2)+1] << 16) | ((uint32_t)data[(i<<2)+0] << 24); + w[i] = (uint32_t)data[(i << 2) + 3] | ((uint32_t)data[(i << 2) + 2] << 8) | + ((uint32_t)data[(i << 2) + 1] << 16) | ((uint32_t)data[(i << 2) + 0] << 24); } for (unsigned int i = 16; i < 64; ++i){ - uint32_t s0 = rr(w[i-15], 7) ^ rr(w[i-15], 18) ^ ((w[i-15] & 0xFFFFFFFF ) >> 3); - uint32_t s1 = rr(w[i-2], 17) ^ rr(w[i-2], 19) ^ ((w[i-2] & 0xFFFFFFFF) >> 10); - w[i] = w[i-16] + s0 + w[i-7] + s1; + uint32_t s0 = rr(w[i - 15], 7) ^ rr(w[i - 15], 18) ^ ((w[i - 15] & 0xFFFFFFFF) >> 3); + uint32_t s1 = rr(w[i - 2], 17) ^ rr(w[i - 2], 19) ^ ((w[i - 2] & 0xFFFFFFFF) >> 10); + w[i] = w[i - 16] + s0 + w[i - 7] + s1; } - static uint32_t k[] = {0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5, 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174, 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da, 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967, 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85, 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070, 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3, 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2}; + static uint32_t k[] ={0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, + 0x923f82a4, 0xab1c5ed5, 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, + 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174, 0xe49b69c1, 0xefbe4786, + 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da, + 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, + 0x06ca6351, 0x14292967, 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, + 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85, 0xa2bfe8a1, 0xa81a664b, + 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070, + 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, + 0x5b9cca4f, 0x682e6ff3, 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, + 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2}; uint32_t a = hash[0]; uint32_t b = hash[1]; uint32_t c = hash[2]; @@ -170,8 +191,8 @@ namespace Secure { uint32_t g = hash[6]; uint32_t h = hash[7]; for (unsigned int i = 0; i < 64; ++i){ - uint32_t temp1 = h + (rr(e, 6) ^ rr(e, 11) ^ rr(e, 25)) + (g^(e&(f^g))) + k[i] + w[i]; - uint32_t temp2 = (rr(a, 2) ^ rr(a, 13) ^ rr(a, 22)) + ((a&b)|(c&(a|b))); + uint32_t temp1 = h + (rr(e, 6) ^ rr(e, 11) ^ rr(e, 25)) + (g ^ (e & (f ^ g))) + k[i] + w[i]; + uint32_t temp2 = (rr(a, 2) ^ rr(a, 13) ^ rr(a, 22)) + ((a & b) | (c & (a | b))); h = g; g = f; f = e; @@ -193,31 +214,32 @@ namespace Secure { /// Calculates a SHA256 digest as per NSAs SHA-2, returning it as binary. /// Assumes output is big enough to contain 16 bytes of data. - void sha256bin(const char * input, const unsigned int in_len, char * output){ - //Initialize the hash, according to MD5 spec. - uint32_t hash[] = {0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19}; - //Add as many whole blocks of 64 bytes as possible from the input, until < 64 are left. + void sha256bin(const char *input, const unsigned int in_len, char *output){ + // Initialize the hash, according to MD5 spec. + uint32_t hash[] ={0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, + 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19}; + // Add as many whole blocks of 64 bytes as possible from the input, until < 64 are left. unsigned int offset = 0; - while (offset+64 <= in_len){ - sha256_add64(hash, input+offset); + while (offset + 64 <= in_len){ + sha256_add64(hash, input + offset); offset += 64; } - //now, copy the remainder to a 64 byte buffer. + // now, copy the remainder to a 64 byte buffer. char buffer[64]; - memcpy(buffer, input+offset, in_len-offset); - //Calculate how much we've filled in that buffer + memcpy(buffer, input + offset, in_len - offset); + // Calculate how much we've filled in that buffer offset = in_len - offset; - //We know at least 1 byte must be empty, so we can safely do this - buffer[offset] = 0x80;//append 0x80 - //fill to the end of the buffer with zeroes - memset(buffer+offset+1, 0, 64-offset-1); + // We know at least 1 byte must be empty, so we can safely do this + buffer[offset] = 0x80; // append 0x80 + // fill to the end of the buffer with zeroes + memset(buffer + offset + 1, 0, 64 - offset - 1); if (offset > 55){ - //There's no space for the length, add what we have and zero it + // There's no space for the length, add what we have and zero it sha256_add64(hash, buffer); memset(buffer, 0, 64); } unsigned long long bit_len = in_len << 3; - //Write the length into the last 8 bytes + // Write the length into the last 8 bytes buffer[56] = (bit_len >> 54) & 0xff; buffer[57] = (bit_len >> 48) & 0xff; buffer[58] = (bit_len >> 40) & 0xff; @@ -226,9 +248,9 @@ namespace Secure { buffer[61] = (bit_len >> 16) & 0xff; buffer[62] = (bit_len >> 8) & 0xff; buffer[63] = (bit_len >> 0) & 0xff; - //Add the last bit of buffer + // Add the last bit of buffer sha256_add64(hash, buffer); - //Write result to output + // Write result to output output[3] = hash[0] & 0xff; output[2] = (hash[0] >> 8) & 0xff; output[1] = (hash[0] >> 16) & 0xff; @@ -263,13 +285,12 @@ namespace Secure { output[28] = (hash[7] >> 24) & 0xff; } - - /// Performs HMAC on msg with given key. /// Uses given hasher function, requires hashSize to be set accordingly. /// Output is returned as hexadecimal alphanumeric string. /// The hasher function must be the "bin" version of the hasher to have a compatible function signature. - std::string hmac(std::string msg, std::string key, unsigned int hashSize, void hasher(const char *, const unsigned int, char*), unsigned int blockSize){ + std::string hmac(std::string msg, std::string key, unsigned int hashSize, + void hasher(const char *, const unsigned int, char *), unsigned int blockSize){ return hmac(msg.data(), msg.size(), key.data(), key.size(), hashSize, hasher, blockSize); } @@ -277,7 +298,9 @@ namespace Secure { /// Uses given hasher function, requires hashSize to be set accordingly. /// Output is returned as hexadecimal alphanumeric string. /// The hasher function must be the "bin" version of the hasher to have a compatible function signature. - std::string hmac(const char * msg, const unsigned int msg_len, const char * key, const unsigned int key_len, unsigned int hashSize, void hasher(const char *, const unsigned int, char*), unsigned int blockSize){ + std::string hmac(const char *msg, const unsigned int msg_len, const char *key, + const unsigned int key_len, unsigned int hashSize, + void hasher(const char *, const unsigned int, char *), unsigned int blockSize){ char output[hashSize]; hmacbin(msg, msg_len, key, key_len, hashSize, hasher, blockSize, output); std::stringstream outStr; @@ -291,30 +314,32 @@ namespace Secure { /// Uses given hasher function, requires hashSize to be set accordingly. /// Output is written in binary form to output, and assumes hashSize bytes are available to be written to. /// The hasher function must be the "bin" version of the hasher to have a compatible function signature. - void hmacbin(const char * msg, const unsigned int msg_len, const char * key, const unsigned int key_len, unsigned int hashSize, void hasher(const char*, const unsigned int, char*), unsigned int blockSize, char * output){ - char key_data[blockSize];//holds key as used in HMAC algorithm + void hmacbin(const char *msg, const unsigned int msg_len, const char *key, const unsigned int key_len, + unsigned int hashSize, void hasher(const char *, const unsigned int, char *), + unsigned int blockSize, char *output){ + char key_data[blockSize]; // holds key as used in HMAC algorithm if (key_len > blockSize){ - //If the key given is too big, hash it. + // If the key given is too big, hash it. hasher(key, key_len, key_data); - memset(key_data+hashSize, 0, blockSize-hashSize); + memset(key_data + hashSize, 0, blockSize - hashSize); }else{ - //Otherwise, use as-is, zero-padded if too small. + // Otherwise, use as-is, zero-padded if too small. memcpy(key_data, key, key_len); - memset(key_data+key_len, 0, blockSize-key_len); + memset(key_data + key_len, 0, blockSize - key_len); } - //key_data now contains hashSize bytes of key data, treated as per spec. - char inner[blockSize+msg_len];//holds data for inner hash - char outer[blockSize+hashSize];//holds data for outer hash + // key_data now contains hashSize bytes of key data, treated as per spec. + char inner[blockSize + msg_len]; // holds data for inner hash + char outer[blockSize + hashSize]; // holds data for outer hash for (unsigned int i = 0; i < blockSize; ++i){ inner[i] = key_data[i] ^ 0x36; outer[i] = key_data[i] ^ 0x5c; } - //Copy the message to the inner hash data buffer - memcpy(inner+blockSize, msg, msg_len); - //Calculate the inner hash - hasher(inner, blockSize+msg_len, outer+blockSize); - //Calculate the outer hash - hasher(outer, blockSize+hashSize, output); + // Copy the message to the inner hash data buffer + memcpy(inner + blockSize, msg, msg_len); + // Calculate the inner hash + hasher(inner, blockSize + msg_len, outer + blockSize); + // Calculate the outer hash + hasher(outer, blockSize + hashSize, output); } /// Convenience function that returns the hexadecimal alphanumeric HMAC-SHA256 of msg and key @@ -323,15 +348,15 @@ namespace Secure { } /// Convenience function that returns the hexadecimal alphanumeric HMAC-SHA256 of msg and key - std::string hmac_sha256(const char * msg, const unsigned int msg_len, const char * key, const unsigned int key_len){ + std::string hmac_sha256(const char *msg, const unsigned int msg_len, const char *key, const unsigned int key_len){ return hmac(msg, msg_len, key, key_len, 32, sha256bin, 64); } /// Convenience function that sets output to the HMAC-SHA256 of msg and key in binary format. /// Assumes at least 32 bytes are available for writing in output. - void hmac_sha256bin(const char * msg, const unsigned int msg_len, const char * key, const unsigned int key_len, char * output){ + void hmac_sha256bin(const char *msg, const unsigned int msg_len, const char *key, + const unsigned int key_len, char *output){ return hmacbin(msg, msg_len, key, key_len, 32, sha256bin, 64, output); } -} - +}// namespace Secure diff --git a/lib/auth.h b/lib/auth.h index ec5132c4..b3a4050f 100644 --- a/lib/auth.h +++ b/lib/auth.h @@ -1,25 +1,30 @@ #pragma once #include -namespace Secure { - //MD5 hashing functions +namespace Secure{ + // MD5 hashing functions std::string md5(std::string input); - std::string md5(const char * input, const unsigned int in_len); - void md5bin(const char * input, const unsigned int in_len, char * output); + std::string md5(const char *input, const unsigned int in_len); + void md5bin(const char *input, const unsigned int in_len, char *output); - //SHA256 hashing functions + // SHA256 hashing functions std::string sha256(std::string input); - std::string sha256(const char * input, const unsigned int in_len); - void sha256bin(const char * input, const unsigned int in_len, char * output); + std::string sha256(const char *input, const unsigned int in_len); + void sha256bin(const char *input, const unsigned int in_len, char *output); - //Generic HMAC functions - std::string hmac(std::string msg, std::string key, unsigned int hashSize, void hasher(const char *, const unsigned int, char*), unsigned int blockSize); - std::string hmac(const char * msg, const unsigned int msg_len, const char * key, const unsigned int key_len, unsigned int hashSize, void hasher(const char *, const unsigned int, char*), unsigned int blockSize); - void hmacbin(const char * msg, const unsigned int msg_len, const char * key, const unsigned int key_len, unsigned int hashSize, void hasher(const char*, const unsigned int, char*), unsigned int blockSize, char * output); - //Specific HMAC functions + // Generic HMAC functions + std::string hmac(std::string msg, std::string key, unsigned int hashSize, + void hasher(const char *, const unsigned int, char *), unsigned int blockSize); + std::string hmac(const char *msg, const unsigned int msg_len, const char *key, + const unsigned int key_len, unsigned int hashSize, + void hasher(const char *, const unsigned int, char *), unsigned int blockSize); + void hmacbin(const char *msg, const unsigned int msg_len, const char *key, const unsigned int key_len, + unsigned int hashSize, void hasher(const char *, const unsigned int, char *), + unsigned int blockSize, char *output); + // Specific HMAC functions std::string hmac_sha256(std::string msg, std::string key); - std::string hmac_sha256(const char * msg, const unsigned int msg_len, const char * key, const unsigned int key_len); - void hmac_sha256bin(const char * msg, const unsigned int msg_len, const char * key, const unsigned int key_len, char * output); - -} + std::string hmac_sha256(const char *msg, const unsigned int msg_len, const char *key, const unsigned int key_len); + void hmac_sha256bin(const char *msg, const unsigned int msg_len, const char *key, + const unsigned int key_len, char *output); +}// namespace Secure diff --git a/lib/bitfields.cpp b/lib/bitfields.cpp index 2586878d..be1a4d95 100644 --- a/lib/bitfields.cpp +++ b/lib/bitfields.cpp @@ -35,8 +35,7 @@ unsigned long long Bit::getMSB(char *pointer, unsigned int offsetBits, unsigned /// This function assumes Most Significant Bits first. /// WARNING: UNFINISHED. DO NOT USE. /// \todo Finish writing this - untested atm. -void Bit::setMSB(char *pointer, unsigned int offsetBits, unsigned int dataBits, - unsigned long long value){ +void Bit::setMSB(char *pointer, unsigned int offsetBits, unsigned int dataBits, unsigned long long value){ // Set the pointer to the last byte we need to be setting pointer += (offsetBits + dataBits) >> 3; // The offset is now guaranteed less than a whole byte. @@ -73,4 +72,3 @@ bool Util::stringToBool(std::string &str){ return (strncmp(tmp.c_str(), "1", 1) == 0 || strncmp(tmp.c_str(), "yes", 3) == 0 || strncmp(tmp.c_str(), "true", 4) == 0 || strncmp(tmp.c_str(), "cont", 4) == 0); } - diff --git a/lib/bitfields.h b/lib/bitfields.h index e4e68ed6..5b164664 100644 --- a/lib/bitfields.h +++ b/lib/bitfields.h @@ -11,8 +11,7 @@ namespace Bit{ unsigned long long getMSB(char *pointer, unsigned int offsetBits, unsigned int dataBits); unsigned long long getByName(char *pointer); // bitfield setters - void setMSB(char *pointer, unsigned int offsetBits, unsigned int dataBits, - unsigned long long value); + void setMSB(char *pointer, unsigned int offsetBits, unsigned int dataBits, unsigned long long value); void setByName(char *pointer); // Host to binary/binary to host functions - similar to kernel ntoh/hton functions. @@ -143,8 +142,7 @@ namespace Bit{ /// Retrieves a long in network order from the pointer p. inline unsigned long btohl_le(const char *p){ - return ((unsigned long)p[3] << 24) | ((unsigned long)p[2] << 16) | ((unsigned long)p[1] << 8) | - p[0]; + return ((unsigned long)p[3] << 24) | ((unsigned long)p[2] << 16) | ((unsigned long)p[1] << 8) | p[0]; } /// Stores a long value of val in little endian to the pointer p. @@ -171,8 +169,7 @@ namespace Bit{ inline unsigned long long btohll_le(const char *p){ return ((unsigned long long)p[7] << 56) | ((unsigned long long)p[6] << 48) | ((unsigned long long)p[5] << 40) | ((unsigned long long)p[4] << 32) | - ((unsigned long)p[3] << 24) | ((unsigned long)p[2] << 16) | ((unsigned long)p[1] << 8) | - p[0]; + ((unsigned long)p[3] << 24) | ((unsigned long)p[2] << 16) | ((unsigned long)p[1] << 8) | p[0]; } /// Stores a long value of val in little endian to the pointer p. @@ -188,4 +185,3 @@ namespace Bit{ } }// namespace Bit - diff --git a/lib/bitstream.cpp b/lib/bitstream.cpp index faa82b13..8288ec9a 100644 --- a/lib/bitstream.cpp +++ b/lib/bitstream.cpp @@ -50,8 +50,7 @@ namespace Utils{ // return 0; } if (count > size()){ - DEBUG_MSG(DLVL_ERROR, "Not enough bits left in stream. Left: %d requested: %d", (int)size(), - (int)count); + DEBUG_MSG(DLVL_ERROR, "Not enough bits left in stream. Left: %d requested: %d", (int)size(), (int)count); return 0; } long long unsigned int retval = 0; @@ -131,16 +130,14 @@ namespace Utils{ long long int bitstream::getExpGolomb(){ long long unsigned int temp = golombGetter(); - return (temp >> 1) * - (1 - ((temp & 1) << 1)); // Is actually return (temp / 2) * (1 - (temp & 1) * 2); + return (temp >> 1) * (1 - ((temp & 1) << 1)); // Is actually return (temp / 2) * (1 - (temp & 1) * 2); } long long unsigned int bitstream::getUExpGolomb(){return golombGetter() - 1;} long long int bitstream::peekExpGolomb(){ long long unsigned int temp = golombPeeker(); - return (temp >> 1) * - (1 - ((temp & 1) << 1)); // Is actually return (temp / 2) * (1 - (temp & 1) * 2); + return (temp >> 1) * (1 - ((temp & 1) << 1)); // Is actually return (temp / 2) * (1 - (temp & 1) * 2); } long long unsigned int bitstream::peekUExpGolomb(){return golombPeeker() - 1;} @@ -285,4 +282,3 @@ namespace Utils{ data.erase(0, pos); } }// namespace Utils - diff --git a/lib/bitstream.h b/lib/bitstream.h index e16b580f..9d035714 100644 --- a/lib/bitstream.h +++ b/lib/bitstream.h @@ -93,4 +93,3 @@ namespace Utils{ void fixData(); }; }// namespace Utils - diff --git a/lib/certificate.cpp b/lib/certificate.cpp index 01b7e801..5ad5c783 100644 --- a/lib/certificate.cpp +++ b/lib/certificate.cpp @@ -1,181 +1,174 @@ #include "certificate.h" #include "defines.h" -Certificate::Certificate() - :rsa_ctx(NULL) -{ - memset((void*)&cert, 0x00, sizeof(cert)); - memset((void*)&key, 0x00, sizeof(key)); +Certificate::Certificate() : rsa_ctx(NULL){ + memset((void *)&cert, 0x00, sizeof(cert)); + memset((void *)&key, 0x00, sizeof(key)); } - -int Certificate::init(const std::string &countryName, - const std::string &organization, - const std::string& commonName) -{ - mbedtls_ctr_drbg_context rand_ctx = {}; - mbedtls_entropy_context entropy_ctx = {}; - mbedtls_x509write_cert write_cert = {}; +int Certificate::init(const std::string &countryName, const std::string &organization, + const std::string &commonName){ - const char* personalisation = "mbedtls-self-signed-key"; - std::string subject_name = "C=" +countryName +",O=" +organization +",CN=" +commonName; - time_t time_from = { 0 }; - time_t time_to = { 0 }; - char time_from_str[20] = { 0 }; - char time_to_str[20] = { 0 }; - mbedtls_mpi serial_mpi = { 0 }; - char serial_hex[17] = { 0 }; + mbedtls_ctr_drbg_context rand_ctx ={}; + mbedtls_entropy_context entropy_ctx ={}; + mbedtls_x509write_cert write_cert ={}; + + const char *personalisation = "mbedtls-self-signed-key"; + std::string subject_name = "C=" + countryName + ",O=" + organization + ",CN=" + commonName; + time_t time_from ={0}; + time_t time_to ={0}; + char time_from_str[20] ={0}; + char time_to_str[20] ={0}; + mbedtls_mpi serial_mpi ={0}; + char serial_hex[17] ={0}; uint64_t serial_num = 0; - uint8_t* serial_ptr = (uint8_t*)&serial_num; + uint8_t *serial_ptr = (uint8_t *)&serial_num; int r = 0; int i = 0; - uint8_t buf[4096] = { 0 }; + uint8_t buf[4096] ={0}; // validate - if (countryName.empty()) { + if (countryName.empty()){ FAIL_MSG("Given `countryName`, C=, is empty."); r = -1; goto error; } - if (organization.empty()) { + if (organization.empty()){ FAIL_MSG("Given `organization`, O=, is empty."); r = -2; goto error; } - if (commonName.empty()) { + if (commonName.empty()){ FAIL_MSG("Given `commonName`, CN=, is empty."); r = -3; goto error; } - - // initialize random number generator + + // initialize random number generator mbedtls_ctr_drbg_init(&rand_ctx); mbedtls_entropy_init(&entropy_ctx); - r = mbedtls_ctr_drbg_seed(&rand_ctx, mbedtls_entropy_func, &entropy_ctx, (const unsigned char*)personalisation, strlen(personalisation)); - if (0 != r) { + r = mbedtls_ctr_drbg_seed(&rand_ctx, mbedtls_entropy_func, &entropy_ctx, + (const unsigned char *)personalisation, strlen(personalisation)); + if (0 != r){ FAIL_MSG("Failed to initialize and seed the entropy context."); r = -10; goto error; } // initialize the public key context - mbedtls_pk_init(&key); + mbedtls_pk_init(&key); r = mbedtls_pk_setup(&key, mbedtls_pk_info_from_type(MBEDTLS_PK_RSA)); - if (0 != r) { + if (0 != r){ FAIL_MSG("Faild to initialize the PK context."); r = -20; goto error; } - + rsa_ctx = mbedtls_pk_rsa(key); - if (NULL == rsa_ctx) { + if (NULL == rsa_ctx){ FAIL_MSG("Failed to get the RSA context from from the public key context (key)."); r = -30; goto error; } - + r = mbedtls_rsa_gen_key(rsa_ctx, mbedtls_ctr_drbg_random, &rand_ctx, 2048, 65537); - if (0 != r) { + if (0 != r){ FAIL_MSG("Failed to generate a private key."); r = -40; goto error; } - // calc the valid from and until time. + // calc the valid from and until time. time_from = time(NULL); time_from = (time_from < 1000000000) ? 1000000000 : time_from; time_to = time_from + (60 * 60 * 24 * 365); // valid for a year - if (time_to < time_from) { - time_to = INT_MAX; - } - + if (time_to < time_from){time_to = INT_MAX;} + r = strftime(time_from_str, sizeof(time_from_str), "%Y%m%d%H%M%S", gmtime(&time_from)); - if (0 == r) { + if (0 == r){ FAIL_MSG("Failed to generate the valid-from time string."); r = -50; goto error; } - + r = strftime(time_to_str, sizeof(time_to_str), "%Y%m%d%H%M%S", gmtime(&time_to)); - if (0 == r) { + if (0 == r){ FAIL_MSG("Failed to generate the valid-to time string."); r = -60; goto error; } - r = mbedtls_ctr_drbg_random((void*)&rand_ctx, (uint8_t*)&serial_num, sizeof(serial_num)); - if (0 != r) { + r = mbedtls_ctr_drbg_random((void *)&rand_ctx, (uint8_t *)&serial_num, sizeof(serial_num)); + if (0 != r){ FAIL_MSG("Failed to generate a random u64."); r = -70; goto error; } - - for (i = 0; i < 8; ++i) { - sprintf(serial_hex + (i * 2), "%02x", serial_ptr[i]); - } + + for (i = 0; i < 8; ++i){sprintf(serial_hex + (i * 2), "%02x", serial_ptr[i]);} // start creating the certificate mbedtls_x509write_crt_init(&write_cert); - mbedtls_x509write_crt_set_md_alg(&write_cert, MBEDTLS_MD_SHA256); + mbedtls_x509write_crt_set_md_alg(&write_cert, MBEDTLS_MD_SHA256); mbedtls_x509write_crt_set_issuer_key(&write_cert, &key); mbedtls_x509write_crt_set_subject_key(&write_cert, &key); r = mbedtls_x509write_crt_set_subject_name(&write_cert, subject_name.c_str()); - if (0 != r) { + if (0 != r){ FAIL_MSG("Failed to set the subject name."); r = -80; goto error; } r = mbedtls_x509write_crt_set_issuer_name(&write_cert, subject_name.c_str()); - if (0 != r) { + if (0 != r){ FAIL_MSG("Failed to set the issuer name."); r = -90; goto error; } r = mbedtls_x509write_crt_set_validity(&write_cert, time_from_str, time_to_str); - if (0 != r) { + if (0 != r){ FAIL_MSG("Failed to set the x509 validity string."); r = -100; goto error; } - + r = mbedtls_x509write_crt_set_basic_constraints(&write_cert, 0, -1); - if (0 != r) { + if (0 != r){ FAIL_MSG("Failed ot set the basic constraints for the certificate."); r = -110; goto error; } r = mbedtls_x509write_crt_set_subject_key_identifier(&write_cert); - if (0 != r) { + if (0 != r){ FAIL_MSG("Failed to set the subjectKeyIdentifier."); r = -120; goto error; } r = mbedtls_x509write_crt_set_authority_key_identifier(&write_cert); - if (0 != r) { + if (0 != r){ FAIL_MSG("Failed to set the authorityKeyIdentifier."); r = -130; goto error; } - // set certificate serial; mpi is used to perform i/o + // set certificate serial; mpi is used to perform i/o mbedtls_mpi_init(&serial_mpi); mbedtls_mpi_read_string(&serial_mpi, 16, serial_hex); r = mbedtls_x509write_crt_set_serial(&write_cert, &serial_mpi); - if (0 != r) { + if (0 != r){ FAIL_MSG("Failed to set the certificate serial."); r = -140; goto error; } - // write the certificate into a PEM structure + // write the certificate into a PEM structure r = mbedtls_x509write_crt_pem(&write_cert, buf, sizeof(buf), mbedtls_ctr_drbg_random, &rand_ctx); - if (0 != r) { + if (0 != r){ FAIL_MSG("Failed to create the PEM data from the x509 write structure."); r = -150; goto error; @@ -187,54 +180,49 @@ int Certificate::init(const std::string &countryName, // struct into a `mbedtls_x509_cert` w/o calling this parse // function. mbedtls_x509_crt_init(&cert); - - r = mbedtls_x509_crt_parse(&cert, (const unsigned char*)buf, strlen((char*)buf) + 1); - if (0 != r) { - mbedtls_strerror(r, (char*)buf, sizeof(buf)); + + r = mbedtls_x509_crt_parse(&cert, (const unsigned char *)buf, strlen((char *)buf) + 1); + if (0 != r){ + mbedtls_strerror(r, (char *)buf, sizeof(buf)); FAIL_MSG("Failed to convert the mbedtls_x509write_crt into a mbedtls_x509_crt: %s", buf); r = -160; goto error; } - - error: - - // cleanup + +error: + + // cleanup mbedtls_ctr_drbg_free(&rand_ctx); mbedtls_entropy_free(&entropy_ctx); mbedtls_x509write_crt_free(&write_cert); mbedtls_mpi_free(&serial_mpi); - if (r < 0) { - shutdown(); - } - + if (r < 0){shutdown();} + return r; } -int Certificate::shutdown() { +int Certificate::shutdown(){ rsa_ctx = NULL; mbedtls_pk_free(&key); mbedtls_x509_crt_free(&cert); return 0; } -std::string Certificate::getFingerprintSha256() { - - uint8_t fingerprint_raw[32] = {}; - uint8_t fingerprint_hex[128] = {}; +std::string Certificate::getFingerprintSha256(){ + + uint8_t fingerprint_raw[32] ={}; + uint8_t fingerprint_hex[128] ={}; mbedtls_md_type_t hash_type = MBEDTLS_MD_SHA256; mbedtls_sha256(cert.raw.p, cert.raw.len, fingerprint_raw, 0); - - for (int i = 0; i < 32; ++i) { - sprintf((char*)(fingerprint_hex + (i * 3)), ":%02X", (int)fingerprint_raw[i]); + + for (int i = 0; i < 32; ++i){ + sprintf((char *)(fingerprint_hex + (i * 3)), ":%02X", (int)fingerprint_raw[i]); } fingerprint_hex[32 * 3] = '\0'; - std::string result = std::string((char*)fingerprint_hex + 1, (32 * 3) - 1); + std::string result = std::string((char *)fingerprint_hex + 1, (32 * 3) - 1); return result; } - - - diff --git a/lib/certificate.h b/lib/certificate.h index 24a7a2fa..0b717810 100644 --- a/lib/certificate.h +++ b/lib/certificate.h @@ -3,32 +3,32 @@ MBEDTLS BASED CERTIFICATE ========================= - + This class can be used to generate a self-signed x509 certificate which enables you to perform secure communication. This certificate uses a 2048 bits RSA key. */ -#include #include +#include +#include +#include +#include +#include #include #include -#include -#include -#include -#include -#include +#include -class Certificate { +class Certificate{ public: Certificate(); - int init(const std::string &countryName, const std::string &organization, const std::string& commonName); + int init(const std::string &countryName, const std::string &organization, const std::string &commonName); int shutdown(); std::string getFingerprintSha256(); - + public: mbedtls_x509_crt cert; - mbedtls_pk_context key; /* key context, stores private and public key. */ - mbedtls_rsa_context* rsa_ctx; /* rsa context, stored in key_ctx */ + mbedtls_pk_context key; /* key context, stores private and public key. */ + mbedtls_rsa_context *rsa_ctx; /* rsa context, stored in key_ctx */ }; diff --git a/lib/checksum.h b/lib/checksum.h index a409aa31..5568c89f 100644 --- a/lib/checksum.h +++ b/lib/checksum.h @@ -1,231 +1,146 @@ #include -namespace checksum { - inline unsigned int crc32c(unsigned int crc, const char * data, size_t len) { - static const unsigned int table[256] = { - 0x00000000U, 0x04C11DB7U, 0x09823B6EU, 0x0D4326D9U, - 0x130476DCU, 0x17C56B6BU, 0x1A864DB2U, 0x1E475005U, - 0x2608EDB8U, 0x22C9F00FU, 0x2F8AD6D6U, 0x2B4BCB61U, - 0x350C9B64U, 0x31CD86D3U, 0x3C8EA00AU, 0x384FBDBDU, - 0x4C11DB70U, 0x48D0C6C7U, 0x4593E01EU, 0x4152FDA9U, - 0x5F15ADACU, 0x5BD4B01BU, 0x569796C2U, 0x52568B75U, - 0x6A1936C8U, 0x6ED82B7FU, 0x639B0DA6U, 0x675A1011U, - 0x791D4014U, 0x7DDC5DA3U, 0x709F7B7AU, 0x745E66CDU, - 0x9823B6E0U, 0x9CE2AB57U, 0x91A18D8EU, 0x95609039U, - 0x8B27C03CU, 0x8FE6DD8BU, 0x82A5FB52U, 0x8664E6E5U, - 0xBE2B5B58U, 0xBAEA46EFU, 0xB7A96036U, 0xB3687D81U, - 0xAD2F2D84U, 0xA9EE3033U, 0xA4AD16EAU, 0xA06C0B5DU, - 0xD4326D90U, 0xD0F37027U, 0xDDB056FEU, 0xD9714B49U, - 0xC7361B4CU, 0xC3F706FBU, 0xCEB42022U, 0xCA753D95U, - 0xF23A8028U, 0xF6FB9D9FU, 0xFBB8BB46U, 0xFF79A6F1U, - 0xE13EF6F4U, 0xE5FFEB43U, 0xE8BCCD9AU, 0xEC7DD02DU, - 0x34867077U, 0x30476DC0U, 0x3D044B19U, 0x39C556AEU, - 0x278206ABU, 0x23431B1CU, 0x2E003DC5U, 0x2AC12072U, - 0x128E9DCFU, 0x164F8078U, 0x1B0CA6A1U, 0x1FCDBB16U, - 0x018AEB13U, 0x054BF6A4U, 0x0808D07DU, 0x0CC9CDCAU, - 0x7897AB07U, 0x7C56B6B0U, 0x71159069U, 0x75D48DDEU, - 0x6B93DDDBU, 0x6F52C06CU, 0x6211E6B5U, 0x66D0FB02U, - 0x5E9F46BFU, 0x5A5E5B08U, 0x571D7DD1U, 0x53DC6066U, - 0x4D9B3063U, 0x495A2DD4U, 0x44190B0DU, 0x40D816BAU, - 0xACA5C697U, 0xA864DB20U, 0xA527FDF9U, 0xA1E6E04EU, - 0xBFA1B04BU, 0xBB60ADFCU, 0xB6238B25U, 0xB2E29692U, - 0x8AAD2B2FU, 0x8E6C3698U, 0x832F1041U, 0x87EE0DF6U, - 0x99A95DF3U, 0x9D684044U, 0x902B669DU, 0x94EA7B2AU, - 0xE0B41DE7U, 0xE4750050U, 0xE9362689U, 0xEDF73B3EU, - 0xF3B06B3BU, 0xF771768CU, 0xFA325055U, 0xFEF34DE2U, - 0xC6BCF05FU, 0xC27DEDE8U, 0xCF3ECB31U, 0xCBFFD686U, - 0xD5B88683U, 0xD1799B34U, 0xDC3ABDEDU, 0xD8FBA05AU, - 0x690CE0EEU, 0x6DCDFD59U, 0x608EDB80U, 0x644FC637U, - 0x7A089632U, 0x7EC98B85U, 0x738AAD5CU, 0x774BB0EBU, - 0x4F040D56U, 0x4BC510E1U, 0x46863638U, 0x42472B8FU, - 0x5C007B8AU, 0x58C1663DU, 0x558240E4U, 0x51435D53U, - 0x251D3B9EU, 0x21DC2629U, 0x2C9F00F0U, 0x285E1D47U, - 0x36194D42U, 0x32D850F5U, 0x3F9B762CU, 0x3B5A6B9BU, - 0x0315D626U, 0x07D4CB91U, 0x0A97ED48U, 0x0E56F0FFU, - 0x1011A0FAU, 0x14D0BD4DU, 0x19939B94U, 0x1D528623U, - 0xF12F560EU, 0xF5EE4BB9U, 0xF8AD6D60U, 0xFC6C70D7U, - 0xE22B20D2U, 0xE6EA3D65U, 0xEBA91BBCU, 0xEF68060BU, - 0xD727BBB6U, 0xD3E6A601U, 0xDEA580D8U, 0xDA649D6FU, - 0xC423CD6AU, 0xC0E2D0DDU, 0xCDA1F604U, 0xC960EBB3U, - 0xBD3E8D7EU, 0xB9FF90C9U, 0xB4BCB610U, 0xB07DABA7U, - 0xAE3AFBA2U, 0xAAFBE615U, 0xA7B8C0CCU, 0xA379DD7BU, - 0x9B3660C6U, 0x9FF77D71U, 0x92B45BA8U, 0x9675461FU, - 0x8832161AU, 0x8CF30BADU, 0x81B02D74U, 0x857130C3U, - 0x5D8A9099U, 0x594B8D2EU, 0x5408ABF7U, 0x50C9B640U, - 0x4E8EE645U, 0x4A4FFBF2U, 0x470CDD2BU, 0x43CDC09CU, - 0x7B827D21U, 0x7F436096U, 0x7200464FU, 0x76C15BF8U, - 0x68860BFDU, 0x6C47164AU, 0x61043093U, 0x65C52D24U, - 0x119B4BE9U, 0x155A565EU, 0x18197087U, 0x1CD86D30U, - 0x029F3D35U, 0x065E2082U, 0x0B1D065BU, 0x0FDC1BECU, - 0x3793A651U, 0x3352BBE6U, 0x3E119D3FU, 0x3AD08088U, - 0x2497D08DU, 0x2056CD3AU, 0x2D15EBE3U, 0x29D4F654U, - 0xC5A92679U, 0xC1683BCEU, 0xCC2B1D17U, 0xC8EA00A0U, - 0xD6AD50A5U, 0xD26C4D12U, 0xDF2F6BCBU, 0xDBEE767CU, - 0xE3A1CBC1U, 0xE760D676U, 0xEA23F0AFU, 0xEEE2ED18U, - 0xF0A5BD1DU, 0xF464A0AAU, 0xF9278673U, 0xFDE69BC4U, - 0x89B8FD09U, 0x8D79E0BEU, 0x803AC667U, 0x84FBDBD0U, - 0x9ABC8BD5U, 0x9E7D9662U, 0x933EB0BBU, 0x97FFAD0CU, - 0xAFB010B1U, 0xAB710D06U, 0xA6322BDFU, 0xA2F33668U, - 0xBCB4666DU, 0xB8757BDAU, 0xB5365D03U, 0xB1F740B4U, +namespace checksum{ + inline unsigned int crc32c(unsigned int crc, const char *data, size_t len){ + static const unsigned int table[256] ={ + 0x00000000U, 0x04C11DB7U, 0x09823B6EU, 0x0D4326D9U, 0x130476DCU, 0x17C56B6BU, 0x1A864DB2U, + 0x1E475005U, 0x2608EDB8U, 0x22C9F00FU, 0x2F8AD6D6U, 0x2B4BCB61U, 0x350C9B64U, 0x31CD86D3U, + 0x3C8EA00AU, 0x384FBDBDU, 0x4C11DB70U, 0x48D0C6C7U, 0x4593E01EU, 0x4152FDA9U, 0x5F15ADACU, + 0x5BD4B01BU, 0x569796C2U, 0x52568B75U, 0x6A1936C8U, 0x6ED82B7FU, 0x639B0DA6U, 0x675A1011U, + 0x791D4014U, 0x7DDC5DA3U, 0x709F7B7AU, 0x745E66CDU, 0x9823B6E0U, 0x9CE2AB57U, 0x91A18D8EU, + 0x95609039U, 0x8B27C03CU, 0x8FE6DD8BU, 0x82A5FB52U, 0x8664E6E5U, 0xBE2B5B58U, 0xBAEA46EFU, + 0xB7A96036U, 0xB3687D81U, 0xAD2F2D84U, 0xA9EE3033U, 0xA4AD16EAU, 0xA06C0B5DU, 0xD4326D90U, + 0xD0F37027U, 0xDDB056FEU, 0xD9714B49U, 0xC7361B4CU, 0xC3F706FBU, 0xCEB42022U, 0xCA753D95U, + 0xF23A8028U, 0xF6FB9D9FU, 0xFBB8BB46U, 0xFF79A6F1U, 0xE13EF6F4U, 0xE5FFEB43U, 0xE8BCCD9AU, + 0xEC7DD02DU, 0x34867077U, 0x30476DC0U, 0x3D044B19U, 0x39C556AEU, 0x278206ABU, 0x23431B1CU, + 0x2E003DC5U, 0x2AC12072U, 0x128E9DCFU, 0x164F8078U, 0x1B0CA6A1U, 0x1FCDBB16U, 0x018AEB13U, + 0x054BF6A4U, 0x0808D07DU, 0x0CC9CDCAU, 0x7897AB07U, 0x7C56B6B0U, 0x71159069U, 0x75D48DDEU, + 0x6B93DDDBU, 0x6F52C06CU, 0x6211E6B5U, 0x66D0FB02U, 0x5E9F46BFU, 0x5A5E5B08U, 0x571D7DD1U, + 0x53DC6066U, 0x4D9B3063U, 0x495A2DD4U, 0x44190B0DU, 0x40D816BAU, 0xACA5C697U, 0xA864DB20U, + 0xA527FDF9U, 0xA1E6E04EU, 0xBFA1B04BU, 0xBB60ADFCU, 0xB6238B25U, 0xB2E29692U, 0x8AAD2B2FU, + 0x8E6C3698U, 0x832F1041U, 0x87EE0DF6U, 0x99A95DF3U, 0x9D684044U, 0x902B669DU, 0x94EA7B2AU, + 0xE0B41DE7U, 0xE4750050U, 0xE9362689U, 0xEDF73B3EU, 0xF3B06B3BU, 0xF771768CU, 0xFA325055U, + 0xFEF34DE2U, 0xC6BCF05FU, 0xC27DEDE8U, 0xCF3ECB31U, 0xCBFFD686U, 0xD5B88683U, 0xD1799B34U, + 0xDC3ABDEDU, 0xD8FBA05AU, 0x690CE0EEU, 0x6DCDFD59U, 0x608EDB80U, 0x644FC637U, 0x7A089632U, + 0x7EC98B85U, 0x738AAD5CU, 0x774BB0EBU, 0x4F040D56U, 0x4BC510E1U, 0x46863638U, 0x42472B8FU, + 0x5C007B8AU, 0x58C1663DU, 0x558240E4U, 0x51435D53U, 0x251D3B9EU, 0x21DC2629U, 0x2C9F00F0U, + 0x285E1D47U, 0x36194D42U, 0x32D850F5U, 0x3F9B762CU, 0x3B5A6B9BU, 0x0315D626U, 0x07D4CB91U, + 0x0A97ED48U, 0x0E56F0FFU, 0x1011A0FAU, 0x14D0BD4DU, 0x19939B94U, 0x1D528623U, 0xF12F560EU, + 0xF5EE4BB9U, 0xF8AD6D60U, 0xFC6C70D7U, 0xE22B20D2U, 0xE6EA3D65U, 0xEBA91BBCU, 0xEF68060BU, + 0xD727BBB6U, 0xD3E6A601U, 0xDEA580D8U, 0xDA649D6FU, 0xC423CD6AU, 0xC0E2D0DDU, 0xCDA1F604U, + 0xC960EBB3U, 0xBD3E8D7EU, 0xB9FF90C9U, 0xB4BCB610U, 0xB07DABA7U, 0xAE3AFBA2U, 0xAAFBE615U, + 0xA7B8C0CCU, 0xA379DD7BU, 0x9B3660C6U, 0x9FF77D71U, 0x92B45BA8U, 0x9675461FU, 0x8832161AU, + 0x8CF30BADU, 0x81B02D74U, 0x857130C3U, 0x5D8A9099U, 0x594B8D2EU, 0x5408ABF7U, 0x50C9B640U, + 0x4E8EE645U, 0x4A4FFBF2U, 0x470CDD2BU, 0x43CDC09CU, 0x7B827D21U, 0x7F436096U, 0x7200464FU, + 0x76C15BF8U, 0x68860BFDU, 0x6C47164AU, 0x61043093U, 0x65C52D24U, 0x119B4BE9U, 0x155A565EU, + 0x18197087U, 0x1CD86D30U, 0x029F3D35U, 0x065E2082U, 0x0B1D065BU, 0x0FDC1BECU, 0x3793A651U, + 0x3352BBE6U, 0x3E119D3FU, 0x3AD08088U, 0x2497D08DU, 0x2056CD3AU, 0x2D15EBE3U, 0x29D4F654U, + 0xC5A92679U, 0xC1683BCEU, 0xCC2B1D17U, 0xC8EA00A0U, 0xD6AD50A5U, 0xD26C4D12U, 0xDF2F6BCBU, + 0xDBEE767CU, 0xE3A1CBC1U, 0xE760D676U, 0xEA23F0AFU, 0xEEE2ED18U, 0xF0A5BD1DU, 0xF464A0AAU, + 0xF9278673U, 0xFDE69BC4U, 0x89B8FD09U, 0x8D79E0BEU, 0x803AC667U, 0x84FBDBD0U, 0x9ABC8BD5U, + 0x9E7D9662U, 0x933EB0BBU, 0x97FFAD0CU, 0xAFB010B1U, 0xAB710D06U, 0xA6322BDFU, 0xA2F33668U, + 0xBCB4666DU, 0xB8757BDAU, 0xB5365D03U, 0xB1F740B4U, }; - while (len > 0) { + while (len > 0){ crc = table[*data ^ ((crc >> 24) & 0xff)] ^ (crc << 8); data++; len--; } return crc; } - - inline unsigned int crc32LE(unsigned int crc, const char * data, size_t len) { - static const unsigned int table[256] = { - 0x00000000U, 0x77073096U, 0xee0e612cU, 0x990951baU, - 0x076dc419U, 0x706af48fU, 0xe963a535U, 0x9e6495a3U, - 0x0edb8832U, 0x79dcb8a4U, 0xe0d5e91eU, 0x97d2d988U, - 0x09b64c2bU, 0x7eb17cbdU, 0xe7b82d07U, 0x90bf1d91U, - 0x1db71064U, 0x6ab020f2U, 0xf3b97148U, 0x84be41deU, - 0x1adad47dU, 0x6ddde4ebU, 0xf4d4b551U, 0x83d385c7U, - 0x136c9856U, 0x646ba8c0U, 0xfd62f97aU, 0x8a65c9ecU, - 0x14015c4fU, 0x63066cd9U, 0xfa0f3d63U, 0x8d080df5U, - 0x3b6e20c8U, 0x4c69105eU, 0xd56041e4U, 0xa2677172U, - 0x3c03e4d1U, 0x4b04d447U, 0xd20d85fdU, 0xa50ab56bU, - 0x35b5a8faU, 0x42b2986cU, 0xdbbbc9d6U, 0xacbcf940U, - 0x32d86ce3U, 0x45df5c75U, 0xdcd60dcfU, 0xabd13d59U, - 0x26d930acU, 0x51de003aU, 0xc8d75180U, 0xbfd06116U, - 0x21b4f4b5U, 0x56b3c423U, 0xcfba9599U, 0xb8bda50fU, - 0x2802b89eU, 0x5f058808U, 0xc60cd9b2U, 0xb10be924U, - 0x2f6f7c87U, 0x58684c11U, 0xc1611dabU, 0xb6662d3dU, - 0x76dc4190U, 0x01db7106U, 0x98d220bcU, 0xefd5102aU, - 0x71b18589U, 0x06b6b51fU, 0x9fbfe4a5U, 0xe8b8d433U, - 0x7807c9a2U, 0x0f00f934U, 0x9609a88eU, 0xe10e9818U, - 0x7f6a0dbbU, 0x086d3d2dU, 0x91646c97U, 0xe6635c01U, - 0x6b6b51f4U, 0x1c6c6162U, 0x856530d8U, 0xf262004eU, - 0x6c0695edU, 0x1b01a57bU, 0x8208f4c1U, 0xf50fc457U, - 0x65b0d9c6U, 0x12b7e950U, 0x8bbeb8eaU, 0xfcb9887cU, - 0x62dd1ddfU, 0x15da2d49U, 0x8cd37cf3U, 0xfbd44c65U, - 0x4db26158U, 0x3ab551ceU, 0xa3bc0074U, 0xd4bb30e2U, - 0x4adfa541U, 0x3dd895d7U, 0xa4d1c46dU, 0xd3d6f4fbU, - 0x4369e96aU, 0x346ed9fcU, 0xad678846U, 0xda60b8d0U, - 0x44042d73U, 0x33031de5U, 0xaa0a4c5fU, 0xdd0d7cc9U, - 0x5005713cU, 0x270241aaU, 0xbe0b1010U, 0xc90c2086U, - 0x5768b525U, 0x206f85b3U, 0xb966d409U, 0xce61e49fU, - 0x5edef90eU, 0x29d9c998U, 0xb0d09822U, 0xc7d7a8b4U, - 0x59b33d17U, 0x2eb40d81U, 0xb7bd5c3bU, 0xc0ba6cadU, - 0xedb88320U, 0x9abfb3b6U, 0x03b6e20cU, 0x74b1d29aU, - 0xead54739U, 0x9dd277afU, 0x04db2615U, 0x73dc1683U, - 0xe3630b12U, 0x94643b84U, 0x0d6d6a3eU, 0x7a6a5aa8U, - 0xe40ecf0bU, 0x9309ff9dU, 0x0a00ae27U, 0x7d079eb1U, - 0xf00f9344U, 0x8708a3d2U, 0x1e01f268U, 0x6906c2feU, - 0xf762575dU, 0x806567cbU, 0x196c3671U, 0x6e6b06e7U, - 0xfed41b76U, 0x89d32be0U, 0x10da7a5aU, 0x67dd4accU, - 0xf9b9df6fU, 0x8ebeeff9U, 0x17b7be43U, 0x60b08ed5U, - 0xd6d6a3e8U, 0xa1d1937eU, 0x38d8c2c4U, 0x4fdff252U, - 0xd1bb67f1U, 0xa6bc5767U, 0x3fb506ddU, 0x48b2364bU, - 0xd80d2bdaU, 0xaf0a1b4cU, 0x36034af6U, 0x41047a60U, - 0xdf60efc3U, 0xa867df55U, 0x316e8eefU, 0x4669be79U, - 0xcb61b38cU, 0xbc66831aU, 0x256fd2a0U, 0x5268e236U, - 0xcc0c7795U, 0xbb0b4703U, 0x220216b9U, 0x5505262fU, - 0xc5ba3bbeU, 0xb2bd0b28U, 0x2bb45a92U, 0x5cb36a04U, - 0xc2d7ffa7U, 0xb5d0cf31U, 0x2cd99e8bU, 0x5bdeae1dU, - 0x9b64c2b0U, 0xec63f226U, 0x756aa39cU, 0x026d930aU, - 0x9c0906a9U, 0xeb0e363fU, 0x72076785U, 0x05005713U, - 0x95bf4a82U, 0xe2b87a14U, 0x7bb12baeU, 0x0cb61b38U, - 0x92d28e9bU, 0xe5d5be0dU, 0x7cdcefb7U, 0x0bdbdf21U, - 0x86d3d2d4U, 0xf1d4e242U, 0x68ddb3f8U, 0x1fda836eU, - 0x81be16cdU, 0xf6b9265bU, 0x6fb077e1U, 0x18b74777U, - 0x88085ae6U, 0xff0f6a70U, 0x66063bcaU, 0x11010b5cU, - 0x8f659effU, 0xf862ae69U, 0x616bffd3U, 0x166ccf45U, - 0xa00ae278U, 0xd70dd2eeU, 0x4e048354U, 0x3903b3c2U, - 0xa7672661U, 0xd06016f7U, 0x4969474dU, 0x3e6e77dbU, - 0xaed16a4aU, 0xd9d65adcU, 0x40df0b66U, 0x37d83bf0U, - 0xa9bcae53U, 0xdebb9ec5U, 0x47b2cf7fU, 0x30b5ffe9U, - 0xbdbdf21cU, 0xcabac28aU, 0x53b39330U, 0x24b4a3a6U, - 0xbad03605U, 0xcdd70693U, 0x54de5729U, 0x23d967bfU, - 0xb3667a2eU, 0xc4614ab8U, 0x5d681b02U, 0x2a6f2b94U, - 0xb40bbe37U, 0xc30c8ea1U, 0x5a05df1bU, 0x2d02ef8dU - }; - while (len > 0) { + inline unsigned int crc32LE(unsigned int crc, const char *data, size_t len){ + static const unsigned int table[256] ={ + 0x00000000U, 0x77073096U, 0xee0e612cU, 0x990951baU, 0x076dc419U, 0x706af48fU, 0xe963a535U, + 0x9e6495a3U, 0x0edb8832U, 0x79dcb8a4U, 0xe0d5e91eU, 0x97d2d988U, 0x09b64c2bU, 0x7eb17cbdU, + 0xe7b82d07U, 0x90bf1d91U, 0x1db71064U, 0x6ab020f2U, 0xf3b97148U, 0x84be41deU, 0x1adad47dU, + 0x6ddde4ebU, 0xf4d4b551U, 0x83d385c7U, 0x136c9856U, 0x646ba8c0U, 0xfd62f97aU, 0x8a65c9ecU, + 0x14015c4fU, 0x63066cd9U, 0xfa0f3d63U, 0x8d080df5U, 0x3b6e20c8U, 0x4c69105eU, 0xd56041e4U, + 0xa2677172U, 0x3c03e4d1U, 0x4b04d447U, 0xd20d85fdU, 0xa50ab56bU, 0x35b5a8faU, 0x42b2986cU, + 0xdbbbc9d6U, 0xacbcf940U, 0x32d86ce3U, 0x45df5c75U, 0xdcd60dcfU, 0xabd13d59U, 0x26d930acU, + 0x51de003aU, 0xc8d75180U, 0xbfd06116U, 0x21b4f4b5U, 0x56b3c423U, 0xcfba9599U, 0xb8bda50fU, + 0x2802b89eU, 0x5f058808U, 0xc60cd9b2U, 0xb10be924U, 0x2f6f7c87U, 0x58684c11U, 0xc1611dabU, + 0xb6662d3dU, 0x76dc4190U, 0x01db7106U, 0x98d220bcU, 0xefd5102aU, 0x71b18589U, 0x06b6b51fU, + 0x9fbfe4a5U, 0xe8b8d433U, 0x7807c9a2U, 0x0f00f934U, 0x9609a88eU, 0xe10e9818U, 0x7f6a0dbbU, + 0x086d3d2dU, 0x91646c97U, 0xe6635c01U, 0x6b6b51f4U, 0x1c6c6162U, 0x856530d8U, 0xf262004eU, + 0x6c0695edU, 0x1b01a57bU, 0x8208f4c1U, 0xf50fc457U, 0x65b0d9c6U, 0x12b7e950U, 0x8bbeb8eaU, + 0xfcb9887cU, 0x62dd1ddfU, 0x15da2d49U, 0x8cd37cf3U, 0xfbd44c65U, 0x4db26158U, 0x3ab551ceU, + 0xa3bc0074U, 0xd4bb30e2U, 0x4adfa541U, 0x3dd895d7U, 0xa4d1c46dU, 0xd3d6f4fbU, 0x4369e96aU, + 0x346ed9fcU, 0xad678846U, 0xda60b8d0U, 0x44042d73U, 0x33031de5U, 0xaa0a4c5fU, 0xdd0d7cc9U, + 0x5005713cU, 0x270241aaU, 0xbe0b1010U, 0xc90c2086U, 0x5768b525U, 0x206f85b3U, 0xb966d409U, + 0xce61e49fU, 0x5edef90eU, 0x29d9c998U, 0xb0d09822U, 0xc7d7a8b4U, 0x59b33d17U, 0x2eb40d81U, + 0xb7bd5c3bU, 0xc0ba6cadU, 0xedb88320U, 0x9abfb3b6U, 0x03b6e20cU, 0x74b1d29aU, 0xead54739U, + 0x9dd277afU, 0x04db2615U, 0x73dc1683U, 0xe3630b12U, 0x94643b84U, 0x0d6d6a3eU, 0x7a6a5aa8U, + 0xe40ecf0bU, 0x9309ff9dU, 0x0a00ae27U, 0x7d079eb1U, 0xf00f9344U, 0x8708a3d2U, 0x1e01f268U, + 0x6906c2feU, 0xf762575dU, 0x806567cbU, 0x196c3671U, 0x6e6b06e7U, 0xfed41b76U, 0x89d32be0U, + 0x10da7a5aU, 0x67dd4accU, 0xf9b9df6fU, 0x8ebeeff9U, 0x17b7be43U, 0x60b08ed5U, 0xd6d6a3e8U, + 0xa1d1937eU, 0x38d8c2c4U, 0x4fdff252U, 0xd1bb67f1U, 0xa6bc5767U, 0x3fb506ddU, 0x48b2364bU, + 0xd80d2bdaU, 0xaf0a1b4cU, 0x36034af6U, 0x41047a60U, 0xdf60efc3U, 0xa867df55U, 0x316e8eefU, + 0x4669be79U, 0xcb61b38cU, 0xbc66831aU, 0x256fd2a0U, 0x5268e236U, 0xcc0c7795U, 0xbb0b4703U, + 0x220216b9U, 0x5505262fU, 0xc5ba3bbeU, 0xb2bd0b28U, 0x2bb45a92U, 0x5cb36a04U, 0xc2d7ffa7U, + 0xb5d0cf31U, 0x2cd99e8bU, 0x5bdeae1dU, 0x9b64c2b0U, 0xec63f226U, 0x756aa39cU, 0x026d930aU, + 0x9c0906a9U, 0xeb0e363fU, 0x72076785U, 0x05005713U, 0x95bf4a82U, 0xe2b87a14U, 0x7bb12baeU, + 0x0cb61b38U, 0x92d28e9bU, 0xe5d5be0dU, 0x7cdcefb7U, 0x0bdbdf21U, 0x86d3d2d4U, 0xf1d4e242U, + 0x68ddb3f8U, 0x1fda836eU, 0x81be16cdU, 0xf6b9265bU, 0x6fb077e1U, 0x18b74777U, 0x88085ae6U, + 0xff0f6a70U, 0x66063bcaU, 0x11010b5cU, 0x8f659effU, 0xf862ae69U, 0x616bffd3U, 0x166ccf45U, + 0xa00ae278U, 0xd70dd2eeU, 0x4e048354U, 0x3903b3c2U, 0xa7672661U, 0xd06016f7U, 0x4969474dU, + 0x3e6e77dbU, 0xaed16a4aU, 0xd9d65adcU, 0x40df0b66U, 0x37d83bf0U, 0xa9bcae53U, 0xdebb9ec5U, + 0x47b2cf7fU, 0x30b5ffe9U, 0xbdbdf21cU, 0xcabac28aU, 0x53b39330U, 0x24b4a3a6U, 0xbad03605U, + 0xcdd70693U, 0x54de5729U, 0x23d967bfU, 0xb3667a2eU, 0xc4614ab8U, 0x5d681b02U, 0x2a6f2b94U, + 0xb40bbe37U, 0xc30c8ea1U, 0x5a05df1bU, 0x2d02ef8dU}; + + while (len > 0){ crc = table[*data ^ ((crc >> 24) & 0xff)] ^ (crc << 8); data++; len--; } return crc; } - - inline unsigned int crc32(unsigned int crc, const char * data, size_t len) { - static const unsigned int table[256] = { - 0x00000000U, 0xB71DC104U, 0x6E3B8209U, 0xD926430DU, - 0xDC760413U, 0x6B6BC517U, 0xB24D861AU, 0x0550471EU, - 0xB8ED0826U, 0x0FF0C922U, 0xD6D68A2FU, 0x61CB4B2BU, - 0x649B0C35U, 0xD386CD31U, 0x0AA08E3CU, 0xBDBD4F38U, - 0x70DB114CU, 0xC7C6D048U, 0x1EE09345U, 0xA9FD5241U, - 0xACAD155FU, 0x1BB0D45BU, 0xC2969756U, 0x758B5652U, - 0xC836196AU, 0x7F2BD86EU, 0xA60D9B63U, 0x11105A67U, - 0x14401D79U, 0xA35DDC7DU, 0x7A7B9F70U, 0xCD665E74U, - 0xE0B62398U, 0x57ABE29CU, 0x8E8DA191U, 0x39906095U, - 0x3CC0278BU, 0x8BDDE68FU, 0x52FBA582U, 0xE5E66486U, - 0x585B2BBEU, 0xEF46EABAU, 0x3660A9B7U, 0x817D68B3U, - 0x842D2FADU, 0x3330EEA9U, 0xEA16ADA4U, 0x5D0B6CA0U, - 0x906D32D4U, 0x2770F3D0U, 0xFE56B0DDU, 0x494B71D9U, - 0x4C1B36C7U, 0xFB06F7C3U, 0x2220B4CEU, 0x953D75CAU, - 0x28803AF2U, 0x9F9DFBF6U, 0x46BBB8FBU, 0xF1A679FFU, - 0xF4F63EE1U, 0x43EBFFE5U, 0x9ACDBCE8U, 0x2DD07DECU, - 0x77708634U, 0xC06D4730U, 0x194B043DU, 0xAE56C539U, - 0xAB068227U, 0x1C1B4323U, 0xC53D002EU, 0x7220C12AU, - 0xCF9D8E12U, 0x78804F16U, 0xA1A60C1BU, 0x16BBCD1FU, - 0x13EB8A01U, 0xA4F64B05U, 0x7DD00808U, 0xCACDC90CU, - 0x07AB9778U, 0xB0B6567CU, 0x69901571U, 0xDE8DD475U, - 0xDBDD936BU, 0x6CC0526FU, 0xB5E61162U, 0x02FBD066U, - 0xBF469F5EU, 0x085B5E5AU, 0xD17D1D57U, 0x6660DC53U, - 0x63309B4DU, 0xD42D5A49U, 0x0D0B1944U, 0xBA16D840U, - 0x97C6A5ACU, 0x20DB64A8U, 0xF9FD27A5U, 0x4EE0E6A1U, - 0x4BB0A1BFU, 0xFCAD60BBU, 0x258B23B6U, 0x9296E2B2U, - 0x2F2BAD8AU, 0x98366C8EU, 0x41102F83U, 0xF60DEE87U, - 0xF35DA999U, 0x4440689DU, 0x9D662B90U, 0x2A7BEA94U, - 0xE71DB4E0U, 0x500075E4U, 0x892636E9U, 0x3E3BF7EDU, - 0x3B6BB0F3U, 0x8C7671F7U, 0x555032FAU, 0xE24DF3FEU, - 0x5FF0BCC6U, 0xE8ED7DC2U, 0x31CB3ECFU, 0x86D6FFCBU, - 0x8386B8D5U, 0x349B79D1U, 0xEDBD3ADCU, 0x5AA0FBD8U, - 0xEEE00C69U, 0x59FDCD6DU, 0x80DB8E60U, 0x37C64F64U, - 0x3296087AU, 0x858BC97EU, 0x5CAD8A73U, 0xEBB04B77U, - 0x560D044FU, 0xE110C54BU, 0x38368646U, 0x8F2B4742U, - 0x8A7B005CU, 0x3D66C158U, 0xE4408255U, 0x535D4351U, - 0x9E3B1D25U, 0x2926DC21U, 0xF0009F2CU, 0x471D5E28U, - 0x424D1936U, 0xF550D832U, 0x2C769B3FU, 0x9B6B5A3BU, - 0x26D61503U, 0x91CBD407U, 0x48ED970AU, 0xFFF0560EU, - 0xFAA01110U, 0x4DBDD014U, 0x949B9319U, 0x2386521DU, - 0x0E562FF1U, 0xB94BEEF5U, 0x606DADF8U, 0xD7706CFCU, - 0xD2202BE2U, 0x653DEAE6U, 0xBC1BA9EBU, 0x0B0668EFU, - 0xB6BB27D7U, 0x01A6E6D3U, 0xD880A5DEU, 0x6F9D64DAU, - 0x6ACD23C4U, 0xDDD0E2C0U, 0x04F6A1CDU, 0xB3EB60C9U, - 0x7E8D3EBDU, 0xC990FFB9U, 0x10B6BCB4U, 0xA7AB7DB0U, - 0xA2FB3AAEU, 0x15E6FBAAU, 0xCCC0B8A7U, 0x7BDD79A3U, - 0xC660369BU, 0x717DF79FU, 0xA85BB492U, 0x1F467596U, - 0x1A163288U, 0xAD0BF38CU, 0x742DB081U, 0xC3307185U, - 0x99908A5DU, 0x2E8D4B59U, 0xF7AB0854U, 0x40B6C950U, - 0x45E68E4EU, 0xF2FB4F4AU, 0x2BDD0C47U, 0x9CC0CD43U, - 0x217D827BU, 0x9660437FU, 0x4F460072U, 0xF85BC176U, - 0xFD0B8668U, 0x4A16476CU, 0x93300461U, 0x242DC565U, - 0xE94B9B11U, 0x5E565A15U, 0x87701918U, 0x306DD81CU, - 0x353D9F02U, 0x82205E06U, 0x5B061D0BU, 0xEC1BDC0FU, - 0x51A69337U, 0xE6BB5233U, 0x3F9D113EU, 0x8880D03AU, - 0x8DD09724U, 0x3ACD5620U, 0xE3EB152DU, 0x54F6D429U, - 0x7926A9C5U, 0xCE3B68C1U, 0x171D2BCCU, 0xA000EAC8U, - 0xA550ADD6U, 0x124D6CD2U, 0xCB6B2FDFU, 0x7C76EEDBU, - 0xC1CBA1E3U, 0x76D660E7U, 0xAFF023EAU, 0x18EDE2EEU, - 0x1DBDA5F0U, 0xAAA064F4U, 0x738627F9U, 0xC49BE6FDU, - 0x09FDB889U, 0xBEE0798DU, 0x67C63A80U, 0xD0DBFB84U, - 0xD58BBC9AU, 0x62967D9EU, 0xBBB03E93U, 0x0CADFF97U, - 0xB110B0AFU, 0x060D71ABU, 0xDF2B32A6U, 0x6836F3A2U, - 0x6D66B4BCU, 0xDA7B75B8U, 0x035D36B5U, 0xB440F7B1U - }; - const char * tmpData = data; - const char * end = tmpData + len; - while(tmpData < end){ - crc = table[((unsigned char) crc) ^ *tmpData++] ^ (crc >> 8); - } + inline unsigned int crc32(unsigned int crc, const char *data, size_t len){ + static const unsigned int table[256] ={ + 0x00000000U, 0xB71DC104U, 0x6E3B8209U, 0xD926430DU, 0xDC760413U, 0x6B6BC517U, 0xB24D861AU, + 0x0550471EU, 0xB8ED0826U, 0x0FF0C922U, 0xD6D68A2FU, 0x61CB4B2BU, 0x649B0C35U, 0xD386CD31U, + 0x0AA08E3CU, 0xBDBD4F38U, 0x70DB114CU, 0xC7C6D048U, 0x1EE09345U, 0xA9FD5241U, 0xACAD155FU, + 0x1BB0D45BU, 0xC2969756U, 0x758B5652U, 0xC836196AU, 0x7F2BD86EU, 0xA60D9B63U, 0x11105A67U, + 0x14401D79U, 0xA35DDC7DU, 0x7A7B9F70U, 0xCD665E74U, 0xE0B62398U, 0x57ABE29CU, 0x8E8DA191U, + 0x39906095U, 0x3CC0278BU, 0x8BDDE68FU, 0x52FBA582U, 0xE5E66486U, 0x585B2BBEU, 0xEF46EABAU, + 0x3660A9B7U, 0x817D68B3U, 0x842D2FADU, 0x3330EEA9U, 0xEA16ADA4U, 0x5D0B6CA0U, 0x906D32D4U, + 0x2770F3D0U, 0xFE56B0DDU, 0x494B71D9U, 0x4C1B36C7U, 0xFB06F7C3U, 0x2220B4CEU, 0x953D75CAU, + 0x28803AF2U, 0x9F9DFBF6U, 0x46BBB8FBU, 0xF1A679FFU, 0xF4F63EE1U, 0x43EBFFE5U, 0x9ACDBCE8U, + 0x2DD07DECU, 0x77708634U, 0xC06D4730U, 0x194B043DU, 0xAE56C539U, 0xAB068227U, 0x1C1B4323U, + 0xC53D002EU, 0x7220C12AU, 0xCF9D8E12U, 0x78804F16U, 0xA1A60C1BU, 0x16BBCD1FU, 0x13EB8A01U, + 0xA4F64B05U, 0x7DD00808U, 0xCACDC90CU, 0x07AB9778U, 0xB0B6567CU, 0x69901571U, 0xDE8DD475U, + 0xDBDD936BU, 0x6CC0526FU, 0xB5E61162U, 0x02FBD066U, 0xBF469F5EU, 0x085B5E5AU, 0xD17D1D57U, + 0x6660DC53U, 0x63309B4DU, 0xD42D5A49U, 0x0D0B1944U, 0xBA16D840U, 0x97C6A5ACU, 0x20DB64A8U, + 0xF9FD27A5U, 0x4EE0E6A1U, 0x4BB0A1BFU, 0xFCAD60BBU, 0x258B23B6U, 0x9296E2B2U, 0x2F2BAD8AU, + 0x98366C8EU, 0x41102F83U, 0xF60DEE87U, 0xF35DA999U, 0x4440689DU, 0x9D662B90U, 0x2A7BEA94U, + 0xE71DB4E0U, 0x500075E4U, 0x892636E9U, 0x3E3BF7EDU, 0x3B6BB0F3U, 0x8C7671F7U, 0x555032FAU, + 0xE24DF3FEU, 0x5FF0BCC6U, 0xE8ED7DC2U, 0x31CB3ECFU, 0x86D6FFCBU, 0x8386B8D5U, 0x349B79D1U, + 0xEDBD3ADCU, 0x5AA0FBD8U, 0xEEE00C69U, 0x59FDCD6DU, 0x80DB8E60U, 0x37C64F64U, 0x3296087AU, + 0x858BC97EU, 0x5CAD8A73U, 0xEBB04B77U, 0x560D044FU, 0xE110C54BU, 0x38368646U, 0x8F2B4742U, + 0x8A7B005CU, 0x3D66C158U, 0xE4408255U, 0x535D4351U, 0x9E3B1D25U, 0x2926DC21U, 0xF0009F2CU, + 0x471D5E28U, 0x424D1936U, 0xF550D832U, 0x2C769B3FU, 0x9B6B5A3BU, 0x26D61503U, 0x91CBD407U, + 0x48ED970AU, 0xFFF0560EU, 0xFAA01110U, 0x4DBDD014U, 0x949B9319U, 0x2386521DU, 0x0E562FF1U, + 0xB94BEEF5U, 0x606DADF8U, 0xD7706CFCU, 0xD2202BE2U, 0x653DEAE6U, 0xBC1BA9EBU, 0x0B0668EFU, + 0xB6BB27D7U, 0x01A6E6D3U, 0xD880A5DEU, 0x6F9D64DAU, 0x6ACD23C4U, 0xDDD0E2C0U, 0x04F6A1CDU, + 0xB3EB60C9U, 0x7E8D3EBDU, 0xC990FFB9U, 0x10B6BCB4U, 0xA7AB7DB0U, 0xA2FB3AAEU, 0x15E6FBAAU, + 0xCCC0B8A7U, 0x7BDD79A3U, 0xC660369BU, 0x717DF79FU, 0xA85BB492U, 0x1F467596U, 0x1A163288U, + 0xAD0BF38CU, 0x742DB081U, 0xC3307185U, 0x99908A5DU, 0x2E8D4B59U, 0xF7AB0854U, 0x40B6C950U, + 0x45E68E4EU, 0xF2FB4F4AU, 0x2BDD0C47U, 0x9CC0CD43U, 0x217D827BU, 0x9660437FU, 0x4F460072U, + 0xF85BC176U, 0xFD0B8668U, 0x4A16476CU, 0x93300461U, 0x242DC565U, 0xE94B9B11U, 0x5E565A15U, + 0x87701918U, 0x306DD81CU, 0x353D9F02U, 0x82205E06U, 0x5B061D0BU, 0xEC1BDC0FU, 0x51A69337U, + 0xE6BB5233U, 0x3F9D113EU, 0x8880D03AU, 0x8DD09724U, 0x3ACD5620U, 0xE3EB152DU, 0x54F6D429U, + 0x7926A9C5U, 0xCE3B68C1U, 0x171D2BCCU, 0xA000EAC8U, 0xA550ADD6U, 0x124D6CD2U, 0xCB6B2FDFU, + 0x7C76EEDBU, 0xC1CBA1E3U, 0x76D660E7U, 0xAFF023EAU, 0x18EDE2EEU, 0x1DBDA5F0U, 0xAAA064F4U, + 0x738627F9U, 0xC49BE6FDU, 0x09FDB889U, 0xBEE0798DU, 0x67C63A80U, 0xD0DBFB84U, 0xD58BBC9AU, + 0x62967D9EU, 0xBBB03E93U, 0x0CADFF97U, 0xB110B0AFU, 0x060D71ABU, 0xDF2B32A6U, 0x6836F3A2U, + 0x6D66B4BCU, 0xDA7B75B8U, 0x035D36B5U, 0xB440F7B1U}; + + const char *tmpData = data; + const char *end = tmpData + len; + while (tmpData < end){crc = table[((unsigned char)crc) ^ *tmpData++] ^ (crc >> 8);} return crc; } -} +}// namespace checksum diff --git a/lib/config.cpp b/lib/config.cpp index 653469cc..abc939ae 100644 --- a/lib/config.cpp +++ b/lib/config.cpp @@ -132,8 +132,7 @@ void Util::Config::printHelp(std::ostream &output){ } while (f.size() < longest){f.append(" ");} if (it->isMember("arg")){ - output << f << "(" << (*it)["arg"].asString() << ") " << (*it)["help"].asString() - << std::endl; + output << f << "(" << (*it)["arg"].asString() << ") " << (*it)["help"].asString() << std::endl; }else{ output << f << (*it)["help"].asString() << std::endl; } @@ -141,8 +140,7 @@ void Util::Config::printHelp(std::ostream &output){ if (it->isMember("arg_num")){ f = it.key(); while (f.size() < longest){f.append(" ");} - output << f << "(" << (*it)["arg"].asString() << ") " << (*it)["help"].asString() - << std::endl; + output << f << "(" << (*it)["arg"].asString() << ") " << (*it)["help"].asString() << std::endl; } } } @@ -188,9 +186,9 @@ bool Util::Config::parseArgs(int &argc, char **&argv){ << std::endl; #endif #ifdef WITH_THREADNAMES - std::cout - << "- Flag: With threadnames. Debuggers will show sensible human-readable thread names." - << std::endl; + std::cout << "- Flag: With threadnames. Debuggers will show sensible human-readable thread " + "names." + << std::endl; #endif /*LTS-START*/ #ifndef UPDATER @@ -210,9 +208,8 @@ bool Util::Config::parseArgs(int &argc, char **&argv){ #endif #ifdef STATS_DELAY if (STATS_DELAY != 15){ - std::cout << "- Setting: Stats delay " << STATS_DELAY - << ". Statistics of viewer counts are delayed by " << STATS_DELAY - << " seconds as opposed to the default of 15 seconds. "; + std::cout << "- Setting: Stats delay " << STATS_DELAY << ". Statistics of viewer counts are delayed by " + << STATS_DELAY << " seconds as opposed to the default of 15 seconds. "; if (STATS_DELAY > 15){ std::cout << "This makes them more accurate." << std::endl; }else{ @@ -263,8 +260,7 @@ bool Util::Config::hasOption(const std::string &optname){ /// If the option does not exist, this exits the application with a return code of 37. JSON::Value &Util::Config::getOption(std::string optname, bool asArray){ if (!vals.isMember(optname)){ - std::cout << "Fatal error: a non-existent option '" << optname << "' was accessed." - << std::endl; + std::cout << "Fatal error: a non-existent option '" << optname << "' was accessed." << std::endl; exit(37); } if (!vals[optname].isMember("value") || !vals[optname]["value"].isArray()){ @@ -313,8 +309,7 @@ static void callThreadCallback(void *cDataArg){ INSANE_MSG("Thread for %p ended", cDataArg); } -int Util::Config::threadServer(Socket::Server &server_socket, - int (*callback)(Socket::Connection &)){ +int Util::Config::threadServer(Socket::Server &server_socket, int (*callback)(Socket::Connection &)){ Util::Procs::socketList.insert(server_socket.getSocket()); while (is_active && server_socket.connected()){ Socket::Connection S = server_socket.accept(); @@ -354,9 +349,7 @@ int Util::Config::forkServer(Socket::Server &server_socket, int (*callback)(Sock } } Util::Procs::socketList.erase(server_socket.getSocket()); - if (!is_restarting){ - server_socket.close(); - } + if (!is_restarting){server_socket.close();} return 0; } @@ -366,7 +359,7 @@ int Util::Config::serveThreadedSocket(int (*callback)(Socket::Connection &)){ server_socket = Socket::Server(0); }else if (vals.isMember("socket")){ server_socket = Socket::Server(Util::getTmpFolder() + getString("socket")); - } else if (vals.isMember("port") && vals.isMember("interface")){ + }else if (vals.isMember("port") && vals.isMember("interface")){ server_socket = Socket::Server(getInteger("port"), getString("interface"), false); } if (!server_socket.connected()){ @@ -394,7 +387,7 @@ int Util::Config::serveForkedSocket(int (*callback)(Socket::Connection &S)){ server_socket = Socket::Server(0); }else if (vals.isMember("socket")){ server_socket = Socket::Server(Util::getTmpFolder() + getString("socket")); - } else if (vals.isMember("port") && vals.isMember("interface")){ + }else if (vals.isMember("port") && vals.isMember("interface")){ server_socket = Socket::Server(getInteger("port"), getString("interface"), false); } if (!server_socket.connected()){ @@ -463,8 +456,7 @@ void Util::Config::signal_handler(int signum, siginfo_t *sigInfo, void *ignore){ case SI_TIMER: case SI_ASYNCIO: case SI_MESGQ: - INFO_MSG("Received signal %s (%d) from process %d", strsignal(signum), signum, - sigInfo->si_pid); + INFO_MSG("Received signal %s (%d) from process %d", strsignal(signum), signum, sigInfo->si_pid); break; default: INFO_MSG("Received signal %s (%d)", strsignal(signum), signum); break; } @@ -653,4 +645,3 @@ void Util::setUser(std::string username){ } } } - diff --git a/lib/config.h b/lib/config.h index 18a50096..8ceeecd3 100644 --- a/lib/config.h +++ b/lib/config.h @@ -23,7 +23,7 @@ namespace Util{ public: // variables - static bool is_active; ///< Set to true by activate(), set to false by the signal handler. + static bool is_active; ///< Set to true by activate(), set to false by the signal handler. static bool is_restarting; ///< Set to true when restarting, set to false on boot. static uint32_t printDebugLevel; static std::string streamName; ///< Used by debug messages to identify the stream name @@ -64,4 +64,3 @@ namespace Util{ void setUser(std::string user); }// namespace Util - diff --git a/lib/defines.h b/lib/defines.h index 3668b1fc..d4ab3186 100644 --- a/lib/defines.h +++ b/lib/defines.h @@ -2,31 +2,33 @@ // Defines to print debug messages. #ifndef MIST_DEBUG #define MIST_DEBUG 1 -#define DLVL_NONE 0 // All debugging disabled. -#define DLVL_FAIL 1 // Only messages about failed operations. -#define DLVL_ERROR 2 // Only messages about errors and failed operations. -#define DLVL_WARN 3 // Warnings, errors, and fail messages. -#define DLVL_DEVEL 4 // All of the above, plus status messages handy during development. -#define DLVL_INFO 4 // All of the above, plus status messages handy during development. -#define DLVL_MEDIUM 5 // Slightly more than just development-level messages. -#define DLVL_HIGH 6 // Verbose debugging messages. -#define DLVL_VERYHIGH 7 // Very verbose debugging messages. -#define DLVL_EXTREME 8 // Everything is reported in extreme detail. -#define DLVL_INSANE 9 // Everything is reported in insane detail. +#define DLVL_NONE 0 // All debugging disabled. +#define DLVL_FAIL 1 // Only messages about failed operations. +#define DLVL_ERROR 2 // Only messages about errors and failed operations. +#define DLVL_WARN 3 // Warnings, errors, and fail messages. +#define DLVL_DEVEL 4 // All of the above, plus status messages handy during development. +#define DLVL_INFO 4 // All of the above, plus status messages handy during development. +#define DLVL_MEDIUM 5 // Slightly more than just development-level messages. +#define DLVL_HIGH 6 // Verbose debugging messages. +#define DLVL_VERYHIGH 7 // Very verbose debugging messages. +#define DLVL_EXTREME 8 // Everything is reported in extreme detail. +#define DLVL_INSANE 9 // Everything is reported in insane detail. #define DLVL_DONTEVEN 10 // All messages enabled, even pointless ones. #define PRETTY_PRINT_TIME "%ud%uh%um%us" -#define PRETTY_ARG_TIME(t) (int)(t)/86400, ((int)(t)%86400)/3600, ((int)(t)%3600)/60, (int)(t)%60 +#define PRETTY_ARG_TIME(t) \ + (int)(t) / 86400, ((int)(t) % 86400) / 3600, ((int)(t) % 3600) / 60, (int)(t) % 60 #define PRETTY_PRINT_MSTIME "%ud%.2uh%.2um%.2us.%.3u" -#define PRETTY_ARG_MSTIME(t) PRETTY_ARG_TIME(t/1000), (int)(t%1000) +#define PRETTY_ARG_MSTIME(t) PRETTY_ARG_TIME(t / 1000), (int)(t % 1000) #if DEBUG > -1 #define __STDC_FORMAT_MACROS 1 -#include -#include +#include "config.h" #include #include -#include "config.h" -static const char * DBG_LVL_LIST[] = {"NONE", "FAIL", "ERROR", "WARN", "INFO", "MEDIUM", "HIGH", "VERYHIGH", "EXTREME", "INSANE", "DONTEVEN"}; +#include +#include +static const char *DBG_LVL_LIST[] ={"NONE", "FAIL", "ERROR", "WARN", "INFO", "MEDIUM", + "HIGH", "VERYHIGH", "EXTREME", "INSANE", "DONTEVEN"}; #if !defined(PRIu64) #define PRIu64 "llu" @@ -40,15 +42,31 @@ static const char * DBG_LVL_LIST[] = {"NONE", "FAIL", "ERROR", "WARN", "INFO", " #include #if DEBUG >= DLVL_DEVEL -#define DEBUG_MSG(lvl, msg, ...) if (Util::Config::printDebugLevel >= lvl){fprintf(stderr, "%s|%s|%d|%s:%d|%s|" msg "\n", DBG_LVL_LIST[lvl], program_invocation_short_name, getpid(), __FILE__, __LINE__, Util::Config::streamName.c_str(), ##__VA_ARGS__);} +#define DEBUG_MSG(lvl, msg, ...) \ + if (Util::Config::printDebugLevel >= lvl){\ + fprintf(stderr, "%s|%s|%d|%s:%d|%s|" msg "\n", DBG_LVL_LIST[lvl], program_invocation_short_name, \ + getpid(), __FILE__, __LINE__, Util::Config::streamName.c_str(), ##__VA_ARGS__); \ + } #else -#define DEBUG_MSG(lvl, msg, ...) if (Util::Config::printDebugLevel >= lvl){fprintf(stderr, "%s|%s|%d||%s|" msg "\n", DBG_LVL_LIST[lvl], program_invocation_short_name, getpid(), Util::Config::streamName.c_str(), ##__VA_ARGS__);} +#define DEBUG_MSG(lvl, msg, ...) \ + if (Util::Config::printDebugLevel >= lvl){\ + fprintf(stderr, "%s|%s|%d||%s|" msg "\n", DBG_LVL_LIST[lvl], program_invocation_short_name, \ + getpid(), Util::Config::streamName.c_str(), ##__VA_ARGS__); \ + } #endif #else #if DEBUG >= DLVL_DEVEL -#define DEBUG_MSG(lvl, msg, ...) if (Util::Config::printDebugLevel >= lvl){fprintf(stderr, "%s|MistProcess|%d|%s:%d|%s|" msg "\n", DBG_LVL_LIST[lvl], getpid(), __FILE__, __LINE__, Util::Config::streamName.c_str(), ##__VA_ARGS__);} +#define DEBUG_MSG(lvl, msg, ...) \ + if (Util::Config::printDebugLevel >= lvl){\ + fprintf(stderr, "%s|MistProcess|%d|%s:%d|%s|" msg "\n", DBG_LVL_LIST[lvl], getpid(), __FILE__, \ + __LINE__, Util::Config::streamName.c_str(), ##__VA_ARGS__); \ + } #else -#define DEBUG_MSG(lvl, msg, ...) if (Util::Config::printDebugLevel >= lvl){fprintf(stderr, "%s|MistProcess|%d||%s|" msg "\n", DBG_LVL_LIST[lvl], getpid(), Util::Config::streamName.c_str(), ##__VA_ARGS__);} +#define DEBUG_MSG(lvl, msg, ...) \ + if (Util::Config::printDebugLevel >= lvl){\ + fprintf(stderr, "%s|MistProcess|%d||%s|" msg "\n", DBG_LVL_LIST[lvl], getpid(), \ + Util::Config::streamName.c_str(), ##__VA_ARGS__); \ + } #endif #endif @@ -56,18 +74,16 @@ static const char * DBG_LVL_LIST[] = {"NONE", "FAIL", "ERROR", "WARN", "INFO", " static inline void show_stackframe(){} #else #include -static inline void show_stackframe() { +static inline void show_stackframe(){ void *trace[16]; char **messages = 0; int i, trace_size = 0; trace_size = backtrace(trace, 16); messages = backtrace_symbols(trace, trace_size); - for (i=1; i 2){ - INFO_MSG("Lost connection while retrieving %s (%zu/%" PRIu32 ")", link.getUrl().c_str(), retryCount - loop + 1, retryCount); + INFO_MSG("Lost connection while retrieving %s (%zu/%" PRIu32 ")", link.getUrl().c_str(), + retryCount - loop + 1, retryCount); }else{ - MEDIUM_MSG("Lost connection while retrieving %s (%zu/%" PRIu32 ")", link.getUrl().c_str(), retryCount - loop + 1, retryCount); + MEDIUM_MSG("Lost connection while retrieving %s (%zu/%" PRIu32 ")", link.getUrl().c_str(), + retryCount - loop + 1, retryCount); } H.Clean(); } @@ -230,7 +230,8 @@ namespace HTTP{ return false; } - bool Downloader::getRangeNonBlocking(const HTTP::URL &link, size_t byteStart, size_t byteEnd, Util::DataCallback &cb){ + bool Downloader::getRangeNonBlocking(const HTTP::URL &link, size_t byteStart, size_t byteEnd, + Util::DataCallback &cb){ char tmp[32]; if (byteEnd <= 0){// get range from byteStart til eof sprintf(tmp, "bytes=%zu-", byteStart); @@ -256,11 +257,11 @@ namespace HTTP{ /// Makes at most 5 attempts, and will wait no longer than 5 seconds without receiving data. bool Downloader::get(const HTTP::URL &link, uint8_t maxRecursiveDepth, Util::DataCallback &cb){ if (!getNonBlocking(link, maxRecursiveDepth)){return false;} - + while (!continueNonBlocking(cb)){Util::sleep(100);} - + if (isComplete){return true;} - + FAIL_MSG("Could not retrieve %s", link.getUrl().c_str()); return false; } @@ -277,9 +278,7 @@ namespace HTTP{ return true; } - const HTTP::URL & Downloader::lastURL(){ - return nbLink; - } + const HTTP::URL &Downloader::lastURL(){return nbLink;} // continue handling a request, originally set up by the getNonBlocking() function // returns true if the request is complete @@ -368,14 +367,15 @@ namespace HTTP{ } } WARN_MSG("Invalid connection state for HTTP request"); - return false; //we should never get here + return false; // we should never get here } bool Downloader::post(const HTTP::URL &link, const std::string &payload, bool sync, uint8_t maxRecursiveDepth){ return post(link, payload.data(), payload.size(), sync, maxRecursiveDepth); } - bool Downloader::post(const HTTP::URL &link, const void * payload, const size_t payloadLen, bool sync, uint8_t maxRecursiveDepth){ + bool Downloader::post(const HTTP::URL &link, const void *payload, const size_t payloadLen, + bool sync, uint8_t maxRecursiveDepth){ if (!canRequest(link)){return false;} size_t loop = retryCount; // max 5 attempts while (--loop){// loop while we are unsuccessful @@ -499,4 +499,3 @@ namespace HTTP{ } }// namespace HTTP - diff --git a/lib/downloader.h b/lib/downloader.h index 34c6ad8e..3956efad 100644 --- a/lib/downloader.h +++ b/lib/downloader.h @@ -1,6 +1,6 @@ #include "http_parser.h" -#include "url.h" #include "socket.h" +#include "url.h" #include "util.h" namespace HTTP{ @@ -11,7 +11,8 @@ namespace HTTP{ std::string &data(); const std::string &const_data() const; void prepareRequest(const HTTP::URL &link, const std::string &method = ""); - void doRequest(const HTTP::URL &link, const std::string &method = "", const void * body = 0, const size_t bodyLen = 0); + void doRequest(const HTTP::URL &link, const std::string &method = "", const void *body = 0, + const size_t bodyLen = 0); void doRequest(const HTTP::URL &link, const std::string &method, const std::string &body); bool get(const std::string &link, Util::DataCallback &cb = Util::defaultDataCallback); bool get(const HTTP::URL &link, uint8_t maxRecursiveDepth = 6, Util::DataCallback &cb = Util::defaultDataCallback); @@ -20,7 +21,8 @@ namespace HTTP{ Util::DataCallback &cb = Util::defaultDataCallback); bool getRangeNonBlocking(const HTTP::URL &link, size_t byteStart, size_t byteEnd, Util::DataCallback &cb = Util::defaultDataCallback); - bool post(const HTTP::URL &link, const void * payload, const size_t payloadLen, bool sync = true, uint8_t maxRecursiveDepth = 6); + bool post(const HTTP::URL &link, const void *payload, const size_t payloadLen, bool sync = true, + uint8_t maxRecursiveDepth = 6); bool post(const HTTP::URL &link, const std::string &payload, bool sync = true, uint8_t maxRecursiveDepth = 6); @@ -45,7 +47,7 @@ namespace HTTP{ const Socket::Connection &getSocket() const; uint32_t retryCount, dataTimeout; bool isProxied() const; - const HTTP::URL & lastURL(); + const HTTP::URL &lastURL(); private: bool isComplete; @@ -54,7 +56,7 @@ namespace HTTP{ uint32_t connectedPort; ///< Currently connected port number Parser H; ///< HTTP parser for downloader Socket::Connection S; ///< TCP socket for downloader - bool ssl; ///< True if ssl is currently in use. + bool ssl; ///< True if ssl is currently in use. std::string authStr; ///< Most recently seen WWW-Authenticate request std::string proxyAuthStr; ///< Most recently seen Proxy-Authenticate request bool proxied; ///< True if proxy server is configured. @@ -65,8 +67,4 @@ namespace HTTP{ uint64_t nbReqTime; }; - - - }// namespace HTTP - diff --git a/lib/dtls_srtp_handshake.cpp b/lib/dtls_srtp_handshake.cpp index fe35fffe..2f22960d 100644 --- a/lib/dtls_srtp_handshake.cpp +++ b/lib/dtls_srtp_handshake.cpp @@ -1,61 +1,54 @@ -#include #include "defines.h" #include "dtls_srtp_handshake.h" +#include /* Write mbedtls into a log file. */ #define LOG_TO_FILE 0 #if LOG_TO_FILE -# include +#include #endif /* ----------------------------------------- */ - + static void print_mbedtls_error(int r); static void print_mbedtls_debug_message(void *ctx, int level, const char *file, int line, const char *str); -static int on_mbedtls_wants_to_read(void* user, unsigned char* buf, size_t len); /* Called when mbedtls wants to read data from e.g. a socket. */ -static int on_mbedtls_wants_to_write(void* user, const unsigned char* buf, size_t len); /* Called when mbedtls wants to write data to e.g. a socket. */ +static int on_mbedtls_wants_to_read(void *user, unsigned char *buf, + size_t len); /* Called when mbedtls wants to read data from e.g. a socket. */ +static int on_mbedtls_wants_to_write(void *user, const unsigned char *buf, + size_t len); /* Called when mbedtls wants to write data to e.g. a socket. */ static std::string mbedtls_err_to_string(int r); - + /* ----------------------------------------- */ -DTLSSRTPHandshake::DTLSSRTPHandshake() - :write_callback(NULL) - ,cert(NULL) - ,key(NULL) -{ - memset((void*)&entropy_ctx, 0x00, sizeof(entropy_ctx)); - memset((void*)&rand_ctx, 0x00, sizeof(rand_ctx)); - memset((void*)&ssl_ctx, 0x00, sizeof(ssl_ctx)); - memset((void*)&ssl_conf, 0x00, sizeof(ssl_conf)); - memset((void*)&cookie_ctx, 0x00, sizeof(cookie_ctx)); - memset((void*)&timer_ctx, 0x00, sizeof(timer_ctx)); +DTLSSRTPHandshake::DTLSSRTPHandshake() : write_callback(NULL), cert(NULL), key(NULL){ + memset((void *)&entropy_ctx, 0x00, sizeof(entropy_ctx)); + memset((void *)&rand_ctx, 0x00, sizeof(rand_ctx)); + memset((void *)&ssl_ctx, 0x00, sizeof(ssl_ctx)); + memset((void *)&ssl_conf, 0x00, sizeof(ssl_conf)); + memset((void *)&cookie_ctx, 0x00, sizeof(cookie_ctx)); + memset((void *)&timer_ctx, 0x00, sizeof(timer_ctx)); } -int DTLSSRTPHandshake::init(mbedtls_x509_crt* certificate, - mbedtls_pk_context* privateKey, - int(*writeCallback)(const uint8_t* data, int* nbytes) -) -{ +int DTLSSRTPHandshake::init(mbedtls_x509_crt *certificate, mbedtls_pk_context *privateKey, + int (*writeCallback)(const uint8_t *data, int *nbytes)){ int r = 0; - mbedtls_ssl_srtp_profile srtp_profiles[] = { - MBEDTLS_SRTP_AES128_CM_HMAC_SHA1_80, - MBEDTLS_SRTP_AES128_CM_HMAC_SHA1_32 - }; + mbedtls_ssl_srtp_profile srtp_profiles[] ={MBEDTLS_SRTP_AES128_CM_HMAC_SHA1_80, + MBEDTLS_SRTP_AES128_CM_HMAC_SHA1_32}; - if (!writeCallback) { + if (!writeCallback){ FAIL_MSG("No writeCallack function given."); r = -3; goto error; } - if (!certificate) { + if (!certificate){ FAIL_MSG("Given certificate is null."); r = -5; goto error; } - if (!privateKey) { + if (!privateKey){ FAIL_MSG("Given key is null."); r = -10; goto error; @@ -70,18 +63,20 @@ int DTLSSRTPHandshake::init(mbedtls_x509_crt* certificate, mbedtls_ssl_init(&ssl_ctx); mbedtls_ssl_config_init(&ssl_conf); mbedtls_ssl_cookie_init(&cookie_ctx); - + /* seed and setup the random number generator */ - r = mbedtls_ctr_drbg_seed(&rand_ctx, mbedtls_entropy_func, &entropy_ctx, (const unsigned char*)"mist-srtp", 9); - if (0 != r) { + r = mbedtls_ctr_drbg_seed(&rand_ctx, mbedtls_entropy_func, &entropy_ctx, + (const unsigned char *)"mist-srtp", 9); + if (0 != r){ print_mbedtls_error(r); r = -20; goto error; } /* load defaults into our ssl_conf */ - r = mbedtls_ssl_config_defaults(&ssl_conf, MBEDTLS_SSL_IS_SERVER, MBEDTLS_SSL_TRANSPORT_DATAGRAM, MBEDTLS_SSL_PRESET_DEFAULT); - if (0 != r) { + r = mbedtls_ssl_config_defaults(&ssl_conf, MBEDTLS_SSL_IS_SERVER, MBEDTLS_SSL_TRANSPORT_DATAGRAM, + MBEDTLS_SSL_PRESET_DEFAULT); + if (0 != r){ print_mbedtls_error(r); r = -30; goto error; @@ -95,8 +90,9 @@ int DTLSSRTPHandshake::init(mbedtls_x509_crt* certificate, mbedtls_debug_set_threshold(10); /* enable SRTP */ - r = mbedtls_ssl_conf_dtls_srtp_protection_profiles(&ssl_conf, srtp_profiles, sizeof(srtp_profiles) / sizeof(srtp_profiles[0])); - if (0 != r) { + r = mbedtls_ssl_conf_dtls_srtp_protection_profiles(&ssl_conf, srtp_profiles, + sizeof(srtp_profiles) / sizeof(srtp_profiles[0])); + if (0 != r){ print_mbedtls_error(r); r = -40; goto error; @@ -104,15 +100,15 @@ int DTLSSRTPHandshake::init(mbedtls_x509_crt* certificate, /* cert certificate chain + key, so we can verify the client-hello signed data */ r = mbedtls_ssl_conf_own_cert(&ssl_conf, cert, key); - if (0 != r) { + if (0 != r){ print_mbedtls_error(r); r = -50; goto error; } - + /* cookie setup (e.g. to prevent ddos). */ r = mbedtls_ssl_cookie_setup(&cookie_ctx, mbedtls_ctr_drbg_random, &rand_ctx); - if (0 != r) { + if (0 != r){ print_mbedtls_error(r); r = -60; goto error; @@ -123,20 +119,21 @@ int DTLSSRTPHandshake::init(mbedtls_x509_crt* certificate, /* setup the ssl context for use. note that ssl_conf will be referenced internall by the context and therefore should be kept around. */ r = mbedtls_ssl_setup(&ssl_ctx, &ssl_conf); - if (0 != r) { + if (0 != r){ print_mbedtls_error(r); r = -70; goto error; } /* set bio handlers */ - mbedtls_ssl_set_bio(&ssl_ctx, (void*)this, on_mbedtls_wants_to_write, on_mbedtls_wants_to_read, NULL); + mbedtls_ssl_set_bio(&ssl_ctx, (void *)this, on_mbedtls_wants_to_write, on_mbedtls_wants_to_read, NULL); /* set temp id, just adds some exta randomness */ { std::string remote_id = "mist"; - r = mbedtls_ssl_set_client_transport_id(&ssl_ctx, (const unsigned char*)remote_id.c_str(), remote_id.size()); - if (0 != r) { + r = mbedtls_ssl_set_client_transport_id(&ssl_ctx, (const unsigned char *)remote_id.c_str(), + remote_id.size()); + if (0 != r){ print_mbedtls_error(r); r = -80; goto error; @@ -145,19 +142,17 @@ int DTLSSRTPHandshake::init(mbedtls_x509_crt* certificate, /* set timer callbacks */ mbedtls_ssl_set_timer_cb(&ssl_ctx, &timer_ctx, mbedtls_timing_set_delay, mbedtls_timing_get_delay); - + write_callback = writeCallback; - - error: - - if (r < 0) { - shutdown(); - } - + +error: + + if (r < 0){shutdown();} + return r; } -int DTLSSRTPHandshake::shutdown() { +int DTLSSRTPHandshake::shutdown(){ /* cleanup the refs from the settings. */ cert = NULL; @@ -178,22 +173,22 @@ int DTLSSRTPHandshake::shutdown() { return 0; } - -/* ----------------------------------------- */ - -int DTLSSRTPHandshake::parse(const uint8_t* data, size_t nbytes) { - if (NULL == data) { +/* ----------------------------------------- */ + +int DTLSSRTPHandshake::parse(const uint8_t *data, size_t nbytes){ + + if (NULL == data){ ERROR_MSG("Given `data` is NULL."); return -1; } - if (0 == nbytes) { + if (0 == nbytes){ ERROR_MSG("Given nbytes is 0."); return -2; } - if (MBEDTLS_SSL_HANDSHAKE_OVER == ssl_ctx.state) { + if (MBEDTLS_SSL_HANDSHAKE_OVER == ssl_ctx.state){ ERROR_MSG("Already finished the handshake."); return -3; } @@ -202,104 +197,106 @@ int DTLSSRTPHandshake::parse(const uint8_t* data, size_t nbytes) { int r = 0; std::copy(data, data + nbytes, std::back_inserter(buffer)); - do { - + do{ + r = mbedtls_ssl_handshake(&ssl_ctx); - switch (r) { - /* 0 = handshake done. */ - case 0: { - if (0 != extractKeyingMaterial()) { - ERROR_MSG("Failed to extract keying material after handshake was done."); - return -2; - } - return 0; - } - /* see the dtls server example; this is used to prevent certain attacks (ddos) */ - case MBEDTLS_ERR_SSL_HELLO_VERIFY_REQUIRED: { - if (0 != resetSession()) { - ERROR_MSG("Failed to reset the session which is necessary when we need to verify the HELLO."); - return -3; - } - break; - } - case MBEDTLS_ERR_SSL_WANT_READ: { - DONTEVEN_MSG("mbedtls wants a bit more data before it can continue parsing the DTLS handshake."); - break; - } - default: { - ERROR_MSG("A serious mbedtls error occured."); - print_mbedtls_error(r); + switch (r){ + /* 0 = handshake done. */ + case 0:{ + if (0 != extractKeyingMaterial()){ + ERROR_MSG("Failed to extract keying material after handshake was done."); return -2; } + return 0; } - } - while (MBEDTLS_ERR_SSL_WANT_WRITE == r); + /* see the dtls server example; this is used to prevent certain attacks (ddos) */ + case MBEDTLS_ERR_SSL_HELLO_VERIFY_REQUIRED:{ + if (0 != resetSession()){ + ERROR_MSG( + "Failed to reset the session which is necessary when we need to verify the HELLO."); + return -3; + } + break; + } + case MBEDTLS_ERR_SSL_WANT_READ:{ + DONTEVEN_MSG( + "mbedtls wants a bit more data before it can continue parsing the DTLS handshake."); + break; + } + default:{ + ERROR_MSG("A serious mbedtls error occured."); + print_mbedtls_error(r); + return -2; + } + } + }while (MBEDTLS_ERR_SSL_WANT_WRITE == r); return 0; } - + /* ----------------------------------------- */ -int DTLSSRTPHandshake::resetSession() { - +int DTLSSRTPHandshake::resetSession(){ + std::string remote_id = "mist"; /* @todo for now we hardcoded this... */ int r = 0; - + r = mbedtls_ssl_session_reset(&ssl_ctx); - if (0 != r) { + if (0 != r){ print_mbedtls_error(r); return -1; } - - r = mbedtls_ssl_set_client_transport_id(&ssl_ctx, (const unsigned char*)remote_id.c_str(), remote_id.size()); - if (0 != r) { + + r = mbedtls_ssl_set_client_transport_id(&ssl_ctx, (const unsigned char *)remote_id.c_str(), + remote_id.size()); + if (0 != r){ print_mbedtls_error(r); return -2; } - + buffer.clear(); - + return 0; } - + /* master key is 128 bits => 16 bytes. master salt is 112 bits => 14 bytes */ -int DTLSSRTPHandshake::extractKeyingMaterial() { - +int DTLSSRTPHandshake::extractKeyingMaterial(){ + int r = 0; - uint8_t keying_material[MBEDTLS_DTLS_SRTP_MAX_KEY_MATERIAL_LENGTH] = {}; + uint8_t keying_material[MBEDTLS_DTLS_SRTP_MAX_KEY_MATERIAL_LENGTH] ={}; size_t keying_material_len = sizeof(keying_material); r = mbedtls_ssl_get_dtls_srtp_key_material(&ssl_ctx, keying_material, &keying_material_len); - if (0 != r) { + if (0 != r){ print_mbedtls_error(r); return -1; } /* @todo following code is for server mode only */ mbedtls_ssl_srtp_profile srtp_profile = mbedtls_ssl_get_dtls_srtp_protection_profile(&ssl_ctx); - switch (srtp_profile) { - case MBEDTLS_SRTP_AES128_CM_HMAC_SHA1_80: { - cipher = "SRTP_AES128_CM_SHA1_80"; - break; - } - case MBEDTLS_SRTP_AES128_CM_HMAC_SHA1_32: { - cipher = "SRTP_AES128_CM_SHA1_32"; - break; - } - default: { - ERROR_MSG("Unhandled SRTP profile, cannot extract keying material."); - return -6; - } + switch (srtp_profile){ + case MBEDTLS_SRTP_AES128_CM_HMAC_SHA1_80:{ + cipher = "SRTP_AES128_CM_SHA1_80"; + break; + } + case MBEDTLS_SRTP_AES128_CM_HMAC_SHA1_32:{ + cipher = "SRTP_AES128_CM_SHA1_32"; + break; + } + default:{ + ERROR_MSG("Unhandled SRTP profile, cannot extract keying material."); + return -6; + } } - remote_key.assign((char*)(&keying_material[0]) + 0, 16); - local_key.assign((char*)(&keying_material[0]) + 16, 16); - remote_salt.assign((char*)(&keying_material[0]) + 32, 14); - local_salt.assign((char*)(&keying_material[0]) + 46, 14); + remote_key.assign((char *)(&keying_material[0]) + 0, 16); + local_key.assign((char *)(&keying_material[0]) + 16, 16); + remote_salt.assign((char *)(&keying_material[0]) + 32, 14); + local_salt.assign((char *)(&keying_material[0]) + 46, 14); DONTEVEN_MSG("Extracted the DTLS SRTP keying material with cipher %s.", cipher.c_str()); DONTEVEN_MSG("Remote DTLS SRTP key size is %zu.", remote_key.size()); @@ -324,54 +321,50 @@ int DTLSSRTPHandshake::extractKeyingMaterial() { as if we were using a non-blocking socket, which means: - we return MBETLS_ERR_SSL_WANT_READ when there is no data left to read - - when there is data in our temporary buffer, we read from that + - when there is data in our temporary buffer, we read from that */ -static int on_mbedtls_wants_to_read(void* user, unsigned char* buf, size_t len) { +static int on_mbedtls_wants_to_read(void *user, unsigned char *buf, size_t len){ - DTLSSRTPHandshake* hs = static_cast(user); - if (NULL == hs) { + DTLSSRTPHandshake *hs = static_cast(user); + if (NULL == hs){ ERROR_MSG("Failed to cast the user pointer into a DTLSSRTPHandshake."); return -1; } /* figure out how much we can read. */ - if (hs->buffer.size() == 0) { - return MBEDTLS_ERR_SSL_WANT_READ; - } + if (hs->buffer.size() == 0){return MBEDTLS_ERR_SSL_WANT_READ;} size_t nbytes = hs->buffer.size(); - if (nbytes > len) { - nbytes = len; - } + if (nbytes > len){nbytes = len;} /* "read" into the given buffer. */ memcpy(buf, &hs->buffer[0], nbytes); hs->buffer.erase(hs->buffer.begin(), hs->buffer.begin() + nbytes); - + return (int)nbytes; } - -static int on_mbedtls_wants_to_write(void* user, const unsigned char* buf, size_t len) { - DTLSSRTPHandshake* hs = static_cast(user); - if (!hs) { +static int on_mbedtls_wants_to_write(void *user, const unsigned char *buf, size_t len){ + + DTLSSRTPHandshake *hs = static_cast(user); + if (!hs){ FAIL_MSG("Failed to cast the user pointer into a DTLSSRTPHandshake."); return -1; } - - if (!hs->write_callback) { + + if (!hs->write_callback){ FAIL_MSG("The `write_callback` member is NULL."); return -2; } - + int nwritten = (int)len; - if (0 != hs->write_callback(buf, &nwritten)) { + if (0 != hs->write_callback(buf, &nwritten)){ FAIL_MSG("Failed to write some DTLS handshake data."); return -3; } - if (nwritten != (int)len) { + if (nwritten != (int)len){ FAIL_MSG("The DTLS-SRTP handshake listener MUST write all the data."); return -4; } @@ -380,41 +373,38 @@ static int on_mbedtls_wants_to_write(void* user, const unsigned char* buf, size_ } /* ----------------------------------------- */ - -static void print_mbedtls_error(int r) { - char buf[1024] = {}; + +static void print_mbedtls_error(int r){ + char buf[1024] ={}; mbedtls_strerror(r, buf, sizeof(buf)); ERROR_MSG("mbedtls error: %s", buf); } -static void print_mbedtls_debug_message(void *ctx, int level, const char *file, int line, const char *str) { +static void print_mbedtls_debug_message(void *ctx, int level, const char *file, int line, const char *str){ DONTEVEN_MSG("%s:%04d: %.*s", file, line, strlen(str) - 1, str); #if LOG_TO_FILE static std::ofstream ofs; - if (!ofs.is_open()) { - ofs.open("mbedtls.log", std::ios::out); - } - if (!ofs.is_open()) { - return; - } + if (!ofs.is_open()){ofs.open("mbedtls.log", std::ios::out);} + if (!ofs.is_open()){return;} ofs << str; ofs.flush(); #endif - } -static std::string mbedtls_err_to_string(int r) { - switch (r) { - case MBEDTLS_ERR_SSL_WANT_READ: { return "MBEDTLS_ERR_SSL_WANT_READ"; } - case MBEDTLS_ERR_SSL_WANT_WRITE: { return "MBEDTLS_ERR_SSL_WANT_WRITE"; } - default: { - print_mbedtls_error(r); - return "UNKNOWN"; - } +static std::string mbedtls_err_to_string(int r){ + switch (r){ + case MBEDTLS_ERR_SSL_WANT_READ:{ + return "MBEDTLS_ERR_SSL_WANT_READ"; + } + case MBEDTLS_ERR_SSL_WANT_WRITE:{ + return "MBEDTLS_ERR_SSL_WANT_WRITE"; + } + default:{ + print_mbedtls_error(r); + return "UNKNOWN"; + } } } /* ---------------------------------------- */ - - diff --git a/lib/dtls_srtp_handshake.h b/lib/dtls_srtp_handshake.h index dfb319a9..b7ab8fc5 100644 --- a/lib/dtls_srtp_handshake.h +++ b/lib/dtls_srtp_handshake.h @@ -1,36 +1,37 @@ #pragma once -#include #include -#include -#include -#include #include -#include +#include +#include +#include +#include +#include #include #include -#include -#include #include +#include +#include /* ----------------------------------------- */ -class DTLSSRTPHandshake { +class DTLSSRTPHandshake{ public: DTLSSRTPHandshake(); - int init(mbedtls_x509_crt* certificate, mbedtls_pk_context* privateKey, int(*writeCallback)(const uint8_t* data, int* nbytes)); // writeCallback should return 0 on succes < 0 on error. nbytes holds the number of bytes to be sent and needs to be set to the number of bytes actually sent. + int init(mbedtls_x509_crt *certificate, + mbedtls_pk_context *privateKey, int (*writeCallback)(const uint8_t *data, int *nbytes)); // writeCallback should return 0 on succes < 0 on error. nbytes holds the number of bytes to be sent and needs to be set to the number of bytes actually sent. int shutdown(); - int parse(const uint8_t* data, size_t nbytes); + int parse(const uint8_t *data, size_t nbytes); bool hasKeyingMaterial(); - + private: int extractKeyingMaterial(); int resetSession(); - + private: - mbedtls_x509_crt* cert; /* Certificate, we do not own the key. Make sure it's kept alive during the livetime of this class instance. */ - mbedtls_pk_context* key; /* Private key, we do not own the key. Make sure it's kept alive during the livetime of this class instance. */ - mbedtls_entropy_context entropy_ctx; + mbedtls_x509_crt *cert; /* Certificate, we do not own the key. Make sure it's kept alive during the livetime of this class instance. */ + mbedtls_pk_context *key; /* Private key, we do not own the key. Make sure it's kept alive during the livetime of this class instance. */ + mbedtls_entropy_context entropy_ctx; mbedtls_ctr_drbg_context rand_ctx; mbedtls_ssl_context ssl_ctx; mbedtls_ssl_config ssl_conf; @@ -38,9 +39,9 @@ private: mbedtls_timing_delay_context timer_ctx; public: - int (*write_callback)(const uint8_t* data, int* nbytes); - std::deque buffer; /* Accessed from BIO callbback. We copy the bytes you pass into `parse()` into this temporary buffer which is read by a trigger to `mbedlts_ssl_handshake()`. */ - std::string cipher; /* selected SRTP cipher. */ + int (*write_callback)(const uint8_t *data, int *nbytes); + std::deque buffer; /* Accessed from BIO callbback. We copy the bytes you pass into `parse()` into this temporary buffer which is read by a trigger to `mbedlts_ssl_handshake()`. */ + std::string cipher; /* selected SRTP cipher. */ std::string remote_key; std::string remote_salt; std::string local_key; @@ -48,12 +49,10 @@ public: }; /* ----------------------------------------- */ - -inline bool DTLSSRTPHandshake::hasKeyingMaterial() { - return (0 != remote_key.size() - && 0 != remote_salt.size() - && 0 != local_key.size() - && 0 != local_salt.size()); + +inline bool DTLSSRTPHandshake::hasKeyingMaterial(){ + return (0 != remote_key.size() && 0 != remote_salt.size() && 0 != local_key.size() && + 0 != local_salt.size()); } /* ----------------------------------------- */ diff --git a/lib/dtsc.cpp b/lib/dtsc.cpp index ad02c164..cea94211 100644 --- a/lib/dtsc.cpp +++ b/lib/dtsc.cpp @@ -1,38 +1,36 @@ /// \file dtsc.cpp /// Holds all code for DDVTECH Stream Container parsing/generation. -#include "dtsc.h" #include "defines.h" +#include "dtsc.h" +#include //for htonl/ntohl #include #include //for memcmp -#include //for htonl/ntohl char DTSC::Magic_Header[] = "DTSC"; char DTSC::Magic_Packet[] = "DTPD"; char DTSC::Magic_Packet2[] = "DTP2"; char DTSC::Magic_Command[] = "DTCM"; -DTSC::File::File() { +DTSC::File::File(){ F = 0; buffer = malloc(4); endPos = 0; } -DTSC::File::File(const File & rhs) { +DTSC::File::File(const File &rhs){ buffer = malloc(4); *this = rhs; } -DTSC::File & DTSC::File::operator =(const File & rhs) { +DTSC::File &DTSC::File::operator=(const File &rhs){ created = rhs.created; - if (rhs.F) { + if (rhs.F){ F = fdopen(dup(fileno(rhs.F)), (created ? "w+b" : "r+b")); - } else { + }else{ F = 0; } endPos = rhs.endPos; - if (rhs.myPack) { - myPack = rhs.myPack; - } + if (rhs.myPack){myPack = rhs.myPack;} metadata = rhs.metadata; currtime = rhs.currtime; lastreadpos = rhs.lastreadpos; @@ -42,31 +40,31 @@ DTSC::File & DTSC::File::operator =(const File & rhs) { return *this; } -DTSC::File::operator bool() const { +DTSC::File::operator bool() const{ return F; } /// Open a filename for DTSC reading/writing. /// If create is true and file does not exist, attempt to create. -DTSC::File::File(std::string filename, bool create) { +DTSC::File::File(std::string filename, bool create){ buffer = malloc(8); - if (create) { + if (create){ F = fopen(filename.c_str(), "w+b"); - if (!F) { + if (!F){ DEBUG_MSG(DLVL_ERROR, "Could not create file %s: %s", filename.c_str(), strerror(errno)); return; } - //write an empty header + // write an empty header fseek(F, 0, SEEK_SET); fwrite(DTSC::Magic_Header, 4, 1, F); memset(buffer, 0, 4); - fwrite(buffer, 4, 1, F); //write 4 zero-bytes + fwrite(buffer, 4, 1, F); // write 4 zero-bytes headerSize = 0; - } else { + }else{ F = fopen(filename.c_str(), "r+b"); } created = create; - if (!F) { + if (!F){ HIGH_MSG("Could not open file %s", filename.c_str()); return; } @@ -74,62 +72,59 @@ DTSC::File::File(std::string filename, bool create) { endPos = ftell(F); bool sepHeader = false; - if (!create) { + if (!create){ fseek(F, 0, SEEK_SET); - if (fread(buffer, 4, 1, F) != 1) { + if (fread(buffer, 4, 1, F) != 1){ DEBUG_MSG(DLVL_ERROR, "Can't read file contents of %s", filename.c_str()); fclose(F); F = 0; return; } - if (memcmp(buffer, DTSC::Magic_Header, 4) != 0) { - if (memcmp(buffer, DTSC::Magic_Packet2, 4) != 0 && memcmp(buffer, DTSC::Magic_Packet, 4) != 0 && memcmp(buffer, DTSC::Magic_Command, 4) != 0) { + if (memcmp(buffer, DTSC::Magic_Header, 4) != 0){ + if (memcmp(buffer, DTSC::Magic_Packet2, 4) != 0 && + memcmp(buffer, DTSC::Magic_Packet, 4) != 0 && memcmp(buffer, DTSC::Magic_Command, 4) != 0){ DEBUG_MSG(DLVL_ERROR, "%s is not a valid DTSC file", filename.c_str()); fclose(F); F = 0; return; - } else { + }else{ metadata.moreheader = -1; } } } - //we now know the first 4 bytes are DTSC::Magic_Header and we have a valid file + // we now know the first 4 bytes are DTSC::Magic_Header and we have a valid file fseek(F, 4, SEEK_SET); - if (fread(buffer, 4, 1, F) != 1) { + if (fread(buffer, 4, 1, F) != 1){ fseek(F, 4, SEEK_SET); memset(buffer, 0, 4); - fwrite(buffer, 4, 1, F); //write 4 zero-bytes - } else { + fwrite(buffer, 4, 1, F); // write 4 zero-bytes + }else{ headerSize = ntohl(((uint32_t *)buffer)[0]); } - if (metadata.moreheader != -1) { - if (!sepHeader) { + if (metadata.moreheader != -1){ + if (!sepHeader){ readHeader(0); fseek(F, 8 + headerSize, SEEK_SET); - } else { + }else{ fseek(F, 0, SEEK_SET); } - } else { + }else{ fseek(F, 0, SEEK_SET); File Fhead(filename + ".dtsh"); - if (Fhead) { - metadata = Fhead.metadata; - } + if (Fhead){metadata = Fhead.metadata;} } currframe = 0; } - /// Returns the header metadata for this file as JSON::Value. -DTSC::Meta & DTSC::File::getMeta() { +DTSC::Meta &DTSC::File::getMeta(){ return metadata; } - /// (Re)writes the given string to the header area if the size is the same as the existing header. /// Forces a write if force is set to true. -bool DTSC::File::writeHeader(std::string & header, bool force) { - if (headerSize != header.size() && !force) { +bool DTSC::File::writeHeader(std::string &header, bool force){ + if (headerSize != header.size() && !force){ DEBUG_MSG(DLVL_ERROR, "Could not overwrite header - not equal size"); return false; } @@ -137,9 +132,7 @@ bool DTSC::File::writeHeader(std::string & header, bool force) { int pSize = htonl(header.size()); fseek(F, 4, SEEK_SET); int tmpret = fwrite((void *)(&pSize), 4, 1, F); - if (tmpret != 1) { - return false; - } + if (tmpret != 1){return false;} fseek(F, 8, SEEK_SET); int ret = fwrite(header.c_str(), headerSize, 1, F); fseek(F, 8 + headerSize, SEEK_SET); @@ -148,47 +141,41 @@ bool DTSC::File::writeHeader(std::string & header, bool force) { /// Adds the given string as a new header to the end of the file. /// \returns The positon the header was written at, or 0 on failure. -long long int DTSC::File::addHeader(std::string & header) { +long long int DTSC::File::addHeader(std::string &header){ fseek(F, 0, SEEK_END); long long int writePos = ftell(F); int hSize = htonl(header.size()); - int ret = fwrite(DTSC::Magic_Header, 4, 1, F); //write header - if (ret != 1) { - return 0; - } - ret = fwrite((void *)(&hSize), 4, 1, F); //write size - if (ret != 1) { - return 0; - } - ret = fwrite(header.c_str(), header.size(), 1, F); //write contents - if (ret != 1) { - return 0; - } + int ret = fwrite(DTSC::Magic_Header, 4, 1, F); // write header + if (ret != 1){return 0;} + ret = fwrite((void *)(&hSize), 4, 1, F); // write size + if (ret != 1){return 0;} + ret = fwrite(header.c_str(), header.size(), 1, F); // write contents + if (ret != 1){return 0;} fseek(F, 0, SEEK_END); endPos = ftell(F); - return writePos; //return position written at + return writePos; // return position written at } /// Reads the header at the given file position. /// If the packet could not be read for any reason, the reason is printed. /// Reading the header means the file position is moved to after the header. -void DTSC::File::readHeader(int pos) { +void DTSC::File::readHeader(int pos){ fseek(F, pos, SEEK_SET); - if (fread(buffer, 4, 1, F) != 1) { - if (feof(F)) { + if (fread(buffer, 4, 1, F) != 1){ + if (feof(F)){ DEBUG_MSG(DLVL_DEVEL, "End of file reached while reading header @ %d", pos); - } else { + }else{ DEBUG_MSG(DLVL_ERROR, "Could not read header @ %d", pos); } metadata = Meta(); return; } - if (memcmp(buffer, DTSC::Magic_Header, 4) != 0) { + if (memcmp(buffer, DTSC::Magic_Header, 4) != 0){ DEBUG_MSG(DLVL_ERROR, "Invalid header - %.4s != %.4s @ %i", (char *)buffer, DTSC::Magic_Header, pos); metadata = Meta(); return; } - if (fread(buffer, 4, 1, F) != 1) { + if (fread(buffer, 4, 1, F) != 1){ DEBUG_MSG(DLVL_ERROR, "Could not read header size @ %i", pos); metadata = Meta(); return; @@ -196,96 +183,91 @@ void DTSC::File::readHeader(int pos) { long packSize = ntohl(((unsigned long *)buffer)[0]) + 8; std::string strBuffer; strBuffer.resize(packSize); - if (packSize) { + if (packSize){ fseek(F, pos, SEEK_SET); - if (fread((void *)strBuffer.c_str(), packSize, 1, F) != 1) { + if (fread((void *)strBuffer.c_str(), packSize, 1, F) != 1){ DEBUG_MSG(DLVL_ERROR, "Could not read header packet @ %i", pos); metadata = Meta(); return; } - metadata = Meta(DTSC::Packet(strBuffer.data(), strBuffer.size(),true)); + metadata = Meta(DTSC::Packet(strBuffer.data(), strBuffer.size(), true)); } - //if there is another header, read it and replace metadata with that one. - if (metadata.moreheader) { - if (metadata.moreheader < getBytePosEOF()) { + // if there is another header, read it and replace metadata with that one. + if (metadata.moreheader){ + if (metadata.moreheader < getBytePosEOF()){ readHeader(metadata.moreheader); return; } } - if (!metadata.live){ - metadata.vod = true; - } + if (!metadata.live){metadata.vod = true;} } -long int DTSC::File::getBytePosEOF() { +long int DTSC::File::getBytePosEOF(){ return endPos; } -long int DTSC::File::getBytePos() { +long int DTSC::File::getBytePos(){ return ftell(F); } -bool DTSC::File::reachedEOF() { +bool DTSC::File::reachedEOF(){ return feof(F); } /// Reads the packet available at the current file position. /// If the packet could not be read for any reason, the reason is printed. /// Reading the packet means the file position is increased to the next packet. -void DTSC::File::seekNext() { - if (!currentPositions.size()) { +void DTSC::File::seekNext(){ + if (!currentPositions.size()){ DEBUG_MSG(DLVL_WARN, "No seek positions set - returning empty packet."); myPack.null(); return; } seekPos thisPos = *currentPositions.begin(); fseek(F, thisPos.bytePos, SEEK_SET); - if (reachedEOF()) { + if (reachedEOF()){ myPack.null(); return; } clearerr(F); currentPositions.erase(currentPositions.begin()); lastreadpos = ftell(F); - if (fread(buffer, 4, 1, F) != 1) { - if (feof(F)) { + if (fread(buffer, 4, 1, F) != 1){ + if (feof(F)){ DEBUG_MSG(DLVL_DEVEL, "End of file reached while seeking @ %i", (int)lastreadpos); - } else { + }else{ DEBUG_MSG(DLVL_ERROR, "Could not seek to next @ %i", (int)lastreadpos); } myPack.null(); return; } - if (memcmp(buffer, DTSC::Magic_Header, 4) == 0) { + if (memcmp(buffer, DTSC::Magic_Header, 4) == 0){ seek_time(myPack.getTime(), myPack.getTrackId(), true); return seekNext(); } long long unsigned int version = 0; - if (memcmp(buffer, DTSC::Magic_Packet, 4) == 0) { - version = 1; - } - if (memcmp(buffer, DTSC::Magic_Packet2, 4) == 0) { - version = 2; - } - if (version == 0) { - DEBUG_MSG(DLVL_ERROR, "Invalid packet header @ %#x - %.4s != %.4s @ %d", (unsigned int)lastreadpos, (char *)buffer, DTSC::Magic_Packet2, (int)lastreadpos); + if (memcmp(buffer, DTSC::Magic_Packet, 4) == 0){version = 1;} + if (memcmp(buffer, DTSC::Magic_Packet2, 4) == 0){version = 2;} + if (version == 0){ + DEBUG_MSG(DLVL_ERROR, "Invalid packet header @ %#x - %.4s != %.4s @ %d", + (unsigned int)lastreadpos, (char *)buffer, DTSC::Magic_Packet2, (int)lastreadpos); myPack.null(); return; } - if (fread(buffer, 4, 1, F) != 1) { + if (fread(buffer, 4, 1, F) != 1){ DEBUG_MSG(DLVL_ERROR, "Could not read packet size @ %d", (int)lastreadpos); myPack.null(); return; } long packSize = ntohl(((unsigned long *)buffer)[0]); - char * packBuffer = (char *)malloc(packSize + 8); - if (version == 1) { + char *packBuffer = (char *)malloc(packSize + 8); + if (version == 1){ memcpy(packBuffer, "DTPD", 4); - } else { + }else{ memcpy(packBuffer, "DTP2", 4); } memcpy(packBuffer + 4, buffer, 4); - if (fread((void *)(packBuffer + 8), packSize, 1, F) != 1) { + if (fread((void *)(packBuffer + 8), packSize, 1, F) != 1){ DEBUG_MSG(DLVL_ERROR, "Could not read packet @ %d", (int)lastreadpos); myPack.null(); free(packBuffer); @@ -293,24 +275,24 @@ void DTSC::File::seekNext() { } myPack.reInit(packBuffer, packSize + 8); free(packBuffer); - if (metadata.merged) { + if (metadata.merged){ int tempLoc = getBytePos(); char newHeader[20]; bool insert = false; seekPos tmpPos; - if (fread((void *)newHeader, 20, 1, F) == 1) { - if (memcmp(newHeader, DTSC::Magic_Packet2, 4) == 0) { + if (fread((void *)newHeader, 20, 1, F) == 1){ + if (memcmp(newHeader, DTSC::Magic_Packet2, 4) == 0){ tmpPos.bytePos = tempLoc; tmpPos.trackID = ntohl(((int *)newHeader)[2]); tmpPos.seekTime = 0; - if (selectedTracks.find(tmpPos.trackID) != selectedTracks.end()) { + if (selectedTracks.find(tmpPos.trackID) != selectedTracks.end()){ tmpPos.seekTime = ((long long unsigned int)ntohl(((int *)newHeader)[3])) << 32; tmpPos.seekTime += ntohl(((int *)newHeader)[4]); insert = true; - } else { + }else{ long tid = myPack.getTrackId(); - for (unsigned int i = 0; i != metadata.tracks[tid].keys.size(); i++) { - if ((unsigned long long)metadata.tracks[tid].keys[i].getTime() > myPack.getTime()) { + for (unsigned int i = 0; i != metadata.tracks[tid].keys.size(); i++){ + if ((unsigned long long)metadata.tracks[tid].keys[i].getTime() > myPack.getTime()){ tmpPos.seekTime = metadata.tracks[tid].keys[i].getTime(); tmpPos.bytePos = metadata.tracks[tid].keys[i].getBpos(); tmpPos.trackID = tid; @@ -319,9 +301,10 @@ void DTSC::File::seekNext() { } } } - if (currentPositions.size()) { - for (std::set::iterator curPosIter = currentPositions.begin(); curPosIter != currentPositions.end(); curPosIter++) { - if ((*curPosIter).trackID == tmpPos.trackID && (*curPosIter).seekTime >= tmpPos.seekTime) { + if (currentPositions.size()){ + for (std::set::iterator curPosIter = currentPositions.begin(); + curPosIter != currentPositions.end(); curPosIter++){ + if ((*curPosIter).trackID == tmpPos.trackID && (*curPosIter).seekTime >= tmpPos.seekTime){ insert = false; break; } @@ -330,11 +313,9 @@ void DTSC::File::seekNext() { } } if (insert){ - if (tmpPos.seekTime > 0xffffffffffffff00ll){ - tmpPos.seekTime = 0; - } + if (tmpPos.seekTime > 0xffffffffffffff00ll){tmpPos.seekTime = 0;} currentPositions.insert(tmpPos); - } else { + }else{ seek_time(myPack.getTime(), myPack.getTrackId(), true); } seek_bpos(tempLoc); @@ -345,39 +326,38 @@ void DTSC::File::seekNext() { } void DTSC::File::parseNext(){ - char header_buffer[4] = {0, 0, 0, 0}; + char header_buffer[4] ={0, 0, 0, 0}; lastreadpos = ftell(F); - if (fread(header_buffer, 4, 1, F) != 1) { - if (feof(F)) { + if (fread(header_buffer, 4, 1, F) != 1){ + if (feof(F)){ DEBUG_MSG(DLVL_DEVEL, "End of file reached @ %d", (int)lastreadpos); - } else { + }else{ DEBUG_MSG(DLVL_ERROR, "Could not read header @ %d", (int)lastreadpos); } myPack.null(); return; } long long unsigned int version = 0; - if (memcmp(header_buffer, DTSC::Magic_Packet, 4) == 0 || memcmp(header_buffer, DTSC::Magic_Command, 4) == 0 || memcmp(header_buffer, DTSC::Magic_Header, 4) == 0) { + if (memcmp(header_buffer, DTSC::Magic_Packet, 4) == 0 || memcmp(header_buffer, DTSC::Magic_Command, 4) == 0 || + memcmp(header_buffer, DTSC::Magic_Header, 4) == 0){ version = 1; } - if (memcmp(header_buffer, DTSC::Magic_Packet2, 4) == 0) { - version = 2; - } - if (version == 0) { + if (memcmp(header_buffer, DTSC::Magic_Packet2, 4) == 0){version = 2;} + if (version == 0){ DEBUG_MSG(DLVL_ERROR, "Invalid packet header @ %#x: %.4s", (unsigned int)lastreadpos, (char *)buffer); myPack.null(); return; } - if (fread(buffer, 4, 1, F) != 1) { + if (fread(buffer, 4, 1, F) != 1){ DEBUG_MSG(DLVL_ERROR, "Could not read packet size @ %#x", (unsigned int)lastreadpos); myPack.null(); return; } long packSize = ntohl(((unsigned long *)buffer)[0]); - char * packBuffer = (char *)malloc(packSize + 8); + char *packBuffer = (char *)malloc(packSize + 8); memcpy(packBuffer, header_buffer, 4); memcpy(packBuffer + 4, buffer, 4); - if (fread((void *)(packBuffer + 8), packSize, 1, F) != 1) { + if (fread((void *)(packBuffer + 8), packSize, 1, F) != 1){ DEBUG_MSG(DLVL_ERROR, "Could not read packet @ %d", (int)lastreadpos); myPack.null(); free(packBuffer); @@ -388,19 +368,19 @@ void DTSC::File::parseNext(){ } /// Returns the byte positon of the start of the last packet that was read. -long long int DTSC::File::getLastReadPos() { +long long int DTSC::File::getLastReadPos(){ return lastreadpos; } /// Returns the internal buffer of the last read packet in raw binary format. -DTSC::Packet & DTSC::File::getPacket() { +DTSC::Packet &DTSC::File::getPacket(){ return myPack; } -bool DTSC::File::seek_time(unsigned int ms, unsigned int trackNo, bool forceSeek) { +bool DTSC::File::seek_time(unsigned int ms, unsigned int trackNo, bool forceSeek){ seekPos tmpPos; tmpPos.trackID = trackNo; - if (!forceSeek && myPack && ms >= myPack.getTime() && trackNo >= myPack.getTrackId()) { + if (!forceSeek && myPack && ms >= myPack.getTime() && trackNo >= myPack.getTrackId()){ tmpPos.seekTime = myPack.getTime(); tmpPos.bytePos = getBytePos(); /* @@ -408,135 +388,124 @@ bool DTSC::File::seek_time(unsigned int ms, unsigned int trackNo, bool forceSeek tmpPos.bytePos += myPack.getDataLen(); } */ - } else { + }else{ tmpPos.seekTime = 0; tmpPos.bytePos = 0; } - if (reachedEOF()) { + if (reachedEOF()){ clearerr(F); seek_bpos(0); tmpPos.bytePos = 0; tmpPos.seekTime = 0; } - DTSC::Track & trackRef = metadata.tracks[trackNo]; - for (unsigned int i = 0; i < trackRef.keys.size(); i++) { + DTSC::Track &trackRef = metadata.tracks[trackNo]; + for (unsigned int i = 0; i < trackRef.keys.size(); i++){ long keyTime = trackRef.keys[i].getTime(); - if (keyTime > ms) { - break; - } - if ((long long unsigned int)keyTime > tmpPos.seekTime) { + if (keyTime > ms){break;} + if ((long long unsigned int)keyTime > tmpPos.seekTime){ tmpPos.seekTime = keyTime; tmpPos.bytePos = trackRef.keys[i].getBpos(); } } bool foundPacket = false; - while (!foundPacket) { + while (!foundPacket){ lastreadpos = ftell(F); - if (reachedEOF()) { + if (reachedEOF()){ DEBUG_MSG(DLVL_WARN, "Reached EOF during seek to %u in track %d - aborting @ %lld", ms, trackNo, lastreadpos); return false; } - //Seek to first packet after ms. + // Seek to first packet after ms. seek_bpos(tmpPos.bytePos); - //read the header + // read the header char header[20]; if (fread((void *)header, 20, 1, F) != 1){ DEBUG_MSG(DLVL_WARN, "Could not read header from file. Much sadface."); return false; } - //check if packetID matches, if not, skip size + 8 bytes. + // check if packetID matches, if not, skip size + 8 bytes. int packSize = ntohl(((int *)header)[1]); unsigned int packID = ntohl(((int *)header)[2]); - if (memcmp(header, Magic_Packet2, 4) != 0 || packID != trackNo) { - if (memcmp(header, "DT", 2) != 0) { - DEBUG_MSG(DLVL_WARN, "Invalid header during seek to %u in track %d @ %lld - resetting bytePos from %lld to zero", ms, trackNo, lastreadpos, tmpPos.bytePos); + if (memcmp(header, Magic_Packet2, 4) != 0 || packID != trackNo){ + if (memcmp(header, "DT", 2) != 0){ + DEBUG_MSG(DLVL_WARN, "Invalid header during seek to %u in track %d @ %lld - resetting bytePos from %lld to zero", + ms, trackNo, lastreadpos, tmpPos.bytePos); tmpPos.bytePos = 0; continue; } tmpPos.bytePos += 8 + packSize; continue; } - //get timestamp of packet, if too large, break, if not, skip size bytes. + // get timestamp of packet, if too large, break, if not, skip size bytes. long long unsigned int myTime = ((long long unsigned int)ntohl(((int *)header)[3]) << 32); myTime += ntohl(((int *)header)[4]); tmpPos.seekTime = myTime; - if (myTime >= ms) { + if (myTime >= ms){ foundPacket = true; - } else { + }else{ tmpPos.bytePos += 8 + packSize; continue; } } - //DEBUG_MSG(DLVL_HIGH, "Seek to %u:%d resulted in %lli", trackNo, ms, tmpPos.seekTime); - if (tmpPos.seekTime > 0xffffffffffffff00ll){ - tmpPos.seekTime = 0; - } + // DEBUG_MSG(DLVL_HIGH, "Seek to %u:%d resulted in %lli", trackNo, ms, tmpPos.seekTime); + if (tmpPos.seekTime > 0xffffffffffffff00ll){tmpPos.seekTime = 0;} currentPositions.insert(tmpPos); return true; } /// Attempts to seek to the given time in ms within the file. /// Returns true if successful, false otherwise. -bool DTSC::File::seek_time(unsigned int ms) { +bool DTSC::File::seek_time(unsigned int ms){ currentPositions.clear(); - if (selectedTracks.size()) { - for (std::set::iterator it = selectedTracks.begin(); it != selectedTracks.end(); it++) { + if (selectedTracks.size()){ + for (std::set::iterator it = selectedTracks.begin(); it != selectedTracks.end(); it++){ seek_time(ms, (*it), true); } } return true; } -bool DTSC::File::seek_bpos(int bpos) { - if (fseek(F, bpos, SEEK_SET) == 0) { - return true; - } +bool DTSC::File::seek_bpos(int bpos){ + if (fseek(F, bpos, SEEK_SET) == 0){return true;} return false; } -void DTSC::File::rewritePacket(std::string & newPacket, int bytePos) { +void DTSC::File::rewritePacket(std::string &newPacket, int bytePos){ fseek(F, bytePos, SEEK_SET); fwrite(newPacket.c_str(), newPacket.size(), 1, F); fseek(F, 0, SEEK_END); - if (ftell(F) > endPos) { - endPos = ftell(F); - } + if (ftell(F) > endPos){endPos = ftell(F);} } -void DTSC::File::writePacket(std::string & newPacket) { +void DTSC::File::writePacket(std::string &newPacket){ fseek(F, 0, SEEK_END); - fwrite(newPacket.c_str(), newPacket.size(), 1, F); //write contents + fwrite(newPacket.c_str(), newPacket.size(), 1, F); // write contents fseek(F, 0, SEEK_END); endPos = ftell(F); } -void DTSC::File::writePacket(JSON::Value & newPacket) { +void DTSC::File::writePacket(JSON::Value &newPacket){ writePacket(newPacket.toNetPacked()); } -bool DTSC::File::atKeyframe() { - if (myPack.getFlag("keyframe")) { - return true; - } +bool DTSC::File::atKeyframe(){ + if (myPack.getFlag("keyframe")){return true;} long long int bTime = myPack.getTime(); - DTSC::Track & trackRef = metadata.tracks[myPack.getTrackId()]; - for (unsigned int i = 0; i < trackRef.keys.size(); i++) { - if (trackRef.keys[i].getTime() >= bTime) { - return (trackRef.keys[i].getTime() == bTime); - } + DTSC::Track &trackRef = metadata.tracks[myPack.getTrackId()]; + for (unsigned int i = 0; i < trackRef.keys.size(); i++){ + if (trackRef.keys[i].getTime() >= bTime){return (trackRef.keys[i].getTime() == bTime);} } return false; } -void DTSC::File::selectTracks(std::set & tracks) { +void DTSC::File::selectTracks(std::set &tracks){ selectedTracks = tracks; currentPositions.clear(); seek_time(0); } /// Close the file if open -DTSC::File::~File() { - if (F) { +DTSC::File::~File(){ + if (F){ fclose(F); F = 0; } diff --git a/lib/dtsc.h b/lib/dtsc.h index 5ad31216..6158da0a 100644 --- a/lib/dtsc.h +++ b/lib/dtsc.h @@ -2,16 +2,16 @@ /// Holds all headers for DDVTECH Stream Container parsing/generation. #pragma once -#include -#include -#include //for uint64_t -#include -#include -#include -#include //for FILE #include "json.h" #include "socket.h" #include "timing.h" +#include +#include +#include +#include //for uint64_t +#include //for FILE +#include +#include #define DTSC_INT 0x01 #define DTSC_STR 0x02 @@ -19,187 +19,179 @@ #define DTSC_ARR 0x0A #define DTSC_CON 0xFF -//Increase this value every time the DTSH file format changes in an incompatible way -//Changelog: +// Increase this value every time the DTSH file format changes in an incompatible way +// Changelog: // Version 0-2: Undocumented changes // Version 3: switched to bigMeta-style by default, Parts layout switched from 3/2/4 to 3/3/3 bytes // Version 4: renamed bps to maxbps (peak bit rate) and added new value bps (average bit rate) #define DTSH_VERSION 4 -namespace DTSC { +namespace DTSC{ ///\brief This enum holds all possible datatypes for DTSC packets. - enum datatype { - AUDIO, ///< Stream Audio data - VIDEO, ///< Stream Video data - META, ///< Stream Metadata - PAUSEMARK, ///< Pause marker + enum datatype{ + AUDIO, ///< Stream Audio data + VIDEO, ///< Stream Video data + META, ///< Stream Metadata + PAUSEMARK, ///< Pause marker MODIFIEDHEADER, ///< Modified header data. - INVALID ///< Anything else or no data available. + INVALID ///< Anything else or no data available. }; - extern char Magic_Header[]; ///< The magic bytes for a DTSC header - extern char Magic_Packet[]; ///< The magic bytes for a DTSC packet + extern char Magic_Header[]; ///< The magic bytes for a DTSC header + extern char Magic_Packet[]; ///< The magic bytes for a DTSC packet extern char Magic_Packet2[]; ///< The magic bytes for a DTSC packet version 2 extern char Magic_Command[]; ///< The magic bytes for a DTCM packet ///\brief A simple structure used for ordering byte seek positions. - struct seekPos { + struct seekPos{ ///\brief Less-than comparison for seekPos structures. ///\param rhs The seekPos to compare with. ///\return Whether this object is smaller than rhs. - bool operator < (const seekPos & rhs) const { - if (seekTime < rhs.seekTime) { + bool operator<(const seekPos &rhs) const{ + if (seekTime < rhs.seekTime){ return true; - } else { - if (seekTime == rhs.seekTime) { - if (trackID < rhs.trackID) { - return true; - } + }else{ + if (seekTime == rhs.seekTime){ + if (trackID < rhs.trackID){return true;} } } return false; } - long long unsigned int seekTime;///< Stores the timestamp of the DTSC packet referenced by this structure. - long long unsigned int bytePos;///< Stores the byteposition of the DTSC packet referenced by this structure. - unsigned int trackID;///< Stores the track the DTSC packet referenced by this structure is associated with. + long long unsigned int seekTime; ///< Stores the timestamp of the DTSC packet referenced by this structure. + long long unsigned int bytePos; ///< Stores the byteposition of the DTSC packet referenced by this structure. + unsigned int trackID; ///< Stores the track the DTSC packet referenced by this structure is associated with. }; - enum packType { - DTSC_INVALID, - DTSC_HEAD, - DTSC_V1, - DTSC_V2, - DTCM - }; + enum packType{DTSC_INVALID, DTSC_HEAD, DTSC_V1, DTSC_V2, DTCM}; /// This class allows scanning through raw binary format DTSC data. /// It can be used as an iterator or as a direct accessor. - class Scan { - public: - Scan(); - Scan(char * pointer, size_t len); - operator bool() const; - std::string toPrettyString(size_t indent = 0) const; - bool hasMember(const std::string & indice) const; - bool hasMember(const char * indice, size_t ind_len) const; - Scan getMember(const std::string & indice) const; - Scan getMember(const char * indice) const; - Scan getMember(const char * indice, size_t ind_len) const; - void nullMember(const std::string & indice); - void nullMember(const char * indice, size_t ind_len); - Scan getIndice(size_t num) const; - std::string getIndiceName(size_t num) const; - size_t getSize() const; + class Scan{ + public: + Scan(); + Scan(char *pointer, size_t len); + operator bool() const; + std::string toPrettyString(size_t indent = 0) const; + bool hasMember(const std::string &indice) const; + bool hasMember(const char *indice, size_t ind_len) const; + Scan getMember(const std::string &indice) const; + Scan getMember(const char *indice) const; + Scan getMember(const char *indice, size_t ind_len) const; + void nullMember(const std::string &indice); + void nullMember(const char *indice, size_t ind_len); + Scan getIndice(size_t num) const; + std::string getIndiceName(size_t num) const; + size_t getSize() const; - char getType() const; - bool asBool() const; - int64_t asInt() const; - std::string asString() const; - void getString(char *& result, size_t & len) const; - JSON::Value asJSON() const; - private: - char * p; - size_t len; + char getType() const; + bool asBool() const; + int64_t asInt() const; + std::string asString() const; + void getString(char *&result, size_t &len) const; + JSON::Value asJSON() const; + + private: + char *p; + size_t len; }; /// DTSC::Packets can currently be three types: /// DTSC_HEAD packets are the "DTSC" header string, followed by 4 bytes len and packed content. /// DTSC_V1 packets are "DTPD", followed by 4 bytes len and packed content. - /// DTSC_V2 packets are "DTP2", followed by 4 bytes len, 4 bytes trackID, 8 bytes time, and packed content. - /// The len is always without the first 8 bytes counted. - class Packet { - public: - Packet(); - Packet(const Packet & rhs); - Packet(const char * data_, unsigned int len, bool noCopy = false); - virtual ~Packet(); - void null(); - void operator = (const Packet & rhs); - operator bool() const; - packType getVersion() const; - void reInit(Socket::Connection & src); - void reInit(const char * data_, unsigned int len, bool noCopy = false); - void genericFill(long long packTime, long long packOffset, long long packTrack, const char * packData, long long packDataSize, uint64_t packBytePos, bool isKeyframe, int64_t bootMsOffset = 0); - void appendData(const char * appendData, uint32_t appendLen); - void getString(const char * identifier, char *& result, size_t & len) const; - void getString(const char * identifier, std::string & result) const; - void getInt(const char * identifier, uint64_t & result) const; - uint64_t getInt(const char * identifier) const; - void getFlag(const char * identifier, bool & result) const; - bool getFlag(const char * identifier) const; - bool hasMember(const char * identifier) const; - void appendNal(const char * appendData, uint32_t appendLen); - void upgradeNal(const char * appendData, uint32_t appendLen); - void setKeyFrame(bool kf); - virtual uint64_t getTime() const; - void setTime(uint64_t _time); - void nullMember(const std::string & memb); - size_t getTrackId() const; - char * getData() const; - size_t getDataLen() const; - size_t getPayloadLen() const; - size_t getDataStringLen(); - size_t getDataStringLenOffset(); - JSON::Value toJSON() const; - std::string toSummary() const; - Scan getScan() const; - Scan getScan(); - protected: - bool master; - packType version; - void resize(size_t size); - char * data; - size_t bufferLen; - size_t dataLen; + /// DTSC_V2 packets are "DTP2", followed by 4 bytes len, 4 bytes trackID, 8 bytes time, and packed + /// content. The len is always without the first 8 bytes counted. + class Packet{ + public: + Packet(); + Packet(const Packet &rhs); + Packet(const char *data_, unsigned int len, bool noCopy = false); + virtual ~Packet(); + void null(); + void operator=(const Packet &rhs); + operator bool() const; + packType getVersion() const; + void reInit(Socket::Connection &src); + void reInit(const char *data_, unsigned int len, bool noCopy = false); + void genericFill(long long packTime, long long packOffset, long long packTrack, + const char *packData, long long packDataSize, uint64_t packBytePos, + bool isKeyframe, int64_t bootMsOffset = 0); + void appendData(const char *appendData, uint32_t appendLen); + void getString(const char *identifier, char *&result, size_t &len) const; + void getString(const char *identifier, std::string &result) const; + void getInt(const char *identifier, uint64_t &result) const; + uint64_t getInt(const char *identifier) const; + void getFlag(const char *identifier, bool &result) const; + bool getFlag(const char *identifier) const; + bool hasMember(const char *identifier) const; + void appendNal(const char *appendData, uint32_t appendLen); + void upgradeNal(const char *appendData, uint32_t appendLen); + void setKeyFrame(bool kf); + virtual uint64_t getTime() const; + void setTime(uint64_t _time); + void nullMember(const std::string &memb); + size_t getTrackId() const; + char *getData() const; + size_t getDataLen() const; + size_t getPayloadLen() const; + size_t getDataStringLen(); + size_t getDataStringLenOffset(); + JSON::Value toJSON() const; + std::string toSummary() const; + Scan getScan() const; + Scan getScan(); - uint64_t prevNalSize; + protected: + bool master; + packType version; + void resize(size_t size); + char *data; + size_t bufferLen; + size_t dataLen; + + uint64_t prevNalSize; }; /// A child class of DTSC::Packet, which allows overriding the packet time efficiently. - class RetimedPacket : public Packet { - public: - RetimedPacket(uint64_t reTime){ - timeOverride = reTime; - } - RetimedPacket(uint64_t reTime, const Packet & rhs) : Packet(rhs){ - timeOverride = reTime; - } - RetimedPacket(uint64_t reTime, const char * data_, unsigned int len, bool noCopy = false) : Packet(data_, len, noCopy){ - timeOverride = reTime; - } - virtual uint64_t getTime() const{return timeOverride;} - protected: - uint64_t timeOverride; + class RetimedPacket : public Packet{ + public: + RetimedPacket(uint64_t reTime){timeOverride = reTime;} + RetimedPacket(uint64_t reTime, const Packet &rhs) : Packet(rhs){timeOverride = reTime;} + RetimedPacket(uint64_t reTime, const char *data_, unsigned int len, bool noCopy = false) + : Packet(data_, len, noCopy){ + timeOverride = reTime; + } + virtual uint64_t getTime() const{return timeOverride;} + + protected: + uint64_t timeOverride; }; /// A simple structure used for ordering byte seek positions. - struct livePos { - livePos() { + struct livePos{ + livePos(){ seekTime = 0; trackID = 0; } - livePos(const livePos & rhs) { + livePos(const livePos &rhs){ seekTime = rhs.seekTime; trackID = rhs.trackID; } - void operator = (const livePos & rhs) { + void operator=(const livePos &rhs){ seekTime = rhs.seekTime; trackID = rhs.trackID; } - bool operator == (const livePos & rhs) { + bool operator==(const livePos &rhs){ return seekTime == rhs.seekTime && trackID == rhs.trackID; } - bool operator != (const livePos & rhs) { + bool operator!=(const livePos &rhs){ return seekTime != rhs.seekTime || trackID != rhs.trackID; } - bool operator < (const livePos & rhs) const { - if (seekTime < rhs.seekTime) { + bool operator<(const livePos &rhs) const{ + if (seekTime < rhs.seekTime){ return true; - } else { - if (seekTime > rhs.seekTime) { - return false; - } + }else{ + if (seekTime > rhs.seekTime){return false;} } return (trackID < rhs.trackID); } @@ -210,261 +202,274 @@ namespace DTSC { /*LTS-START*/ ///\brief Basic class supporting initialization Vectors. /// - ///These are used for encryption of data. - class Ivec { - public: - Ivec(); - Ivec(long long int iVec); - void setIvec(long long int iVec); - void setIvec(std::string iVec); - void setIvec(const char * iVec, int len); - long long int asInt(); - char * getData(); - private: - ///\brief Data storage for this initialization vector. - /// - /// - 8 bytes: MSB storage of the initialization vector. - char data[8]; + /// These are used for encryption of data. + class Ivec{ + public: + Ivec(); + Ivec(long long int iVec); + void setIvec(long long int iVec); + void setIvec(std::string iVec); + void setIvec(const char *iVec, int len); + long long int asInt(); + char *getData(); + + private: + ///\brief Data storage for this initialization vector. + /// + /// - 8 bytes: MSB storage of the initialization vector. + char data[8]; }; /*LTS-END*/ ///\brief Basic class for storage of data associated with single DTSC packets, a.k.a. parts. - class Part { - public: - uint32_t getSize(); - void setSize(uint32_t newSize); - uint32_t getDuration(); - void setDuration(uint32_t newDuration); - uint32_t getOffset(); - void setOffset(uint32_t newOffset); - char * getData(); - void toPrettyString(std::ostream & str, int indent = 0); - private: + class Part{ + public: + uint32_t getSize(); + void setSize(uint32_t newSize); + uint32_t getDuration(); + void setDuration(uint32_t newDuration); + uint32_t getOffset(); + void setOffset(uint32_t newOffset); + char *getData(); + void toPrettyString(std::ostream &str, int indent = 0); + + private: #define PACKED_PART_SIZE 9 - ///\brief Data storage for this Part. - /// - /// - 3 bytes: MSB storage of the payload size of this packet in bytes. - /// - 3 bytes: MSB storage of the duration of this packet in milliseconds. - /// - 3 bytes: MSB storage of the presentation time offset of this packet in milliseconds. - char data[PACKED_PART_SIZE]; + ///\brief Data storage for this Part. + /// + /// - 3 bytes: MSB storage of the payload size of this packet in bytes. + /// - 3 bytes: MSB storage of the duration of this packet in milliseconds. + /// - 3 bytes: MSB storage of the presentation time offset of this packet in milliseconds. + char data[PACKED_PART_SIZE]; }; ///\brief Basic class for storage of data associated with keyframes. /// /// When deleting this object, make sure to remove all DTSC::Part associated with it, if any. If you fail doing this, it *will* cause data corruption. - class Key { - public: - unsigned long long getBpos(); - void setBpos(unsigned long long newBpos); - unsigned long getLength(); - void setLength(unsigned long newLength); - unsigned long getNumber(); - void setNumber(unsigned long newNumber); - unsigned short getParts(); - void setParts(unsigned short newParts); - unsigned long long getTime(); - void setTime(unsigned long long newTime); - char * getData(); - void toPrettyString(std::ostream & str, int indent = 0); - private: + class Key{ + public: + unsigned long long getBpos(); + void setBpos(unsigned long long newBpos); + unsigned long getLength(); + void setLength(unsigned long newLength); + unsigned long getNumber(); + void setNumber(unsigned long newNumber); + unsigned short getParts(); + void setParts(unsigned short newParts); + unsigned long long getTime(); + void setTime(unsigned long long newTime); + char *getData(); + void toPrettyString(std::ostream &str, int indent = 0); + + private: #define PACKED_KEY_SIZE 25 - ///\brief Data storage for this Key. - /// - /// - 8 bytes: MSB storage of the position of the first packet of this keyframe within the file. - /// - 3 bytes: MSB storage of the duration of this keyframe. - /// - 4 bytes: MSB storage of the number of this keyframe. - /// - 2 bytes: MSB storage of the amount of parts in this keyframe. - /// - 8 bytes: MSB storage of the timestamp associated with this keyframe's first packet. - char data[PACKED_KEY_SIZE]; + ///\brief Data storage for this Key. + /// + /// - 8 bytes: MSB storage of the position of the first packet of this keyframe within the file. + /// - 3 bytes: MSB storage of the duration of this keyframe. + /// - 4 bytes: MSB storage of the number of this keyframe. + /// - 2 bytes: MSB storage of the amount of parts in this keyframe. + /// - 8 bytes: MSB storage of the timestamp associated with this keyframe's first packet. + char data[PACKED_KEY_SIZE]; }; ///\brief Basic class for storage of data associated with fragments. - class Fragment { - public: - unsigned long getDuration(); - void setDuration(unsigned long newDuration); - char getLength(); - void setLength(char newLength); - unsigned long getNumber(); - void setNumber(unsigned long newNumber); - unsigned long getSize(); - void setSize(unsigned long newSize); - char * getData(); - void toPrettyString(std::ostream & str, int indent = 0); - private: + class Fragment{ + public: + unsigned long getDuration(); + void setDuration(unsigned long newDuration); + char getLength(); + void setLength(char newLength); + unsigned long getNumber(); + void setNumber(unsigned long newNumber); + unsigned long getSize(); + void setSize(unsigned long newSize); + char *getData(); + void toPrettyString(std::ostream &str, int indent = 0); + + private: #define PACKED_FRAGMENT_SIZE 13 - ///\brief Data storage for this Fragment. - /// - /// - 4 bytes: duration (in milliseconds) - /// - 1 byte: length (amount of keyframes) - /// - 4 bytes: number of first keyframe in fragment - /// - 4 bytes: size of fragment in bytes - char data[PACKED_FRAGMENT_SIZE]; + ///\brief Data storage for this Fragment. + /// + /// - 4 bytes: duration (in milliseconds) + /// - 1 byte: length (amount of keyframes) + /// - 4 bytes: number of first keyframe in fragment + /// - 4 bytes: size of fragment in bytes + char data[PACKED_FRAGMENT_SIZE]; }; ///\brief Class for storage of track data - class Track { - public: - Track(); - Track(JSON::Value & trackRef); - Track(Scan & trackRef); - void clearParts(); - - inline operator bool() const { - return (parts.size() && keySizes.size() && (keySizes.size() == keys.size())); - } - /* - void update(long long packTime, long long packOffset, long long packDataSize, uint64_t packBytePos, bool isKeyframe, long long packSendSize, unsigned long segment_size = 1900); - */ - void update(long long packTime, long long packOffset, long long packDataSize, uint64_t packBytePos, bool isKeyframe, long long packSendSize, unsigned long segment_size = 1900, const char * iVec = 0); - int getSendLen(bool skipDynamic = false); - void send(Socket::Connection & conn, bool skipDynamic = false); - void writeTo(char *& p); - JSON::Value toJSON(bool skipDynamic = false); - std::deque fragments; - std::deque keys; - std::deque keySizes; - std::deque parts; - std::deque ivecs; /*LTS*/ - Key & getKey(unsigned int keyNum); - Fragment & getFrag(unsigned int fragNum); - unsigned int timeToKeynum(unsigned int timestamp); - uint32_t timeToFragnum(uint64_t timestamp); - void reset(); - void toPrettyString(std::ostream & str, int indent = 0, int verbosity = 0); - void finalize(); - uint32_t biggestFragment(); - - std::string getIdentifier(); - std::string getWritableIdentifier(); - unsigned int trackID; - uint64_t firstms; - uint64_t lastms; - int bps; - int max_bps; - int missedFrags; - std::string init; - std::string codec; - std::string type; - std::string lang;///< ISO 639-2 Language of track, empty or und if unknown. - uint32_t minKeepAway;///