diff options
| author | Tatsuhiro Tsujikawa <tatsuhiro.t@gmail.com> | 2009-07-22 12:54:35 +0000 |
|---|---|---|
| committer | Tatsuhiro Tsujikawa <tatsuhiro.t@gmail.com> | 2009-07-22 12:54:35 +0000 |
| commit | 65906c07fe8074013a52621fcc467e4bdfa0c51c (patch) | |
| tree | e5fee1667e9287d13fe6e1187dd109d008926455 /src/DHTRoutingTableDeserializer.cc | |
| parent | 0d101d47c9beb6020242fd105993a0f023485588 (diff) | |
2009-07-22 Tatsuhiro Tsujikawa <t-tujikawa@users.sourceforge.net>
Rewritten stream error handling
* src/DHTAutoSaveCommand.cc
* src/DHTRoutingTableDeserializer.cc
* src/DHTRoutingTableSerializer.cc
* src/DHTSetup.cc
Diffstat (limited to 'src/DHTRoutingTableDeserializer.cc')
| -rw-r--r-- | src/DHTRoutingTableDeserializer.cc | 255 |
1 files changed, 140 insertions, 115 deletions
diff --git a/src/DHTRoutingTableDeserializer.cc b/src/DHTRoutingTableDeserializer.cc index c60172d4..73345ad5 100644 --- a/src/DHTRoutingTableDeserializer.cc +++ b/src/DHTRoutingTableDeserializer.cc @@ -56,136 +56,161 @@ DHTRoutingTableDeserializer::DHTRoutingTableDeserializer() {} DHTRoutingTableDeserializer::~DHTRoutingTableDeserializer() {} -static std::istream& readBytes(unsigned char* buf, size_t buflen, - std::istream& in, size_t readlen) +static void readBytes(unsigned char* buf, size_t buflen, + std::istream& in, size_t readlen) { assert(readlen <= buflen); - return in.read(reinterpret_cast<char*>(buf), readlen); + in.read(reinterpret_cast<char*>(buf), readlen); } +#define CHECK_STREAM(in, length) \ + if(in.gcount() != length) { \ + throw DL_ABORT_EX \ + (StringFormat("Failed to load DHT routing table. cause:%s", \ + "Unexpected EOF").str()); \ + } \ + if(!in) { \ + throw DL_ABORT_EX \ + (StringFormat("Failed to load DHT routing table. cause:%s", \ + strerror(errno)).str()); \ + } + void DHTRoutingTableDeserializer::deserialize(std::istream& in) { - try { - char header[8]; - memset(header, 0, sizeof(header)); - // magic - header[0] = 0xa1; - header[1] = 0xa2; - // format ID - header[2] = 0x02; - // version - header[6] = 0; - header[7] = 0x03; - - char headerCompat[8]; - memset(headerCompat, 0, sizeof(headerCompat)); - // magic - headerCompat[0] = 0xa1; - headerCompat[1] = 0xa2; - // format ID - headerCompat[2] = 0x02; - // version - headerCompat[6] = 0; - headerCompat[7] = 0x02; - - char zero[8]; - memset(zero, 0, sizeof(zero)); - - int version; - - // If you change the code to read more than the size of buf, then - // expand the buf size here. - array_wrapper<unsigned char, 255> buf; - - // header - readBytes(buf, buf.size(), in, 8); - if(memcmp(header, buf, 8) == 0) { - version = 3; - } else if(memcmp(headerCompat, buf, 8) == 0) { - version = 2; - } else { - throw DL_ABORT_EX - (StringFormat("Failed to load DHT routing table. cause:%s", - "bad header").str()); - } + char header[8]; + memset(header, 0, sizeof(header)); + // magic + header[0] = 0xa1; + header[1] = 0xa2; + // format ID + header[2] = 0x02; + // version + header[6] = 0; + header[7] = 0x03; + + char headerCompat[8]; + memset(headerCompat, 0, sizeof(headerCompat)); + // magic + headerCompat[0] = 0xa1; + headerCompat[1] = 0xa2; + // format ID + headerCompat[2] = 0x02; + // version + headerCompat[6] = 0; + headerCompat[7] = 0x02; + + char zero[8]; + memset(zero, 0, sizeof(zero)); + + int version; + + // If you change the code to read more than the size of buf, then + // expand the buf size here. + array_wrapper<unsigned char, 255> buf; + + // header + readBytes(buf, buf.size(), in, 8); + CHECK_STREAM(in, 8); + if(memcmp(header, buf, 8) == 0) { + version = 3; + } else if(memcmp(headerCompat, buf, 8) == 0) { + version = 2; + } else { + throw DL_ABORT_EX + (StringFormat("Failed to load DHT routing table. cause:%s", + "bad header").str()); + } - uint32_t temp32; - uint64_t temp64; - // time - if(version == 2) { - in.read(reinterpret_cast<char*>(&temp32), sizeof(temp32)); - _serializedTime.setTimeInSec(ntohl(temp32)); - // 4bytes reserved - readBytes(buf, buf.size(), in, 4); - } else { - in.read(reinterpret_cast<char*>(&temp64), sizeof(temp64)); - _serializedTime.setTimeInSec(ntoh64(temp64)); - } + uint32_t temp32; + uint64_t temp64; + // time + if(version == 2) { + in.read(reinterpret_cast<char*>(&temp32), sizeof(temp32)); + CHECK_STREAM(in, sizeof(temp32)); + _serializedTime.setTimeInSec(ntohl(temp32)); + // 4bytes reserved + readBytes(buf, buf.size(), in, 4); + CHECK_STREAM(in, 4); + } else { + in.read(reinterpret_cast<char*>(&temp64), sizeof(temp64)); + CHECK_STREAM(in, sizeof(temp64)); + _serializedTime.setTimeInSec(ntoh64(temp64)); + } - // localnode - // 8bytes reserved - readBytes(buf, buf.size(), in, 8); + // localnode + // 8bytes reserved + readBytes(buf, buf.size(), in, 8); + CHECK_STREAM(in, 8); + // localnode ID + readBytes(buf, buf.size(), in, DHT_ID_LENGTH); + CHECK_STREAM(in, DHT_ID_LENGTH); + SharedHandle<DHTNode> localNode(new DHTNode(buf)); + // 4bytes reserved + readBytes(buf, buf.size(), in, 4); + CHECK_STREAM(in, 4); + + // number of nodes + in.read(reinterpret_cast<char*>(&temp32), sizeof(temp32)); + CHECK_STREAM(in, sizeof(temp32)); + uint32_t numNodes = ntohl(temp32); + // 4bytes reserved + readBytes(buf, buf.size(), in, 4); + CHECK_STREAM(in, 4); + + std::deque<SharedHandle<DHTNode> > nodes; + // nodes + for(size_t i = 0; i < numNodes; ++i) { + // Currently, only IPv4 addresses are supported. + // 1byte compact peer info length + uint8_t peerInfoLen; + in >> peerInfoLen; + if(peerInfoLen != 6) { + // skip this entry + readBytes(buf, buf.size(), in, 42+7+6); + CHECK_STREAM(in, 42+7+6); + continue; + } + // 7bytes reserved + readBytes(buf, buf.size(), in, 7); + CHECK_STREAM(in, 7); + // 6bytes compact peer info + readBytes(buf, buf.size(), in, 6); + CHECK_STREAM(in, 6); + if(memcmp(zero, buf, 6) == 0) { + // skip this entry + readBytes(buf, buf.size(), in, 42); + CHECK_STREAM(in, 42); + continue; + } + std::pair<std::string, uint16_t> peer = + PeerMessageUtil::unpackcompact(buf); + if(peer.first.empty()) { + // skip this entry + readBytes(buf, buf.size(), in, 42); + CHECK_STREAM(in, 42); + continue; + } + // 2bytes reserved + readBytes(buf, buf.size(), in, 2); + CHECK_STREAM(in, 2); + // 16byte reserved + readBytes(buf, buf.size(), in, 16); + CHECK_STREAM(in, 16); // localnode ID readBytes(buf, buf.size(), in, DHT_ID_LENGTH); - SharedHandle<DHTNode> localNode(new DHTNode(buf)); - // 4bytes reserved - readBytes(buf, buf.size(), in, 4); + CHECK_STREAM(in, DHT_ID_LENGTH); - // number of nodes - in.read(reinterpret_cast<char*>(&temp32), sizeof(temp32)); - uint32_t numNodes = ntohl(temp32); + SharedHandle<DHTNode> node(new DHTNode(buf)); + node->setIPAddress(peer.first); + node->setPort(peer.second); // 4bytes reserved readBytes(buf, buf.size(), in, 4); + CHECK_STREAM(in, 4); - // nodes - for(size_t i = 0; i < numNodes; ++i) { - // Currently, only IPv4 addresses are supported. - // 1byte compact peer info length - uint8_t peerInfoLen; - in >> peerInfoLen; - if(peerInfoLen != 6) { - // skip this entry - readBytes(buf, buf.size(), in, 42+7+6); - continue; - } - // 7bytes reserved - readBytes(buf, buf.size(), in, 7); - // 6bytes compact peer info - readBytes(buf, buf.size(), in, 6); - if(memcmp(zero, buf, 6) == 0) { - // skip this entry - readBytes(buf, buf.size(), in, 42); - continue; - } - std::pair<std::string, uint16_t> peer = - PeerMessageUtil::unpackcompact(buf); - if(peer.first.empty()) { - // skip this entry - readBytes(buf, buf.size(), in, 42); - continue; - } - // 2bytes reserved - readBytes(buf, buf.size(), in, 2); - // 16byte reserved - readBytes(buf, buf.size(), in, 16); - // localnode ID - readBytes(buf, buf.size(), in, DHT_ID_LENGTH); - - SharedHandle<DHTNode> node(new DHTNode(buf)); - node->setIPAddress(peer.first); - node->setPort(peer.second); - // 4bytes reserved - readBytes(buf, buf.size(), in, 4); - - _nodes.push_back(node); - } - _localNode = localNode; - } catch(std::ios::failure const& exception) { - _nodes.clear(); - throw DL_ABORT_EX - (StringFormat("Failed to load DHT routing table. cause:%s", - strerror(errno)).str()); + nodes.push_back(node); } + _localNode = localNode; + _nodes = nodes; } } // namespace aria2 |
