X-Git-Url: https://git.sesse.net/?p=cubemap;a=blobdiff_plain;f=httpinput.cpp;h=c975a2497007c1d45605ce73103f5405be4c78ed;hp=7f96970b678fb75c68a31746a39087a1a41e269d;hb=bfc1a54cf84bb1784c14bd4f5acbb500460e35b5;hpb=70c0baf4bcec3a77f0626d5a7bfde87fc7339698 diff --git a/httpinput.cpp b/httpinput.cpp index 7f96970..c975a24 100644 --- a/httpinput.cpp +++ b/httpinput.cpp @@ -8,6 +8,7 @@ #include #include #include +#include #include #include #include @@ -17,11 +18,12 @@ #include "httpinput.h" #include "log.h" -#include "metacube.h" +#include "metacube2.h" #include "mutexlock.h" #include "parse.h" #include "serverpool.h" #include "state.pb.h" +#include "stream.h" #include "util.h" #include "version.h" @@ -505,7 +507,7 @@ void HTTPInput::process_data(char *ptr, size_t bytes) for ( ;; ) { // If we don't have enough data (yet) for even the Metacube header, just return. - if (pending_data.size() < sizeof(metacube_block_header)) { + if (pending_data.size() < sizeof(metacube2_block_header)) { return; } @@ -514,13 +516,13 @@ void HTTPInput::process_data(char *ptr, size_t bytes) if (!has_metacube_header) { char *ptr = static_cast( memmem(pending_data.data(), pending_data.size(), - METACUBE_SYNC, strlen(METACUBE_SYNC))); + METACUBE2_SYNC, strlen(METACUBE2_SYNC))); if (ptr == NULL) { // OK, so we didn't find the sync marker. We know then that // we do not have the _full_ marker in the buffer, but we // could have N-1 bytes. Drop everything before that, // and then give up. - drop_pending_data(pending_data.size() - (strlen(METACUBE_SYNC) - 1)); + drop_pending_data(pending_data.size() - (strlen(METACUBE2_SYNC) - 1)); return; } else { // Yay, we found the header. Drop everything (if anything) before it. @@ -528,25 +530,38 @@ void HTTPInput::process_data(char *ptr, size_t bytes) has_metacube_header = true; // Re-check that we have the entire header; we could have dropped data. - if (pending_data.size() < sizeof(metacube_block_header)) { + if (pending_data.size() < sizeof(metacube2_block_header)) { return; } } } // Now it's safe to read the header. - metacube_block_header *hdr = reinterpret_cast(pending_data.data()); - assert(memcmp(hdr->sync, METACUBE_SYNC, sizeof(hdr->sync)) == 0); - uint32_t size = ntohl(hdr->size); - uint32_t flags = ntohl(hdr->flags); - + metacube2_block_header hdr; + memcpy(&hdr, pending_data.data(), sizeof(hdr)); + assert(memcmp(hdr.sync, METACUBE2_SYNC, sizeof(hdr.sync)) == 0); + uint32_t size = ntohl(hdr.size); + uint16_t flags = ntohs(hdr.flags); + uint16_t expected_csum = metacube2_compute_crc(&hdr); + + if (expected_csum != ntohs(hdr.csum)) { + log(WARNING, "[%s] Metacube checksum failed (expected 0x%x, got 0x%x), " + "not reading block claiming to be %d bytes (flags=%x).", + url.c_str(), expected_csum, ntohs(hdr.csum), + size, flags); + + // Drop only the first byte, and let the rest of the code handle resync. + pending_data.erase(pending_data.begin(), pending_data.begin() + 1); + has_metacube_header = false; + continue; + } if (size > 262144) { log(WARNING, "[%s] Metacube block of %d bytes (flags=%x); corrupted header?", url.c_str(), size, flags); } // See if we have the entire block. If not, wait for more data. - if (pending_data.size() < sizeof(metacube_block_header) + size) { + if (pending_data.size() < sizeof(metacube2_block_header) + size) { return; } @@ -555,7 +570,7 @@ void HTTPInput::process_data(char *ptr, size_t bytes) MutexLock lock(&stats_mutex); stats.data_bytes_received += size; } - char *inner_data = pending_data.data() + sizeof(metacube_block_header); + char *inner_data = pending_data.data() + sizeof(metacube2_block_header); if (flags & METACUBE_FLAGS_HEADER) { stream_header = string(inner_data, inner_data + size); for (size_t i = 0; i < stream_indices.size(); ++i) { @@ -576,7 +591,7 @@ void HTTPInput::process_data(char *ptr, size_t bytes) // Consume the block. This isn't the most efficient way of dealing with things // should we have many blocks, but these routines don't need to be too efficient // anyway. - pending_data.erase(pending_data.begin(), pending_data.begin() + sizeof(metacube_block_header) + size); + pending_data.erase(pending_data.begin(), pending_data.begin() + sizeof(metacube2_block_header) + size); has_metacube_header = false; } } @@ -586,7 +601,7 @@ void HTTPInput::drop_pending_data(size_t num_bytes) if (num_bytes == 0) { return; } - log(WARNING, "[%s] Dropping %lld junk bytes from stream, maybe it is not a Metacube stream?", + log(WARNING, "[%s] Dropping %lld junk bytes from stream, maybe it is not a Metacube2 stream?", url.c_str(), (long long)num_bytes); assert(pending_data.size() >= num_bytes); pending_data.erase(pending_data.begin(), pending_data.begin() + num_bytes);