summaryrefslogtreecommitdiff
path: root/src/DHTRoutingTableDeserializer.cc
diff options
context:
space:
mode:
authorTatsuhiro Tsujikawa <tatsuhiro.t@gmail.com>2009-07-22 12:54:35 +0000
committerTatsuhiro Tsujikawa <tatsuhiro.t@gmail.com>2009-07-22 12:54:35 +0000
commit65906c07fe8074013a52621fcc467e4bdfa0c51c (patch)
treee5fee1667e9287d13fe6e1187dd109d008926455 /src/DHTRoutingTableDeserializer.cc
parent0d101d47c9beb6020242fd105993a0f023485588 (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.cc255
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