00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031 #include <hn/hnprec.h>
00032 #include <hn/osdep.h>
00033 #include <hn/partdata.h>
00034 #include <boost/tuple/tuple.hpp>
00035 #include <boost/random/mersenne_twister.hpp>
00036 #include "packets.h"
00037 #include "ed2k.h"
00038 #include "serverlist.h"
00039 #include "tag.h"
00040 #include "ed2kfile.h"
00041 #include "zutils.h"
00042 #include <bitset>
00043
00044
00045 namespace ED2KPacket {
00046
00047
00048
00049
00050
00051 boost::mt19937 getRandom;
00052
00053 uint64_t s_overheadUpSize = 0;
00054 uint64_t s_overheadDnSize = 0;
00055 uint64_t getOverheadUp() { return s_overheadUpSize; }
00056 uint64_t getOverheadDn() { return s_overheadDnSize; }
00057 void addOverheadDn(uint32_t amount) { s_overheadDnSize += amount; }
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070 std::vector<bool> makePartMap(const PartData *pd) {
00071 if (!pd) {
00072 return std::vector<bool>();
00073 }
00074 try {
00075 return pd->getPartStatus(ED2K_PARTSIZE);
00076 } catch (std::exception &) {}
00077
00078 std::vector<bool> partMap;
00079 for (uint32_t i = 0; i < pd->getSize(); i += ED2K_PARTSIZE + 1) {
00080 if (i + ED2K_PARTSIZE > pd->getSize()) {
00081 partMap.push_back(pd->isComplete(i, pd->getSize()));
00082 } else {
00083 partMap.push_back(pd->isComplete(i, i + ED2K_PARTSIZE));
00084 }
00085 }
00086 return partMap;
00087 }
00088
00089
00090 void writePartMap(std::ostream &o, const std::vector<bool> &partMap) {
00091 Utils::putVal<uint16_t>(o, partMap.size());
00092 std::vector<bool>::const_iterator iter = partMap.begin();
00093 while (iter != partMap.end()) {
00094 uint8_t tmp = 0;
00095 for (uint8_t i = 0; i < 8; ++i, ++iter) {
00096 if (iter == partMap.end()) {
00097 Utils::putVal<uint8_t>(o, tmp);
00098 break;
00099 } else {
00100 tmp |= *iter << i;
00101 }
00102 }
00103 Utils::putVal<uint8_t>(o, tmp);
00104 }
00105 }
00106
00107
00108 void readPartMap(std::istream &i, std::vector<bool> *partMap) {
00109 CHECK_THROW(partMap);
00110 uint16_t cnt = Utils::getVal<uint16_t>(i);
00111 while (cnt && i) {
00112 std::bitset<8> tmp(Utils::getVal<uint8_t>(i));
00113 for (uint8_t i = 0; i < (cnt >= 8 ? 8 : cnt); ++i) {
00114 partMap->push_back(tmp[i]);
00115 }
00116 cnt -= cnt > 8 ? 8 : cnt;
00117 }
00118 }
00119
00120
00121
00122 InvalidPacket::InvalidPacket(const std::string &what) :
00123 std::runtime_error(what) {}
00124
00125
00126
00127 Packet::Packet(uint8_t proto) : m_proto(proto) {}
00128 Packet::~Packet() {}
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143 std::string Packet::makePacket(const std::string &data, bool hexDump) {
00144 using namespace Zlib;
00145
00146 std::string packet(data);
00147 if (m_proto == PR_ZLIB) {
00148 std::string ret = compress(data.substr(1));
00149 if (ret.size() >= data.size()) {
00150 m_proto = PR_ED2K;
00151 } else {
00152 #ifndef NDEBUG // Verify compressiong/decompression
00153 std::string check(decompress(ret));
00154 assert(check == data.substr(1));
00155 #endif
00156 ret.insert(ret.begin(), data.at(0));
00157 packet = ret;
00158 }
00159 }
00160 std::ostringstream tmp;
00161 Utils::putVal<uint8_t>(tmp, m_proto);
00162 Utils::putVal<uint32_t>(tmp, packet.size());
00163 Utils::putVal(tmp, packet, packet.size());
00164 if (hexDump) {
00165 logDebug(boost::format(
00166 COL_SEND
00167 "Sending packet: protocol=%s opcode=%s size=%s %s %s"
00168 COL_NONE
00169 ) % Utils::hexDump(m_proto) % Utils::hexDump(data.at(0))
00170 % Utils::hexDump(data.size())
00171 % (m_proto == PR_ZLIB ?
00172 COL_COMP "(compressed)" COL_SEND
00173 : ""
00174 ) % (data.size() > 1024
00175 ? "Data size > 1024 - omitted."
00176 : Utils::hexDump(data.substr(1))
00177 )
00178 );
00179 }
00180
00181 if (tmp.str()[5] == OP_SENDINGCHUNK || tmp.str()[5] == OP_PACKEDCHUNK) {
00182 s_overheadUpSize += 30;
00183 } else {
00184 s_overheadUpSize += tmp.str().size();
00185 }
00186
00187 return tmp.str();
00188 }
00189
00190
00191
00192
00193
00194
00195
00196 LoginRequest::LoginRequest(uint8_t proto) : Packet(proto) {}
00197 LoginRequest::operator std::string() {
00198 std::ostringstream tmp;
00199 Utils::putVal<uint8_t>(tmp, OP_LOGINREQUEST);
00200 Utils::putVal(tmp, ED2K::instance().getHash().getData(), 16);
00201 Utils::putVal<uint32_t>(tmp, 0);
00202 Utils::putVal<uint16_t>(tmp, ED2K::instance().getTcpPort());
00203 Utils::putVal<uint32_t>(tmp, 5);
00204 tmp << Tag(CT_NICK, ED2K::instance().getNick());
00205 tmp << Tag(CT_VERSION, VER_EDONKEY);
00206 tmp << Tag(CT_PORT, ED2K::instance().getTcpPort());
00207 tmp << Tag(CT_MULEVERSION, VER_OWN);
00208 tmp << Tag(CT_FLAGS, FL_ZLIB|FL_NEWTAGS);
00209 return makePacket(tmp.str());
00210 }
00211
00212
00213
00214 ServerMessage::ServerMessage(std::istream &i) {
00215 uint16_t len = Utils::getVal<uint16_t>(i);
00216 m_msg = Utils::getVal<std::string>(i, len);
00217 }
00218
00219
00220
00221 ServerStatus::ServerStatus(std::istream &i) {
00222 m_users = Utils::getVal<uint32_t>(i);
00223 m_files = Utils::getVal<uint32_t>(i);
00224 }
00225
00226
00227
00228 IdChange::IdChange(std::istream &i) : m_id(Utils::getVal<uint32_t>(i)),
00229 m_flags() {
00230
00231 try {
00232 m_flags = Utils::getVal<uint32_t>(i);
00233 } catch (Utils::ReadError &) {
00234
00235 }
00236 }
00237
00238
00239
00240 GetServerList::GetServerList(uint8_t proto) : Packet(proto) {}
00241 GetServerList::operator std::string() {
00242 std::ostringstream tmp;
00243 Utils::putVal<uint8_t>(tmp, OP_GETSERVERLIST);
00244 return makePacket(tmp.str());
00245 }
00246
00247
00248
00249 ServerIdent::ServerIdent(std::istream &i) {
00250 m_hash = Utils::getVal<std::string>(i, 16);
00251 m_addr.setAddr(Utils::getVal<uint32_t>(i));
00252 m_addr.setPort(Utils::getVal<uint16_t>(i));
00253 uint32_t tagcount = Utils::getVal<uint32_t>(i);
00254 while (tagcount-- && i) {
00255 Tag t(i);
00256 switch (t.getOpcode()) {
00257 case CT_SERVERNAME:
00258 m_name = t.getStr();
00259 break;
00260 case CT_SERVERDESC:
00261 m_desc = t.getStr();
00262 break;
00263 default:
00264 warnUnHandled("ServerIdent packet", t);
00265 break;
00266 }
00267 }
00268 }
00269
00270 ServerList::ServerList(std::istream &i) {
00271 uint8_t count = Utils::getVal<uint8_t>(i);
00272 while (count--) {
00273 IPV4Address addr;
00274 addr.setAddr(Utils::getVal<uint32_t>(i));
00275 addr.setPort(Utils::getVal<uint16_t>(i));
00276 m_servers.push_back(addr);
00277 }
00278 }
00279
00280
00281
00282 OfferFiles::OfferFiles(uint8_t proto) : Packet(proto) {}
00283 OfferFiles::OfferFiles(boost::shared_ptr<ED2KFile> f, uint8_t proto)
00284 : Packet(proto) {
00285 push(f);
00286 }
00287
00288
00289 OfferFiles::operator std::string() {
00290 std::ostringstream tmp;
00291 Utils::putVal<uint8_t>(tmp, OP_OFFERFILES);
00292 Utils::putVal<uint32_t>(tmp, m_toOffer.size());
00293 for (Iter i = m_toOffer.begin(); i != m_toOffer.end(); ++i) {
00294 logDebug(
00295 boost::format("Offering file %s to server.")
00296 % (*i)->getName()
00297 );
00298 tmp << *(*i);
00299 }
00300 return makePacket(tmp.str());
00301 }
00302
00303
00304
00305
00306
00307
00308
00309
00310
00311
00312
00313
00314
00315
00316
00317 Search::Search(SearchPtr data, uint8_t proto) : Packet(proto), m_data(data) {}
00318
00319 Search::operator std::string() {
00320
00321 static const uint8_t stringParameter = 0x01;
00322 static const uint8_t typeParameter = 0x02;
00323 static const uint8_t numericParameter = 0x03;
00324 static const uint16_t andParameter = 0x0000;
00325 static const uint32_t typeNemonic = 0x030001;
00326
00327 static const uint32_t minNemonic = 0x02000101;
00328 static const uint32_t maxNemonic = 0x02000102;
00329
00330
00331 std::ostringstream tmp;
00332 uint32_t paramCount = 0;
00333
00334
00335 std::string terms;
00336 for (uint32_t i = 0; i < m_data->getTermCount(); ++i) {
00337 terms += m_data->getTerm(i) + " ";
00338 }
00339 terms.erase(--terms.end());
00340 Utils::putVal<uint16_t>(tmp, andParameter);
00341 Utils::putVal<uint8_t>(tmp, stringParameter);
00342 Utils::putVal<uint16_t>(tmp, terms.size());
00343 Utils::putVal(tmp, terms, terms.size());
00344 ++paramCount;
00345
00346
00347 std::string type(ED2KFile::HNType2ED2KType(m_data->getType()));
00348 if (!type.size()) {
00349 type = "Any";
00350 }
00351 Utils::putVal<uint8_t>(tmp, typeParameter);
00352 Utils::putVal<uint16_t>(tmp, type.size());
00353 Utils::putVal(tmp, type, type.size());
00354
00355 uint32_t _tmp(typeNemonic);
00356 _tmp = SWAP32_ON_BE(_tmp);
00357 tmp.write(reinterpret_cast<const char*>(&_tmp), 3);
00358 ++paramCount;
00359
00360
00361 if (m_data->getMinSize() > 0) {
00362 Utils::putVal<uint16_t>(tmp, andParameter);
00363 Utils::putVal<uint8_t>(tmp, numericParameter);
00364 Utils::putVal<uint32_t>(tmp, m_data->getMinSize());
00365 Utils::putVal<uint32_t>(tmp, minNemonic);
00366 ++paramCount;
00367 }
00368 if (m_data->getMaxSize() < std::numeric_limits<uint32_t>::max()) {
00369 Utils::putVal<uint16_t>(tmp, andParameter);
00370 Utils::putVal<uint8_t>(tmp, numericParameter);
00371 Utils::putVal<uint32_t>(tmp, m_data->getMaxSize());
00372 Utils::putVal<uint32_t>(tmp, maxNemonic);
00373 ++paramCount;
00374 }
00375
00376
00377
00378 std::ostringstream packet;
00379 Utils::putVal<uint8_t>(packet, OP_SEARCH);
00380 Utils::putVal(packet, tmp.str(), tmp.str().size());
00381 return makePacket(packet.str());
00382 }
00383
00384
00385
00386
00387
00388 SearchResult::SearchResult(std::istream &i) {
00389 uint32_t count = Utils::getVal<uint32_t>(i);
00390 Utils::StopWatch stopwatch;
00391 uint32_t cnt2 = count;
00392 while (count-- && i) {
00393 Hash<ED2KHash> h(Utils::getVal<std::string>(i, 16));
00394 Utils::getVal<uint32_t>(i);
00395 Utils::getVal<uint16_t>(i);
00396 uint32_t tagCount = Utils::getVal<uint32_t>(i);
00397 std::string name;
00398 uint32_t size = 0;
00399 uint32_t sources = 0;
00400 uint32_t completesrc = 0;
00401 std::string codec;
00402 uint32_t bitrate = 0;
00403 uint32_t len = 0;
00404 uint32_t lastSeen = 0;
00405 while (tagCount-- && i) {
00406 Tag t(i);
00407 switch (t.getOpcode()) {
00408 case CT_FILENAME:
00409 name = t.getStr();
00410 break;
00411 case CT_FILESIZE:
00412 size = t.getInt();
00413 break;
00414 case CT_SOURCES:
00415 sources = t.getInt();
00416 break;
00417 case CT_COMPLSRC:
00418 completesrc = t.getInt();
00419 break;
00420 case CT_MEDIA_CODEC:
00421 codec = t.getStr();
00422 break;
00423 case CT_MEDIA_BITRATE:
00424 bitrate = t.getInt();
00425 break;
00426 case CT_MEDIA_LENGTH:
00427 len = t.getInt();
00428 break;
00429 case CT_LASTSEENCOMPL:
00430 lastSeen = t.getInt();
00431 break;
00432 default:
00433 warnUnHandled("SearchResult", t);
00434 break;
00435 }
00436 }
00437 boost::shared_ptr<ED2KSearchResult> f;
00438
00439
00440 f.reset(new ED2KSearchResult(h, name, size));
00441 f->addSources(sources);
00442 f->addComplete(completesrc);
00443
00444 if (codec.empty() || bitrate || len) {
00445 f->getStrd().reset(new StreamData(codec, bitrate, len));
00446 }
00447
00448 m_results.push_back(f);
00449 }
00450
00451 logDebug(
00452 boost::format(
00453 "Parsing " COL_BCYAN "%d"COL_NONE" search results took "
00454 COL_BGREEN "%dms" COL_NONE "."
00455 ) % cnt2 % stopwatch
00456 );
00457 }
00458
00459
00460
00461 ReqCallback::ReqCallback(uint32_t id) : m_id(id) {}
00462 ReqCallback::operator std::string() {
00463 std::ostringstream tmp;
00464 Utils::putVal<uint8_t>(tmp, OP_REQCALLBACK);
00465 Utils::putVal<uint32_t>(tmp, m_id);
00466 return makePacket(tmp.str());
00467 }
00468
00469
00470
00471 CallbackReq::CallbackReq(std::istream &i) {
00472 m_addr.setAddr(Utils::getVal<uint32_t>(i));
00473 m_addr.setPort(Utils::getVal<uint16_t>(i));
00474 }
00475
00476
00477
00478 ReqSources::ReqSources(const Hash<ED2KHash> &h) : m_hash(h) {}
00479 ReqSources::operator std::string() {
00480 std::ostringstream tmp;
00481 Utils::putVal<uint8_t>(tmp, OP_GETSOURCES);
00482 Utils::putVal(tmp, m_hash.getData(), 16);
00483 return makePacket(tmp.str());
00484 }
00485
00486
00487
00488 FoundSources::FoundSources(std::istream &i) : m_lowCount() {
00489 m_hash = Utils::getVal<std::string>(i, 16);
00490 uint8_t cnt = Utils::getVal<uint8_t>(i);
00491 while (cnt--) {
00492 IPV4Address addr;
00493 addr.setAddr(Utils::getVal<uint32_t>(i));
00494 addr.setPort(Utils::getVal<uint16_t>(i));
00495 addr.setAddr(SWAP32_ON_BE(addr.getAddr()));
00496 m_sources.push_back(addr);
00497 m_lowCount += isLowId(addr.getIp());
00498 }
00499 }
00500
00501
00502
00503 GlobGetSources::GlobGetSources(bool sendSize) : m_sendSize(sendSize) {}
00504 GlobGetSources::operator std::string() {
00505 std::ostringstream tmp;
00506 Utils::putVal<uint8_t>(tmp, PR_ED2K);
00507 Utils::putVal<uint8_t>(tmp, OP_GLOBGETSOURCES);
00508 for (uint32_t i = 0; i < m_hashList.size(); ++i) {
00509 Utils::putVal(tmp, m_hashList[i].first.getData(), 16);
00510 if (m_sendSize) {
00511 Utils::putVal<uint32_t>(tmp, m_hashList[i].second);
00512 }
00513 }
00514 return tmp.str();
00515 }
00516
00517
00518
00519 GlobFoundSources::GlobFoundSources(std::istream &i) {
00520 m_hash = Utils::getVal<std::string>(i, 16);
00521 uint8_t cnt = Utils::getVal<uint8_t>(i);
00522 while (i && cnt--) {
00523 uint32_t id = Utils::getVal<uint32_t>(i);
00524 uint16_t port = Utils::getVal<uint16_t>(i);
00525 id = SWAP32_ON_BE(id);
00526 m_sources.push_back(IPV4Address(id, port));
00527 }
00528 }
00529
00530
00531
00532 GlobStatReq::GlobStatReq() {
00533 m_challenge = 0x55aa0000 + static_cast<uint16_t>(getRandom());
00534 }
00535 GlobStatReq::operator std::string() {
00536 std::ostringstream tmp;
00537 Utils::putVal<uint8_t>(tmp, PR_ED2K);
00538 Utils::putVal<uint8_t>(tmp, OP_GLOBSTATREQ);
00539 Utils::putVal<uint32_t>(tmp, m_challenge);
00540 return tmp.str();
00541 }
00542
00543
00544
00545 GlobStatRes::GlobStatRes(std::istream &i) : m_challenge(), m_users(), m_files(),
00546 m_maxUsers(), m_softLimit(), m_hardLimit(), m_udpFlags(), m_lowIdUsers() {
00547 try {
00548 m_challenge = Utils::getVal<uint32_t>(i);
00549 m_users = Utils::getVal<uint32_t>(i);
00550 m_files = Utils::getVal<uint32_t>(i);
00551 m_maxUsers = Utils::getVal<uint32_t>(i);
00552 m_softLimit = Utils::getVal<uint32_t>(i);
00553 m_hardLimit = Utils::getVal<uint32_t>(i);
00554 m_udpFlags = Utils::getVal<uint32_t>(i);
00555 m_lowIdUsers = Utils::getVal<uint32_t>(i);
00556 } catch (std::exception &) {}
00557 }
00558
00559
00560
00561
00562
00563
00564
00565 Hello::Hello(uint8_t proto , const std::string &modStr )
00566 : Packet(proto), m_modStr(modStr) {}
00567
00568 Hello::Hello(std::istream &i, bool hashLen )
00569 : m_version(), m_muleVer(), m_udpPort(), m_features() {
00570 load(i, hashLen);
00571 }
00572 void Hello::load(std::istream &i, bool hashLen) {
00573 if (hashLen) {
00574 uint8_t hashSize = Utils::getVal<uint8_t>(i);
00575 if (hashSize != 16) {
00576
00577 throw InvalidPacket("Hello: hashSize != 16");
00578 }
00579 }
00580 m_hash = Utils::getVal<std::string>(i, 16);
00581 m_clientAddr.setAddr(Utils::getVal<uint32_t>(i));
00582 m_clientAddr.setPort(Utils::getVal<uint16_t>(i));
00583 uint32_t tagcount = Utils::getVal<uint32_t>(i);
00584 while (tagcount--) {
00585 Tag t(i);
00586 try {
00587 switch (t.getOpcode()) {
00588 case CT_NICK: m_nick = t.getStr(); break;
00589 case CT_VERSION: m_version = t.getInt(); break;
00590 case CT_PORT: break;
00591 case CT_MODSTR: m_modStr = t.getStr(); break;
00592 case CT_MULEVERSION: m_muleVer = t.getInt(); break;
00593 case CT_UDPPORTS: m_udpPort = t.getInt(); break;
00594 case CT_MISCFEATURES: m_features = t.getInt(); break;
00595 default:
00596 break;
00597 }
00598 } catch (boost::bad_any_cast &) {
00599 logWarning(
00600 boost::format(
00601 "Invalid Hello Packet tag: %s"
00602 ) % t.dump()
00603 );
00604 }
00605 }
00606
00607 try {
00608 m_serverAddr.setAddr(Utils::getVal<uint32_t>(i));
00609 m_serverAddr.setPort(Utils::getVal<uint16_t>(i));
00610 } catch (Utils::ReadError&) {}
00611
00612
00613 CHECK_THROW(m_clientAddr.getPort() != 0);
00614 }
00615 Hello::operator std::string() {
00616 return save(OP_HELLO, true);
00617 }
00618 std::string Hello::save(uint8_t opcode, bool hashLen ) {
00619 std::ostringstream tmp;
00620 Utils::putVal<uint8_t>(tmp, opcode);
00621 if (hashLen) {
00622 Utils::putVal<uint8_t>(tmp, 16);
00623 }
00624
00625
00626 Utils::putVal(tmp, ED2K::instance().getHash().getData(), 16);
00627
00628 Utils::putVal<uint32_t>(tmp, ED2K::instance().getId());
00629 Utils::putVal<uint16_t>(tmp, ED2K::instance().getTcpPort());
00630
00631 uint32_t tagcount = 5;
00632
00633
00634
00635
00636 if (m_modStr.size()) {
00637 tagcount++;
00638 }
00639
00640 Utils::putVal<uint32_t>(tmp, tagcount);
00641
00642 if (m_modStr.size()) {
00643 tmp << Tag(CT_MODSTR, m_modStr);
00644 }
00645
00646 tmp << Tag(CT_NICK, ED2K::instance().getNick());
00647
00648
00649
00650 tmp << Tag(CT_VERSION, 0x3c);
00651 tmp << Tag(CT_MULEVERSION, VER_OWN);
00652 tmp << Tag(CT_UDPPORTS, ED2K::instance().getUdpPort());
00653
00654
00655 static struct Features {
00656 uint8_t m_preview :1;
00657 uint8_t m_multiPacket :1;
00658 uint8_t m_noViewShared:1;
00659 uint8_t m_peerCache :1;
00660 uint8_t m_commentVer :4;
00661 uint8_t m_extReqVer :4;
00662 uint8_t m_srcExchVer :4;
00663 uint8_t m_secIdentVer :4;
00664 uint8_t m_comprVer :4;
00665 uint8_t m_udpVer :4;
00666 uint8_t m_unicode :1;
00667 uint8_t m_aichVer :3;
00668 } options;
00669
00670 options.m_aichVer = 0;
00671 options.m_unicode = 0;
00672 options.m_udpVer = 4;
00673
00674
00675
00676
00677
00678
00679 options.m_comprVer = 0;
00680 options.m_secIdentVer = 3;
00681 options.m_srcExchVer = 3;
00682 options.m_extReqVer = 2;
00683 options.m_commentVer = 1;
00684 options.m_peerCache = 0;
00685 options.m_noViewShared = 1;
00686 options.m_multiPacket = 0;
00687 options.m_preview = 0;
00688
00689 tmp << Tag(CT_MISCFEATURES, *reinterpret_cast<uint32_t*>(&options));
00690
00691 IPV4Address addr;
00692 try {
00693 addr = ::ServerList::instance().getCurServerAddr();
00694 } catch (...) {
00695
00696
00697
00698 }
00699 Utils::putVal<uint32_t>(tmp, addr.getAddr());
00700 Utils::putVal<uint16_t>(tmp, addr.getPort());
00701
00702 return makePacket(tmp.str());
00703 }
00704
00705
00706
00707 HelloAnswer::HelloAnswer(uint8_t proto , const std::string &modStr )
00708 : Hello(proto, modStr) {}
00709 HelloAnswer::HelloAnswer(std::istream &i) : Hello(i, false) {}
00710 HelloAnswer::operator std::string() { return save(OP_HELLOANSWER, false); }
00711
00712
00713
00714 MuleInfo::MuleInfo(std::istream &i) : Packet(PR_EMULE), m_protocol(),
00715 m_version(), m_comprVer(), m_udpVer(), m_commentVer(), m_extReqVer(),
00716 m_srcExchVer(), m_compatCliID(), m_udpPort(), m_features(), m_opcode() {
00717 m_version = Utils::getVal<uint8_t>(i);
00718 m_protocol = Utils::getVal<uint8_t>(i);
00719 uint32_t tagCount = Utils::getVal<uint32_t>(i);
00720 while (i && tagCount--) {
00721 Tag t(i);
00722 switch (t.getOpcode()) {
00723 case CT_COMPRESSION: m_comprVer = t.getInt(); break;
00724 case CT_UDPVER: m_udpVer = t.getInt(); break;
00725 case CT_UDPPORT: m_udpPort = t.getInt(); break;
00726 case CT_SOURCEEXCH: m_srcExchVer = t.getInt(); break;
00727 case CT_COMMENTS: m_commentVer = t.getInt(); break;
00728 case CT_EXTREQ: m_extReqVer = t.getInt(); break;
00729 case CT_FEATURES: m_features = t.getInt(); break;
00730 case CT_COMPATCLIENT: m_compatCliID = t.getInt(); break;
00731 case CT_MODVERSION: {
00732 try {
00733 m_modStr = t.getStr();
00734 break;
00735 } catch (boost::bad_any_cast&) {
00736 try {
00737 boost::format fmt("ModID: %s");
00738 fmt % t.getInt();
00739 m_modStr = fmt.str();
00740 break;
00741 } catch (boost::bad_any_cast&) {
00742 m_modStr = "ModID: <unknown>";
00743 break;
00744 }
00745 }
00746 }
00747 default: break;
00748 }
00749 }
00750 }
00751 MuleInfo::MuleInfo() : Packet(PR_EMULE), m_opcode(OP_MULEINFO) {}
00752 MuleInfo::operator std::string() {
00753 std::ostringstream tmp;
00754 Utils::putVal<uint8_t>(tmp, m_opcode);
00755 Utils::putVal<uint8_t>(tmp, 0x44);
00756 Utils::putVal<uint8_t>(tmp, 0x01);
00757 Utils::putVal<uint32_t>(tmp, 8);
00758 tmp << Tag(CT_COMPRESSION, 0x00);
00759 tmp << Tag(CT_UDPVER, 0x04);
00760 tmp << Tag(CT_UDPPORT, ED2K::instance().getUdpPort());
00761 tmp << Tag(CT_SOURCEEXCH, 0x03);
00762 tmp << Tag(CT_COMMENTS, 0x01);
00763 tmp << Tag(CT_EXTREQ, 0x02);
00764 tmp << Tag(CT_FEATURES, 0x03);
00765 tmp << Tag(CT_COMPATCLIENT, CS_HYDRANODE);
00766 return makePacket(tmp.str());
00767 }
00768
00769
00770
00771
00772 MuleInfoAnswer::MuleInfoAnswer() {}
00773 MuleInfoAnswer::MuleInfoAnswer(std::istream &i) : MuleInfo(i) {}
00774 MuleInfoAnswer::operator std::string() {
00775 m_opcode = OP_MULEINFOANSWER;
00776 return *dynamic_cast<MuleInfo*>(this);
00777 }
00778
00779
00780
00781 ReqFile::ReqFile(const Hash<ED2KHash> &h, const PartData *pd, uint16_t srcCnt)
00782 : m_hash(h), m_srcCnt(srcCnt) {
00783 CHECK_THROW(!h.isEmpty());
00784 CHECK_THROW(pd);
00785 m_partMap = makePartMap(pd);
00786 }
00787 ReqFile::ReqFile(std::istream &i) {
00788 try {
00789 m_hash = Utils::getVal<std::string>(i, 16);
00790 readPartMap(i, &m_partMap);
00791 m_srcCnt = Utils::getVal<uint16_t>(i);
00792 } catch (Utils::ReadError&) {}
00793 }
00794
00795 ReqFile::operator std::string() {
00796 std::ostringstream tmp;
00797 Utils::putVal<uint8_t>(tmp, OP_REQFILE);
00798 Utils::putVal(tmp, m_hash.getData(), 16);
00799 writePartMap(tmp, m_partMap);
00800 Utils::putVal<uint16_t>(tmp, m_srcCnt);
00801 return makePacket(tmp.str());
00802 }
00803
00804
00805
00806 FileName::FileName(const Hash<ED2KHash> &h, const std::string &filename)
00807 : m_hash(h), m_name(filename) {}
00808 FileName::FileName(std::istream &i) {
00809 m_hash = Utils::getVal<std::string>(i, 16);
00810 uint16_t len = Utils::getVal<uint16_t>(i);
00811 m_name = Utils::getVal<std::string>(i, len);
00812 }
00813 FileName::operator std::string() {
00814 std::ostringstream tmp;
00815 Utils::putVal<uint8_t>(tmp, OP_FILENAME);
00816 Utils::putVal(tmp, m_hash.getData(), 16);
00817 Utils::putVal<uint16_t>(tmp, m_name.size());
00818 Utils::putVal(tmp, m_name, m_name.size());
00819 return makePacket(tmp.str());
00820 }
00821
00822
00823
00824 FileDesc::FileDesc(ED2KFile::Rating rating, const std::string &comment)
00825 : m_rating(rating), m_comment(comment) {}
00826 FileDesc::FileDesc(std::istream &i) {
00827 m_rating = static_cast<ED2KFile::Rating>(Utils::getVal<uint8_t>(i));
00828 uint32_t len = Utils::getVal<uint32_t>(i);
00829 m_comment = Utils::getVal<std::string>(i, len);
00830 }
00831 FileDesc::operator std::string() {
00832 std::ostringstream tmp;
00833 Utils::putVal<uint8_t>(tmp, OP_FILEDESC);
00834 Utils::putVal<uint8_t>(tmp, m_rating);
00835 Utils::putVal<uint32_t>(tmp, m_comment.size());
00836 Utils::putVal(tmp, m_comment, m_comment.size());
00837 return makePacket(tmp.str());
00838 }
00839
00840
00841
00842 SetReqFileId::SetReqFileId(const Hash<ED2KHash> &hash) : m_hash(hash) {}
00843 SetReqFileId::SetReqFileId(std::istream &i) {
00844 m_hash = Utils::getVal<std::string>(i, 16);
00845 }
00846 SetReqFileId::operator std::string() {
00847 std::ostringstream tmp;
00848 Utils::putVal<uint8_t>(tmp, OP_SETREQFILEID);
00849 Utils::putVal(tmp, m_hash.getData(), 16);
00850 return makePacket(tmp.str());
00851 }
00852
00853
00854
00855 NoFile::NoFile(const Hash<ED2KHash> &hash) : m_hash(hash) {}
00856 NoFile::NoFile(std::istream &i) {
00857 m_hash = Utils::getVal<std::string>(i, 16);
00858 }
00859 NoFile::operator std::string() {
00860 std::ostringstream tmp;
00861 Utils::putVal<uint8_t>(tmp, OP_REQFILE_NOFILE);
00862 Utils::putVal(tmp, m_hash.getData(), 16);
00863 return makePacket(tmp.str());
00864 }
00865
00866
00867
00868
00869
00870 FileStatus::FileStatus(const Hash<ED2KHash> &hash, const PartData *pd)
00871 : m_hash(hash), m_partMap(makePartMap(pd)) {
00872 CHECK_THROW(!hash.isEmpty());
00873 }
00874 FileStatus::operator std::string() {
00875 std::ostringstream tmp;
00876 Utils::putVal<uint8_t>(tmp, OP_REQFILE_STATUS);
00877 Utils::putVal(tmp, m_hash.getData(), 16);
00878 writePartMap(tmp, m_partMap);
00879 return makePacket(tmp.str());
00880 }
00881
00882 FileStatus::FileStatus(std::istream &i) {
00883 m_hash = Utils::getVal<std::string>(i, 16);
00884 readPartMap(i, &m_partMap);
00885 }
00886
00887
00888
00889 ReqHashSet::ReqHashSet(const Hash<ED2KHash> &hash) : m_hash(hash) {}
00890 ReqHashSet::ReqHashSet(std::istream &i)
00891 : m_hash(Utils::getVal<std::string>(i, 16)) {}
00892 ReqHashSet::operator std::string() {
00893 std::ostringstream tmp;
00894 Utils::putVal<uint8_t>(tmp, OP_REQHASHSET);
00895 Utils::putVal(tmp, m_hash.getData(), 16);
00896 return makePacket(tmp.str());
00897 }
00898
00899
00900
00901 HashSet::HashSet(ED2KHashSet *hashset) : m_tmpSet(hashset) {}
00902 HashSet::HashSet(std::istream &i) {
00903 m_hashSet.reset(new ED2KHashSet());
00904 m_hashSet->setFileHash(Utils::getVal<std::string>(i, 16));
00905 uint16_t count = Utils::getVal<uint16_t>(i);
00906 while (count--) {
00907 m_hashSet->addChunkHash(Utils::getVal<std::string>(i, 16));
00908 }
00909 }
00910 HashSet::operator std::string() {
00911 CHECK_THROW(m_tmpSet);
00912 std::ostringstream tmp;
00913 Utils::putVal<uint8_t>(tmp, OP_HASHSET);
00914 Utils::putVal(tmp, m_tmpSet->getFileHash().getData(), 16);
00915 Utils::putVal<uint16_t>(tmp, m_tmpSet->getChunkCnt());
00916 for (uint32_t i = 0; i < m_tmpSet->getChunkCnt(); ++i) {
00917 Utils::putVal(tmp, (*m_tmpSet)[i].getData(), 16);
00918 }
00919 return makePacket(tmp.str());
00920 }
00921
00922
00923
00924 StartUploadReq::StartUploadReq() {}
00925 StartUploadReq::StartUploadReq(const Hash<ED2KHash> &h) : m_hash(h) {}
00926 StartUploadReq::StartUploadReq(std::istream &i) {
00927
00928 try {
00929 m_hash = Utils::getVal<std::string>(i, 16);
00930 } catch (Utils::ReadError&) {}
00931 }
00932 StartUploadReq::operator std::string() {
00933 std::ostringstream tmp;
00934 Utils::putVal<uint8_t>(tmp, OP_STARTUPLOADREQ);
00935 if (!m_hash.isEmpty()) {
00936 Utils::putVal(tmp, m_hash.getData(), 16);
00937 }
00938 return makePacket(tmp.str());
00939 }
00940
00941
00942
00943 AcceptUploadReq::AcceptUploadReq() {}
00944 AcceptUploadReq::AcceptUploadReq(std::istream &) {}
00945 AcceptUploadReq::operator std::string() {
00946 std::ostringstream tmp;
00947 Utils::putVal<uint8_t>(tmp, OP_ACCEPTUPLOADREQ);
00948 return makePacket(tmp.str());
00949 }
00950
00951
00952
00953 QueueRanking::QueueRanking(uint16_t rank) : m_qr(rank) {}
00954 QueueRanking::QueueRanking(std::istream &i) {
00955 m_qr = Utils::getVal<uint32_t>(i);
00956 }
00957 QueueRanking::operator std::string() {
00958 std::ostringstream tmp;
00959 Utils::putVal<uint8_t>(tmp, OP_QUEUERANKING);
00960 Utils::putVal<uint32_t>(tmp, m_qr);
00961 return makePacket(tmp.str());
00962 }
00963
00964
00965
00966 MuleQueueRank::MuleQueueRank(uint16_t rank) : Packet(PR_EMULE), m_qr(rank) {}
00967 MuleQueueRank::MuleQueueRank(std::istream &i) {
00968 m_qr = Utils::getVal<uint16_t>(i);
00969 }
00970 MuleQueueRank::operator std::string() {
00971 std::ostringstream tmp;
00972 Utils::putVal<uint8_t>(tmp, OP_MULEQUEUERANK);
00973 Utils::putVal<uint16_t>(tmp, m_qr);
00974 Utils::putVal<uint16_t>(tmp, 0);
00975 Utils::putVal<uint32_t>(tmp, 0);
00976 Utils::putVal<uint32_t>(tmp, 0);
00977 return makePacket(tmp.str());
00978 }
00979
00980
00981
00982 ReqChunks::ReqChunks(
00983 const Hash<ED2KHash> &h, const std::list<Range32> &reqparts
00984 ) : m_hash(h) {
00985 CHECK_THROW(!m_hash.isEmpty());
00986 CHECK_THROW(reqparts.size());
00987 CHECK_THROW(reqparts.size() < 4);
00988 copy(reqparts.begin(), reqparts.end(), std::back_inserter(m_reqChunks));
00989 }
00990 ReqChunks::ReqChunks(std::istream &i) {
00991 m_hash = Utils::getVal<std::string>(i, 16);
00992 boost::tuple<uint32_t, uint32_t, uint32_t> begins;
00993 boost::tuple<uint32_t, uint32_t, uint32_t> ends;
00994 begins.get<0>() = Utils::getVal<uint32_t>(i);
00995 begins.get<1>() = Utils::getVal<uint32_t>(i);
00996 begins.get<2>() = Utils::getVal<uint32_t>(i);
00997 ends.get<0>() = Utils::getVal<uint32_t>(i);
00998 ends.get<1>() = Utils::getVal<uint32_t>(i);
00999 ends.get<2>() = Utils::getVal<uint32_t>(i);
01000 if (ends.get<0>()) {
01001 Range32 r(begins.get<0>(), ends.get<0>() - 1);
01002 m_reqChunks.push_back(r);
01003 }
01004 if (ends.get<1>()) {
01005 Range32 r(begins.get<1>(), ends.get<1>() - 1);
01006 m_reqChunks.push_back(r);
01007 }
01008 if (ends.get<2>()) {
01009 Range32 r(begins.get<2>(), ends.get<2>() - 1);
01010 m_reqChunks.push_back(r);
01011 }
01012 }
01013 ReqChunks::operator std::string() {
01014 std::ostringstream tmp;
01015 Utils::putVal<uint8_t>(tmp, OP_REQCHUNKS);
01016 Utils::putVal(tmp, m_hash.getData(), 16);
01017 CHECK_THROW(m_reqChunks.size());
01018 Utils::putVal<uint32_t>(tmp, m_reqChunks.at(0).begin());
01019 if (m_reqChunks.size() > 1) {
01020 Utils::putVal<uint32_t>(tmp, m_reqChunks.at(1).begin());
01021 } else {
01022 Utils::putVal<uint32_t>(tmp, 0);
01023 }
01024 if (m_reqChunks.size() > 2) {
01025 Utils::putVal<uint32_t>(tmp, m_reqChunks.at(2).begin());
01026 } else {
01027 Utils::putVal<uint32_t>(tmp, 0);
01028 }
01029 Utils::putVal<uint32_t>(tmp, m_reqChunks.at(0).end() + 1);
01030 if (m_reqChunks.size() > 1) {
01031 Utils::putVal<uint32_t>(tmp, m_reqChunks.at(1).end() + 1);
01032 } else {
01033 Utils::putVal<uint32_t>(tmp, 0);
01034 }
01035 if (m_reqChunks.size() > 2) {
01036 Utils::putVal<uint32_t>(tmp, m_reqChunks.at(2).end() + 1);
01037 } else {
01038 Utils::putVal<uint32_t>(tmp, 0);
01039 }
01040 return makePacket(tmp.str());
01041 }
01042
01043
01044
01045 DataChunk::DataChunk(
01046 Hash<ED2KHash> hash, uint32_t begin, uint32_t end,
01047 const std::string &data
01048 ) : m_hash(hash), m_begin(begin), m_end(end), m_data(data) {
01049 CHECK_THROW(m_end > m_begin);
01050 CHECK_THROW(m_data.size() == m_end - m_begin);
01051 CHECK_THROW(!hash.isEmpty());
01052 }
01053 DataChunk::DataChunk(std::istream &i) {
01054 m_hash = Utils::getVal<std::string>(i, 16);
01055 m_begin = Utils::getVal<uint32_t>(i);
01056 m_end = Utils::getVal<uint32_t>(i);
01057 m_data = Utils::getVal<std::string>(i, m_end - m_begin);
01058 }
01059 DataChunk::operator std::string() {
01060 std::ostringstream tmp;
01061 Utils::putVal<uint8_t>(tmp, OP_SENDINGCHUNK);
01062 Utils::putVal(tmp, m_hash.getData(), 16);
01063 Utils::putVal<uint32_t>(tmp, m_begin);
01064 Utils::putVal<uint32_t>(tmp, m_end);
01065 Utils::putVal(tmp, m_data, m_data.size());
01066 return makePacket(tmp.str());
01067 }
01068
01069
01070
01071 PackedChunk::PackedChunk(
01072 Hash<ED2KHash> hash, uint32_t begin, uint32_t size,
01073 const std::string &data
01074 ) : Packet(PR_EMULE), m_hash(hash), m_begin(begin), m_size(size), m_data(data){}
01075
01076
01077
01078
01079
01080
01081
01082
01083 PackedChunk::PackedChunk(std::istream &i) : Packet(PR_EMULE) {
01084 m_hash = Utils::getVal<std::string>(i, 16);
01085 m_begin = Utils::getVal<uint32_t>(i);
01086 m_size = Utils::getVal<uint32_t>(i);
01087 std::istringstream &is = dynamic_cast<std::istringstream&>(i);
01088 m_data = is.str().substr(24);
01089 }
01090 PackedChunk::operator std::string() {
01091 std::ostringstream tmp;
01092 Utils::putVal<uint8_t>(tmp, OP_PACKEDCHUNK);
01093 Utils::putVal(tmp, m_hash.getData(), 16);
01094 Utils::putVal<uint32_t>(tmp, m_begin);
01095 Utils::putVal<uint32_t>(tmp, m_size);
01096 Utils::putVal(tmp, m_data, m_data.size());
01097 return makePacket(tmp.str());
01098 }
01099
01100
01101
01102 CancelTransfer::CancelTransfer() {}
01103 CancelTransfer::CancelTransfer(std::istream &) {}
01104 CancelTransfer::operator std::string() {
01105 std::ostringstream tmp;
01106 Utils::putVal<uint8_t>(tmp, OP_CANCELTRANSFER);
01107 return makePacket(tmp.str());
01108 }
01109
01110
01111
01112 SourceExchReq::SourceExchReq(const Hash<ED2KHash> &hash)
01113 : Packet(PR_EMULE), m_hash(hash) {
01114 CHECK_THROW(m_hash);
01115 }
01116 SourceExchReq::SourceExchReq(std::istream &i) {
01117 m_hash = Utils::getVal<std::string>(i, 16);
01118 }
01119 SourceExchReq::operator std::string() {
01120 std::ostringstream tmp;
01121 Utils::putVal<uint8_t>(tmp, OP_REQSOURCES);
01122 Utils::putVal(tmp, m_hash.getData(), 16);
01123 return makePacket(tmp.str());
01124 }
01125
01126
01127
01128 AnswerSources::AnswerSources(const Hash<ED2KHash> &hash, const SourceList &srcs)
01129 : Packet(PR_EMULE), m_hash(hash), m_srcList(srcs), m_swapIds() {
01130 CHECK_THROW(m_hash);
01131 }
01132 AnswerSources::AnswerSources(std::istringstream &i) {
01133 m_hash = Utils::getVal<std::string>(i, 16);
01134 uint16_t cnt = Utils::getVal<uint16_t>(i);
01135 bool hashes = true;
01136
01137 if (i.str().size() - 18u == cnt * 12u) {
01138 hashes = false;
01139 } else if (i.str().size() - 18u == cnt * (12u + 16u)) {
01140 hashes = true;
01141 } else {
01142 logDebug(
01143 boost::format(
01144 "%s: Shouldn't get here; cnt=%d size=%d data:%s"
01145 ) % __PRETTY_FUNCTION__ % cnt % i.str().size()
01146 % Utils::hexDump(i.str())
01147 );
01148 }
01149
01150 while (i && cnt--) {
01151 Source tmp;
01152 tmp.get<0>() = Utils::getVal<uint32_t>(i);
01153 tmp.get<1>() = Utils::getVal<uint16_t>(i);
01154 tmp.get<2>() = Utils::getVal<uint32_t>(i);
01155 tmp.get<3>() = Utils::getVal<uint16_t>(i);
01156 if (hashes) {
01157
01158 i.seekg(16, std::ios::cur);
01159 }
01160 m_srcList.push_back(tmp);
01161 }
01162 }
01163
01164 AnswerSources::operator std::string() {
01165 std::ostringstream tmp;
01166 Utils::putVal<uint8_t>(tmp, OP_ANSWERSOURCES);
01167 Utils::putVal<uint16_t>(tmp, m_srcList.size());
01168 for (CIter i = begin(); i != end(); ++i) {
01169 if (m_swapIds) {
01170 SWAP32_ON_LE((*i).get<0>());
01171 }
01172 Utils::putVal<uint32_t>(tmp, (*i).get<0>());
01173 Utils::putVal<uint16_t>(tmp, (*i).get<1>());
01174 Utils::putVal<uint32_t>(tmp, (*i).get<2>());
01175 Utils::putVal<uint16_t>(tmp, (*i).get<3>());
01176 }
01177 return makePacket(tmp.str());
01178 }
01179
01180
01181
01182 Message::Message(const std::string &msg) : m_message(msg) {}
01183 Message::Message(std::istream &i) {
01184 uint16_t len = Utils::getVal<uint16_t>(i);
01185 m_message = Utils::getVal<std::string>(i, len);
01186 }
01187 Message::operator std::string() {
01188 std::ostringstream tmp;
01189 Utils::putVal<uint16_t>(tmp, m_message.size());
01190 Utils::putVal(tmp, m_message, m_message.size());
01191 return makePacket(tmp.str());
01192 }
01193
01194
01195
01196 ChangeId::ChangeId(uint32_t oldId, uint32_t newId)
01197 : m_oldId(oldId), m_newId(newId) {
01198 CHECK_THROW(m_oldId);
01199 CHECK_THROW(m_newId);
01200 }
01201 ChangeId::ChangeId(std::istream &i) {
01202 m_oldId = Utils::getVal<uint32_t>(i);
01203 m_newId = Utils::getVal<uint32_t>(i);
01204
01205 CHECK_THROW(m_oldId);
01206 CHECK_THROW(m_newId);
01207 }
01208 ChangeId::operator std::string() {
01209 std::ostringstream tmp;
01210 Utils::putVal<uint8_t>(tmp, OP_CHANGEID);
01211 Utils::putVal<uint32_t>(tmp, m_oldId);
01212 Utils::putVal<uint32_t>(tmp, m_newId);
01213 return makePacket(tmp.str());
01214 }
01215
01216
01217
01218 SecIdentState::SecIdentState(::SecIdentState s)
01219 : Packet(PR_EMULE), m_state(s), m_challenge() {
01220 m_challenge = getRandom();
01221 }
01222 SecIdentState::SecIdentState(std::istream &i) {
01223 m_state = Utils::getVal<uint8_t>(i);
01224 m_challenge = Utils::getVal<uint32_t>(i);
01225 }
01226 SecIdentState::operator std::string() {
01227 std::ostringstream tmp;
01228 Utils::putVal<uint8_t>(tmp, OP_SECIDENTSTATE);
01229 Utils::putVal<uint8_t>(tmp, m_state);
01230 Utils::putVal<uint32_t>(tmp, m_challenge);
01231 return makePacket(tmp.str());
01232 }
01233
01234
01235
01236 PublicKey::PublicKey(const ::PublicKey &pubKey)
01237 : Packet(PR_EMULE), m_pubKey(pubKey) {}
01238 PublicKey::PublicKey(std::istream &i) {
01239 uint8_t keyLen = Utils::getVal<uint8_t>(i);
01240 m_pubKey = ::PublicKey(Utils::getVal<std::string>(i, keyLen));
01241 }
01242 PublicKey::operator std::string() {
01243 std::ostringstream tmp;
01244 Utils::putVal<uint8_t>(tmp, OP_PUBLICKEY);
01245 Utils::putVal<uint8_t>(tmp, m_pubKey.size());
01246 Utils::putVal(tmp, m_pubKey.c_str(), m_pubKey.size());
01247 return makePacket(tmp.str());
01248 }
01249
01250
01251
01252 Signature::Signature(const std::string &sign, IpType ipType)
01253 : Packet(PR_EMULE), m_signature(sign), m_ipType(ipType) {}
01254 Signature::Signature(std::istream &i) : m_ipType() {
01255 std::istringstream &is = dynamic_cast<std::istringstream&>(i);
01256 uint8_t len = Utils::getVal<uint8_t>(is);
01257 if (is.str().substr(1).size() == len) {
01258 m_signature = Utils::getVal<std::string>(i, len);
01259 } else {
01260
01261 m_signature = Utils::getVal<std::string>(i, len);
01262 m_ipType = Utils::getVal<uint8_t>(i);
01263 }
01264 }
01265
01266 Signature::operator std::string() {
01267 std::ostringstream tmp;
01268 Utils::putVal<uint8_t>(tmp, OP_SIGNATURE);
01269 Utils::putVal<uint8_t>(tmp, m_signature.size());
01270 Utils::putVal(tmp, m_signature, m_signature.size());
01271 if (m_ipType) {
01272 Utils::putVal<uint8_t>(tmp, m_ipType);
01273 }
01274 return makePacket(tmp.str());
01275 }
01276
01277
01278
01279
01280
01281
01282
01283 ReaskFilePing::ReaskFilePing(
01284 const Hash<ED2KHash> &h, const PartData *pd, uint16_t srcCnt,
01285 uint8_t udpVersion
01286 ) : m_hash(h), m_partMap(makePartMap(pd)), m_srcCnt(srcCnt),
01287 m_udpVersion(udpVersion) {}
01288 ReaskFilePing::ReaskFilePing(std::istream &i) {
01289 m_hash = Utils::getVal<std::string>(i, 16);
01290 std::istringstream &tmp = dynamic_cast<std::istringstream&>(i);
01291 if (tmp.str().size() >= 20) {
01292 readPartMap(i, &m_partMap);
01293 }
01294 if (tmp.str().size() >= 18) {
01295 m_srcCnt = Utils::getVal<uint16_t>(i);
01296 }
01297 }
01298 ReaskFilePing::operator std::string() {
01299 std::ostringstream tmp;
01300 Utils::putVal<uint8_t>(tmp, PR_EMULE);
01301 Utils::putVal<uint8_t>(tmp, OP_REASKFILEPING);
01302 Utils::putVal(tmp, m_hash.getData(), 16);
01303 if (m_udpVersion >= 4) {
01304 writePartMap(tmp, m_partMap);
01305 }
01306 if (m_udpVersion >= 3) {
01307 Utils::putVal<uint16_t>(tmp, m_srcCnt);
01308 }
01309 return tmp.str();
01310 }
01311
01312
01313
01314 QueueFull::QueueFull() {}
01315 QueueFull::QueueFull(std::istream &) {}
01316 QueueFull::operator std::string() {
01317 std::ostringstream tmp;
01318 Utils::putVal<uint8_t>(tmp, PR_EMULE);
01319 Utils::putVal<uint8_t>(tmp, OP_QUEUEFULL);
01320 return tmp.str();
01321 }
01322
01323
01324
01325 ReaskAck::ReaskAck(const PartData *pd, uint16_t qr, uint8_t udpVersion)
01326 : Packet(PR_EMULE), m_partMap(makePartMap(pd)), m_qr(qr),
01327 m_udpVersion(udpVersion) {}
01328 ReaskAck::ReaskAck(std::istream &i) {
01329 std::istringstream &tmp = dynamic_cast<std::istringstream&>(i);
01330 if (tmp.str().size() >= 4) {
01331 readPartMap(tmp, &m_partMap);
01332 }
01333 m_qr = Utils::getVal<uint16_t>(i);
01334 }
01335 ReaskAck::operator std::string() {
01336 std::ostringstream tmp;
01337 Utils::putVal<uint8_t>(tmp, PR_EMULE);
01338 Utils::putVal<uint8_t>(tmp, OP_REASKACK);
01339 if (m_udpVersion >= 4) {
01340 writePartMap(tmp, m_partMap);
01341 }
01342 Utils::putVal<uint16_t>(tmp, m_qr);
01343 return tmp.str();
01344 }
01345
01346
01347
01348 FileNotFound::FileNotFound() {}
01349 FileNotFound::FileNotFound(std::istream &) {}
01350 FileNotFound::operator std::string() {
01351 std::ostringstream tmp;
01352 Utils::putVal<uint8_t>(tmp, PR_EMULE);
01353 Utils::putVal<uint8_t>(tmp, OP_FILENOTFOUND);
01354 return tmp.str();
01355 }
01356
01357
01358
01359 PortTest::PortTest() {}
01360 PortTest::PortTest(std::istream &) {}
01361 PortTest::operator std::string() {
01362 std::ostringstream tmp;
01363 Utils::putVal<uint8_t>(tmp, PR_EMULE);
01364 Utils::putVal<uint8_t>(tmp, OP_PORTTEST);
01365 Utils::putVal<uint8_t>(tmp, 1);
01366 return tmp.str();
01367 }
01368
01369 }