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
00032
00077 #include <stdint.h>
00078 #include <inttypes.h>
00079 #include <sys/types.h>
00080 #include "m_net.h"
00081 #include <iomanip>
00082 #include <cassert>
00083 #include <boost/shared_ptr.hpp>
00084 #include <string>
00085
00086
00087
00088 #include "Serializable.h"
00089 #include "Exception.h"
00090 #include "HashUtil.h"
00091 #include "Log.h"
00092 #include "MaceBasics.h"
00093 #include "Collections.h"
00094
00095 #ifndef __MACEKEY_H
00096 #define __MACEKEY_H
00097
00098 #define MACE_KEY_USE_SHARED_PTR
00099
00100 namespace mace {
00101
00109 class SockAddr : public mace::PrintPrintable, public mace::Serializable {
00110 public:
00111 SockAddr() : addr(INADDR_NONE), port(0) { }
00112 SockAddr(const SockAddr& s) : addr(s.addr), port(s.port) { }
00113 SockAddr(uint32_t a, uint16_t p) : addr(a), port(p) { }
00114 void print(std::ostream& out) const;
00115 void print(PrintNode& pr, const std::string& name) const;
00116 void serialize(std::string& s) const {
00117 mace::serialize(s, &addr);
00118 mace::serialize(s, &port);
00119 }
00120 int deserialize(std::istream& in) throw (mace::SerializationException) {
00121 int o = 0;
00122 o += mace::deserialize(in, &addr);
00123 o += mace::deserialize(in, &port);
00124 return o;
00125 }
00126 bool operator==(const SockAddr& other) const {
00127 return ((other.addr == addr) && (other.port == port));
00128 }
00129 bool operator!=(const SockAddr& other) const {
00130 return (!(*this == other));
00131 }
00132 bool operator<(const SockAddr& other) const {
00133 if (addr < other.addr) {
00134 return true;
00135 }
00136 else if (addr == other.addr) {
00137 return port < other.port;
00138 }
00139 else {
00140 return false;
00141 }
00142 }
00144 bool isUnroutable() const {
00145 return !isNull() && port == 0;
00146 }
00148 bool isNull() const;
00149
00150 public:
00151 uint32_t addr;
00152 uint16_t port;
00153 };
00154
00166 class MaceAddr : public mace::PrintPrintable, public mace::Serializable {
00167 public:
00168 MaceAddr() : local(SockAddr()), proxy(SockAddr()) { }
00169 MaceAddr(const MaceAddr& s) : local(s.local), proxy(s.proxy) { }
00170 MaceAddr(const SockAddr& l, const SockAddr& p) : local(l), proxy(p) { }
00171 void print(std::ostream& out) const;
00172 void print(PrintNode& pr, const std::string& name) const;
00173 void serialize(std::string& s) const {
00174 local.serialize(s);
00175 proxy.serialize(s);
00176 }
00177 int deserialize(std::istream& in) throw (mace::SerializationException) {
00178 int o = 0;
00179 o += local.deserialize(in);
00180 o += proxy.deserialize(in);
00181 return o;
00182 }
00183 bool operator==(const MaceAddr& other) const {
00184 return ((other.local == local) && (other.proxy == proxy));
00185 }
00186 bool operator!=(const MaceAddr& other) const {
00187 return (!(*this == other));
00188 }
00189 bool operator<(const MaceAddr& other) const {
00190 if (local < other.local) {
00191 return true;
00192 }
00193 else if (local == other.local) {
00194 return proxy < other.proxy;
00195 }
00196 else {
00197 return false;
00198 }
00199 }
00201 bool isUnroutable() const {
00202 return local.isUnroutable();
00203 }
00204 bool isNull() const;
00205
00206 public:
00207 SockAddr local;
00208 SockAddr proxy;
00209 };
00210
00211 }
00212
00213 namespace __gnu_cxx {
00214
00215 template<> struct hash<mace::SockAddr> {
00216 uint32_t operator()(const mace::SockAddr& x) const {
00217 return hash<uint32_t>()(x.addr * x.port);
00218 }
00219 };
00220
00221 template<> struct hash<mace::MaceAddr> {
00222 uint32_t operator()(const mace::MaceAddr& x) const {
00223 return hash<uint32_t>()((x.local.addr * x.local.port)^
00224 (x.proxy.addr * x.proxy.port));
00225 }
00226 };
00227
00228 }
00229
00230 namespace mace {
00231
00232 class InvalidMaceKeyException : public SerializationException {
00233 public:
00234 InvalidMaceKeyException(const std::string& m) : SerializationException(m) { }
00235 void rethrow() const { throw *this; }
00236 };
00237
00238 class IndexOutOfBoundsException : public Exception {
00239 public:
00240 IndexOutOfBoundsException(const std::string& m) : Exception(m) { }
00241 void rethrow() const { throw *this; }
00242 };
00243
00244 class DigitBaseException : public Exception {
00245 public:
00246 DigitBaseException(const std::string& m) : Exception(m) { }
00247 void rethrow() const { throw *this; }
00248 };
00249
00250 class MaceKey;
00251
00253 class MaceKey_interface : public Serializable, virtual public Printable {
00254 friend class MaceKey;
00255 public:
00256
00257 virtual bool isUnroutable() const = 0;
00258 virtual bool isNullAddress() const = 0;
00259 virtual std::string toHex() const = 0;
00260
00261
00262 virtual std::string addressString() const = 0;
00263 virtual bool isBitArrMaceKey() const = 0;
00264 virtual size_t hashOf() const = 0;
00265 virtual bool operator==(const MaceKey& right) const = 0;
00266 virtual bool operator<(const MaceKey& right) const = 0;
00267
00268
00269 virtual const MaceAddr& getMaceAddr() const = 0;
00270
00271
00272 virtual int bitLength() const = 0;
00273
00274
00275
00276 virtual uint32_t getNthDigit(int position, uint32_t digitBits = 4) const = 0;
00277 virtual void setNthDigit(uint32_t value, int position, uint32_t digitBits = 4) = 0;
00278 virtual int sharedPrefixLength(const MaceKey& key, uint32_t digitBits = 4) const = 0;
00279 protected:
00280 virtual uint32_t getNthDigitSafe(int position, uint32_t digitBits) const = 0;
00281 };
00282
00284 class MaceKey : public MaceKey_interface, virtual public PrintPrintable {
00285 public:
00290 static const MaceKey null;
00291 private:
00293 class MaceKey_interface_helper : public MaceKey_interface {
00294 public:
00295 virtual MaceKey_interface_helper* clone() const = 0;
00296 };
00297 #ifndef MACE_KEY_USE_SHARED_PTR
00298 typedef MaceKey_interface_helper* HelperPtr;
00299 #else
00300 typedef boost::shared_ptr<MaceKey_interface_helper> HelperPtr;
00301 #endif
00302 HelperPtr helper;
00303 int8_t address_family;
00304
00305 protected:
00306 uint32_t getNthDigitSafe(int position, uint32_t digitBits) const { return helper->getNthDigitSafe(position, digitBits); }
00307
00308 public:
00309 static bool getHostnameOnly();
00310
00311 int8_t addressFamily() const { return address_family; }
00312 bool isUnroutable() const { return (helper == NULL ? true : helper->isUnroutable()); }
00313 bool isNullAddress() const { return (helper==NULL?true:helper->isNullAddress()); }
00314 std::string toHex() const {
00315 std::string hexStr = Log::toHex(std::string((char*)&address_family, sizeof(int8_t )));
00316 if(helper != NULL) { hexStr += helper->toHex(); }
00317 return hexStr;
00318 }
00319 void print(std::ostream& out) const {
00320 static bool hostnameOnly = getHostnameOnly();
00321 if (helper != NULL) {
00322 if (!hostnameOnly) {
00323 out << addressFamilyName(address_family) << "/";
00324 }
00325 out << (*helper);
00326 }
00327 else {
00328 out << addressFamilyName(address_family) << "/";
00329 }
00330 }
00331 void print(PrintNode& pr, const std::string& name) const {
00332 pr.addChild(PrintNode(name, std::string("MaceKey::") + addressFamilyName(address_family),
00333 helper ? helper->toString() : string()));
00334 }
00335 std::string addressString() const {
00336 return addressString(true);
00337 }
00338 std::string addressString(bool printFamily) const {
00339 if (printFamily) {
00340 std::ostringstream out;
00341 out << addressFamilyName(address_family) << "/";
00342 if (helper != 0) {
00343 out << helper->addressString();
00344 }
00345 return out.str();
00346 }
00347 if (helper == 0) {
00348 throw InvalidMaceKeyException("addressString() called with no helper defined");
00349 }
00350 return helper->addressString();
00351 }
00352 bool isBitArrMaceKey() const { return (helper==NULL?false:helper->isBitArrMaceKey()); }
00353 size_t hashOf() const { return (helper==NULL?0:helper->hashOf()); }
00354
00355
00356 const MaceAddr& getMaceAddr() const throw(InvalidMaceKeyException) {
00357 if(helper==NULL) {
00358 throw(InvalidMaceKeyException("No Helper Defined for getMaceAddr"));
00359 } else {
00360 return helper->getMaceAddr();
00361 }
00362 }
00363
00364
00365 int bitLength() const throw(InvalidMaceKeyException) { if(helper==NULL) { throw(InvalidMaceKeyException("No Helper Defined")); } else { return helper->bitLength(); } }
00366 uint32_t getNthDigit(int position, uint32_t digitBits = 4) const throw(Exception)
00367 { if(helper==NULL) { throw(InvalidMaceKeyException("No helper defined")); } else { return helper->getNthDigit(position, digitBits); } }
00368 void setNthDigit(uint32_t digit, int position, uint32_t digitBits = 4) throw(Exception) {
00369 if(helper==NULL) {
00370 throw(InvalidMaceKeyException("No helper defined"));
00371 } else {
00372 #ifdef MACE_KEY_USE_SHARED_PTR
00373 if(!helper.unique()) {
00374 helper = HelperPtr(helper->clone());
00375 }
00376 #endif
00377 helper->setNthDigit(digit, position, digitBits);
00378 }
00379 }
00380 int sharedPrefixLength(const MaceKey& key, uint32_t digitBits = 4) const throw(InvalidMaceKeyException)
00381 { if(helper==NULL) { throw(InvalidMaceKeyException("No helper defined")); } else { return helper->sharedPrefixLength(key, digitBits); } }
00382
00383 virtual void serialize(std::string& str) const {
00384 mace::serialize(str, &address_family);
00385 if(address_family != 0 && helper != NULL) {
00386 helper->serialize(str);
00387 }
00388 }
00389 virtual int deserialize(std::istream& in) throw(SerializationException) {
00390 int count = 0;
00391 count += mace::deserialize(in, &address_family);
00392 #ifndef MACE_KEY_USE_SHARED_PTR
00393 delete helper;
00394 #endif
00395 helper = HelperPtr();
00396 switch(address_family) {
00397 case UNDEFINED_ADDRESS: return count;
00398 case IPV4: helper = HelperPtr(new ipv4_MaceKey()); break;
00399 case SHA160: helper = HelperPtr(new sha160_MaceKey()); break;
00400 case SHA32: helper = HelperPtr(new sha32_MaceKey()); break;
00401 case STRING_ADDRESS: helper = HelperPtr(new string_MaceKey()); break;
00402 default: throw(InvalidMaceKeyException("Deserializing bad address family "+boost::lexical_cast<std::string>(address_family)+"!"));
00403 }
00404 count += helper->deserialize(in);
00405 return count;
00406 }
00407
00408 virtual void serializeXML_RPC(std::string& str) const throw(SerializationException) {
00409 StringMap m;
00410
00411 switch (address_family) {
00412 case IPV4:
00413 m["type"] = "ipv4";
00414 break;
00415 case STRING_ADDRESS:
00416 m["type"] = "str";
00417 break;
00418 default: throw(InvalidMaceKeyException("Serializing bad address family "+boost::lexical_cast<std::string>(address_family)+"!"));
00419 }
00420 mace::string s;
00421 if (helper) {
00422 helper->serializeXML_RPC(s);
00423 }
00424 m["addr"] = s;
00425 m.serializeXML_RPC(str);
00426 }
00427
00428 virtual int deserializeXML_RPC(std::istream& in) throw(SerializationException) {
00429 StringMap m;
00430 int r = m.deserializeXML_RPC(in);
00431 const StringMap::iterator i = m.find("type");
00432 if (i == m.end()) {
00433 throw InvalidMaceKeyException("deserialized MaceKey without type");
00434 }
00435 const StringMap::iterator ai = m.find("addr");
00436 if (ai == m.end()) {
00437 throw InvalidMaceKeyException("deserialized MaceKey without address");
00438 }
00439
00440 const mace::string& t = i->second;
00441 if (t == "ipv4") {
00442 address_family = IPV4;
00443 helper = HelperPtr(new ipv4_MaceKey());
00444 }
00445 else if (t == "str") {
00446 address_family = STRING_ADDRESS;
00447 helper = HelperPtr(new string_MaceKey());
00448 }
00449 else {
00450 throw InvalidMaceKeyException("deserialized MaceKey with unknown type: " + t);
00451 }
00452 std::istringstream is(ai->second);
00453 helper->deserializeXML_RPC(is);
00454 return r;
00455 }
00456
00457
00458 MaceKey() : helper(HelperPtr()), address_family(UNDEFINED_ADDRESS) {}
00459 virtual ~MaceKey() {
00460 #ifndef MACE_KEY_USE_SHARED_PTR
00461 delete helper;
00462 #endif
00463 }
00464
00465
00466 bool operator==(const MaceKey& right) const {
00467 if(helper == right.helper) { return true; }
00468 if(addressFamily() != right.addressFamily()) { return false; }
00469 else if(addressFamily() == 0) { return true; }
00470 else { try {return (*helper) == right;} catch (InvalidMaceKeyException e) { ASSERT(false); return false; } }
00471 }
00472
00473 bool operator!=(const MaceKey& right) const {
00474 return !((*this)==right);
00475 }
00476
00477 bool operator<(const MaceKey& right) const {
00478 if(addressFamily() != right.addressFamily()) { return addressFamily() < right.addressFamily(); }
00479 else if(addressFamily() == 0) { return false; }
00480 else { try {return (*helper) < right;} catch (InvalidMaceKeyException e) { ASSERT(false); return false; } }
00481 }
00482
00483 bool operator<=(const MaceKey& right) const {
00484 return ( (*this) < right || (*this) == right);
00485 }
00486 bool operator>(const MaceKey& right) const {
00487 return !( (*this) <= right );
00488 }
00489 bool operator>=(const MaceKey& right) const {
00490 return !( (*this) < right );
00491 }
00492
00493
00494 MaceKey& operator=(const MaceKey& right) {
00495 #ifndef MACE_KEY_USE_SHARED_PTR
00496 if(this != &right) {
00497 delete helper;
00498 if(right.helper == NULL)
00499 {
00500 helper = NULL;
00501 address_family = 0;
00502 }
00503 else
00504 {
00505 helper = right.helper->clone();
00506 address_family = right.address_family;
00507 }
00508 }
00509 #else
00510 helper = right.helper;
00511 address_family = right.address_family;
00512 #endif
00513 return *this;
00514 }
00515
00517 MaceKey(const MaceKey& right) : helper(), address_family(right.address_family) {
00518 #ifndef MACE_KEY_USE_SHARED_PTR
00519 if(right.helper != NULL)
00520 {
00521 helper = right.helper->clone();
00522 }
00523 #else
00524 helper = right.helper;
00525 #endif
00526 }
00527
00529 static const char* addressFamilyName(int addressFamily) {
00530 switch(addressFamily) {
00531 case UNDEFINED_ADDRESS: return "NONE";
00532 case IPV4: return "IPV4";
00533 case SHA160: return "SHA160";
00534 case SHA32: return "SHA32";
00535 case STRING_ADDRESS: return "STRING";
00536 default: return "HUH?";
00537 }
00538 }
00539
00541 static const char* addressFamilyVar(int addressFamily) {
00542 switch(addressFamily) {
00543 case UNDEFINED_ADDRESS: return "UNDEFINED_ADDRESS";
00544 case IPV4: return "IPV4";
00545 case SHA160: return "SHA160";
00546 case SHA32: return "SHA32";
00547 case STRING_ADDRESS: return "STRING_ADDRESS";
00548 default: return "HUH?";
00549 }
00550 }
00551
00552 private:
00553
00555 class MaceKey_exception : public MaceKey_interface_helper {
00556 protected:
00557 virtual uint32_t getNthDigitSafe(int position, uint32_t digitBits) const { abort(); }
00558 public:
00559
00560 virtual bool isUnroutable() const throw(InvalidMaceKeyException) { throw(InvalidMaceKeyException("Not Implemented For This MaceKey Family")); }
00561 virtual const MaceAddr& getMaceAddr() const throw(InvalidMaceKeyException) { throw(InvalidMaceKeyException("Not Implemented For This MaceKey Family")); }
00562
00563
00564 virtual int bitLength() const throw(InvalidMaceKeyException) { throw(InvalidMaceKeyException("Not Implemented For This MaceKey Family")); }
00565
00566
00567
00568 virtual uint32_t getNthDigit(int position, uint32_t digitBits = 4) const throw(Exception) { throw(InvalidMaceKeyException("Not Implemented For This MaceKey Family")); }
00569 virtual void setNthDigit(uint32_t digit, int position, uint32_t digitBits = 4) throw(Exception) { throw(InvalidMaceKeyException("Not Implemented For This MaceKey Family")); }
00570 virtual int sharedPrefixLength(const MaceKey& key, uint32_t digitBits = 4) const throw(Exception) { throw(InvalidMaceKeyException("Not Implemented For This MaceKey Family")); }
00571 };
00572
00574 class ipv4_MaceKey : public MaceKey_exception, virtual public PrintPrintable {
00575 protected:
00576 MaceAddr addr;
00577
00578 public:
00579 virtual bool isUnroutable() const throw(InvalidMaceKeyException) { return addr.isUnroutable(); }
00580 virtual bool isNullAddress() const { return addr.isNull(); }
00581 virtual std::string toHex() const { return Log::toHex(std::string((char*)&(addr.local.addr), sizeof(uint32_t))); }
00582 virtual std::string addressString() const;
00583 virtual void print(std::ostream& out) const;
00584 virtual bool isBitArrMaceKey() const { return false; }
00585 virtual size_t hashOf() const { return __gnu_cxx::hash<MaceAddr>()(addr); }
00586
00587
00588 virtual const MaceAddr& getMaceAddr() const throw(InvalidMaceKeyException) { return addr; }
00589
00590
00591 ipv4_MaceKey(): addr() { }
00592 ipv4_MaceKey(uint32_t ipaddr, uint16_t port = 0, uint32_t proxyIp = INADDR_NONE, uint16_t proxyPort = 0);
00593 ipv4_MaceKey(const MaceAddr& ma) {
00594 addr = ma;
00595 }
00596
00597 ipv4_MaceKey(const std::string& address);
00598 virtual ~ipv4_MaceKey() { }
00599
00600 virtual void serialize(std::string& str) const {
00601 mace::serialize(str, &addr);
00602 }
00603 virtual int deserialize(std::istream& in) throw(SerializationException) {
00604 return mace::deserialize(in, &addr);
00605 }
00606 virtual void serializeXML_RPC(std::string& str) const throw(SerializationException);
00607 virtual int deserializeXML_RPC(std::istream& in) throw(SerializationException);
00608
00609 bool operator==(const ipv4_MaceKey& right) const {
00610 return addr == right.addr;
00611 }
00612 bool operator==(const MaceKey& right) const {
00613 return addr == right.getMaceAddr();
00614 }
00615 bool operator<(const MaceKey& right) const {
00616 return addr < right.getMaceAddr();
00617 }
00618
00619 MaceKey_interface_helper* clone() const {
00620 ipv4_MaceKey* key = new ipv4_MaceKey();
00621 key->addr = addr;
00622 return key;
00623 }
00624 };
00625
00627 class string_MaceKey : public MaceKey_exception, virtual public PrintPrintable {
00628 protected:
00629 mace::string s;
00630
00631 public:
00632 virtual bool isNullAddress() const { return s == ""; }
00633 virtual std::string toHex() const { return Log::toHex(s); }
00634 virtual std::string addressString() const { return s; }
00635 virtual void print(std::ostream& out) const { out << "[" << s << "]"; }
00636 virtual bool isBitArrMaceKey() const { return false; }
00637 virtual size_t hashOf() const { return __gnu_cxx::hash<mace::string>()(s); }
00638
00639 string_MaceKey(): s() { }
00640 string_MaceKey(const mace::string& t) : s(t) { }
00641 virtual ~string_MaceKey() { }
00642
00643 virtual void serialize(std::string& str) const {
00644 mace::serialize(str, &s);
00645 }
00646 virtual int deserialize(std::istream& in) throw(SerializationException) {
00647 return mace::deserialize(in, &s);
00648 }
00649 virtual void serializeXML_RPC(std::string& str) const throw(SerializationException) {
00650 ASSERT(str.empty());
00651 str = s;
00652 }
00653 virtual int deserializeXML_RPC(std::istream& in) throw(SerializationException) {
00654 in >> s;
00655 ASSERT(in.eof());
00656 return s.size();
00657 }
00658 bool operator==(const string_MaceKey& right) const {
00659 return s == right.s;
00660 }
00661 bool operator==(const MaceKey& right) const {
00662 return s == right.addressString(false);
00663 }
00664 bool operator<(const MaceKey& right) const {
00665 return s < right.addressString(false);
00666 }
00667
00668 MaceKey_interface_helper* clone() const {
00669 string_MaceKey* key = new string_MaceKey();
00670 key->s = s;
00671 return key;
00672 }
00673 };
00674
00675
00676
00678 class bitarr_MaceKey : public MaceKey_exception {
00679 public:
00680
00681 bool isBitArrMaceKey() const { return true; }
00682 };
00683
00691 template<int SIZE>
00692 class intarr_MaceKey : public bitarr_MaceKey, virtual public PrintPrintable {
00693 protected:
00694 uint32_t data[SIZE];
00695 bool null;
00696
00697 void exceptDivides32(uint32_t digitBits) const throw(DigitBaseException) {
00698 switch(digitBits) {
00699 case 4:
00700 case 32:
00701 case 1:
00702 case 2:
00703 case 8:
00704 case 16: return;
00705 }
00706 throw(DigitBaseException("DigitBits does not divide 32"));
00707 }
00708 void exceptDivides32Bounds(int digit, uint32_t digitBits) const throw(DigitBaseException,IndexOutOfBoundsException) {
00709 if(digit < 0) {
00710 throw(IndexOutOfBoundsException("Digit is out of bounds (<= 0)"));
00711 }
00712 switch(digitBits) {
00713 case 4:
00714 if((uint32_t)digit < SIZE << 3) { return; }
00715 throw(IndexOutOfBoundsException("Digit is out of bounds"));
00716 case 32:
00717 if((uint32_t)digit < SIZE) { return; }
00718 throw(IndexOutOfBoundsException("Digit is out of bounds"));
00719 case 1:
00720 if((uint32_t)digit < SIZE << 5) { return; }
00721 throw(IndexOutOfBoundsException("Digit is out of bounds"));
00722 case 2:
00723 if((uint32_t)digit < SIZE << 4) { return; }
00724 throw(IndexOutOfBoundsException("Digit is out of bounds"));
00725 case 8:
00726 if((uint32_t)digit < SIZE << 2) { return; }
00727 throw(IndexOutOfBoundsException("Digit is out of bounds"));
00728 case 16:
00729 if((uint32_t)digit < SIZE << 1) { return; }
00730 throw(IndexOutOfBoundsException("Digit is out of bounds"));
00731 }
00732 throw(DigitBaseException("DigitBits does not divide 32"));
00733 }
00734
00735 int getArrPos(int position, uint32_t digitBits) const {
00736 switch(digitBits) {
00737 case 4: return position >> 3;
00738 case 32: return position;
00739 case 1: return position >> 5;
00740 case 2: return position >> 4;
00741 case 8: return position >> 2;
00742 case 16: return position >> 1;
00743 }
00744 abort();
00745 }
00746 uint32_t getDigitMask(int digitBits) const {
00747 switch(digitBits) {
00748 case 4: return 0xf;
00749 case 1: return 0x1;
00750 case 2: return 0x3;
00751 case 8: return 0xff;
00752 case 16: return 0xffff;
00753 case 32: return 0xffffffff;
00754 }
00755 abort();
00756 }
00757 int getShift(int position, uint32_t digitBits) const {
00758 switch(digitBits) {
00759 case 4: return (~(position & 0x7)) << 2;
00760 case 1: return (~(position & 0x1f));
00761 case 2: return (~(position & 0xf)) << 1;
00762 case 8: return (~(position & 0x3)) << 3;
00763 case 16: return (~(position & 0x1)) << 4;
00764 case 32: return 0;
00765 }
00766 ASSERT(0);
00767 }
00768 uint32_t getNthDigitSafe(int position, uint32_t digitBits) const {
00769 if(null) { return 0; }
00770 else if(digitBits == sizeof(int)*8) {
00771 return data[position];
00772 } else {
00773 return (data[getArrPos(position, digitBits)] >> getShift(position, digitBits)) & getDigitMask(digitBits);
00774 }
00775 }
00776
00777 public:
00778
00779 bool isNullAddress() const { return null; }
00780 void printHex(std::ostream& out) const {
00781 std::ios::fmtflags f(out.flags());
00782 out << std::hex << std::setfill('0');
00783 for(int i=0; i<SIZE; i++) {
00784 out << std::setw(sizeof(uint32_t)*2) << data[i];
00785 }
00786 out.flags(f);
00787 }
00788 std::string toHex() const {
00789 std::ostringstream out;
00790 printHex(out);
00791 return out.str();
00792 }
00793 std::string addressString() const { return toHex(); }
00794 void print(std::ostream& out) const { printHex(out); }
00795 virtual size_t hashOf() const {
00796 size_t hash = 0;
00797 for(int i = 0; i < SIZE; i++) {
00798 hash += __gnu_cxx::hash<uint32_t>()(data[i]);
00799 }
00800 return hash;
00801 }
00802
00803 int bitLength() const throw(InvalidMaceKeyException) { return SIZE * sizeof(uint32_t) * 8; }
00804 uint32_t getNthDigit(int position, uint32_t digitBits = 4) const throw(Exception) {
00805
00806
00807
00808 exceptDivides32Bounds(position, digitBits);
00809 return getNthDigitSafe(position, digitBits);
00810 }
00811 void setNthDigit(uint32_t digit, int position, uint32_t digitBits = 4) throw(Exception) {
00812
00813
00814
00815 exceptDivides32Bounds(position, digitBits);
00816 if(null) { throw(InvalidMaceKeyException("Mace Key Array is void")); }
00817 else if(digitBits == sizeof(int)*8) {
00818 data[position] = digit;
00819 } else {
00820 int arrPos = getArrPos(position, digitBits);
00821 int shift = getShift(position, digitBits);
00822 uint32_t DIGIT_MASK = getDigitMask(digitBits) << shift;
00823 digit &= (1<<digitBits)-1;
00824 data[arrPos] &= ~DIGIT_MASK;
00825 data[arrPos] |= (digit << shift);
00826 }
00827 }
00828 int sharedPrefixLength(const MaceKey& key, uint32_t digitBits = 4) const throw(Exception) {
00829
00830 exceptDivides32(digitBits);
00831 if(null) { return 0; }
00832 int common;
00833 unsigned myBitLength, hisBitLength;
00834 for(common = 0, myBitLength = this->bitLength(), hisBitLength = key.bitLength();
00835 myBitLength > 0 && hisBitLength > 0 &&
00836 getNthDigitSafe(common, digitBits) == key.getNthDigitSafe(common, digitBits);
00837 common++, myBitLength -= digitBits, hisBitLength -= digitBits
00838 );
00839 return common;
00840 }
00841
00842 virtual void serialize(std::string& str) const {
00843 mace::serialize(str, &null);
00844 if(null) {
00845 return;
00846 }
00847 for(int i = 0; i < SIZE; i++) {
00848 mace::serialize(str, (data+i));
00849 }
00850 }
00851
00852 virtual int deserialize(std::istream& in) throw(SerializationException) {
00853 int count = 0;
00854 count += mace::deserialize(in, &null);
00855 if(!null) {
00856 for(int i = 0; i < SIZE; i++) {
00857 count += mace::deserialize(in, (data+i));
00858 }
00859 }
00860 return count;
00861 }
00862
00863 bool operator==(const intarr_MaceKey& right) const {
00864 if(bitLength() != right.bitLength()) { return false; }
00865 for(int i = 0; i < SIZE; i++) {
00866 if(data[i] != right.data[i]) {
00867 return false;
00868 }
00869 }
00870 return true;
00871 }
00872
00873 bool operator==(const MaceKey& right) const {
00874 if(bitLength() != right.bitLength()) { return false; }
00875 return sharedPrefixLength(right, 32) == SIZE;
00876 }
00877
00878 bool operator<(const MaceKey& right) const {
00879 int common = sharedPrefixLength(right, 32);
00880 if(common == SIZE && bitLength() != right.bitLength()) {
00881 return true;
00882 } else if(common == SIZE) {
00883 return false;
00884 } else if(common*8 == right.bitLength()) {
00885 return false;
00886 }
00887 return data[common] < right.getNthDigit(common, 32);
00888 }
00889
00890 void setArr(const char carr[SIZE*4]) {
00891 uint32_t* arr = (uint32_t*)carr;
00892 if(arr == NULL) {
00893 null = true;
00894 }
00895 else {
00896 null = false;
00897 for(uint32_t i = 0; i < SIZE; i++) {
00898 data[i] = ntohl(arr[i]);
00899 }
00900 }
00901 }
00902
00903 void setArr(const uint32_t arr[SIZE]) {
00904 if(arr == NULL) {
00905 null = true;
00906 }
00907 else {
00908 null = false;
00909 memcpy(data, arr, SIZE*sizeof(uint32_t));
00910 }
00911 }
00912
00913 intarr_MaceKey(): null(true) { }
00914 intarr_MaceKey(const char carr[SIZE*4]): null(carr==NULL) {
00915 const uint32_t* arr = (uint32_t*)carr;
00916 if(arr != NULL) {
00917 for(uint32_t i = 0; i < SIZE; i++) {
00918 data[i] = ntohl(arr[i]);
00919 }
00920 }
00921 }
00922 intarr_MaceKey(const uint32_t arr[SIZE]): null(arr==NULL) {
00923 if(arr != NULL) {
00924 memcpy(data, arr, SIZE*sizeof(uint32_t));
00925 }
00926 }
00927 };
00928
00930 class sha160_MaceKey : public intarr_MaceKey<5> {
00931 public:
00932 MaceKey_interface_helper* clone() const {
00933 sha160_MaceKey* key = new sha160_MaceKey();
00934 memcpy(key->data, data, sizeof(uint32_t)*5);
00935 key->null = null;
00936 return key;
00937 }
00938
00939 sha160_MaceKey() : intarr_MaceKey<5>() {
00940
00941 }
00942 sha160_MaceKey(int toHash) {
00943 sha1 buf;
00944 HashUtil::computeSha1(toHash, buf);
00945
00946 setArr(buf.data());
00947 }
00948 sha160_MaceKey(const uint32_t arr[5]) : intarr_MaceKey<5>(arr) {
00949
00950 }
00951 sha160_MaceKey(const char arr[5*4]) : intarr_MaceKey<5>(arr) {
00952
00953 }
00954 sha160_MaceKey(const std::string& toHash) {
00955 sha1 buf;
00956 HashUtil::computeSha1(toHash, buf);
00957
00958 setArr(buf.data());
00959 }
00960 };
00961
00963 class sha32_MaceKey : public intarr_MaceKey<1> {
00964 public:
00965 MaceKey_interface_helper* clone() const {
00966 sha32_MaceKey* key = new sha32_MaceKey();
00967 memcpy(key->data, data, sizeof(uint32_t));
00968 key->null = null;
00969 return key;
00970 }
00971
00972 sha32_MaceKey() : intarr_MaceKey<1>() {}
00973 sha32_MaceKey(int toHash) { sha1 buf; HashUtil::computeSha1(toHash, buf); setArr((uint32_t*)buf.data()); }
00974 sha32_MaceKey(const uint32_t arr[1]) : intarr_MaceKey<1>(arr) { }
00975 sha32_MaceKey(const char arr[4]) : intarr_MaceKey<1>(arr) { }
00976 sha32_MaceKey(const std::string& toHash) { sha1 buf; HashUtil::computeSha1(toHash, buf); setArr(buf.data()); }
00977 };
00978
00979 public:
00980
00981 struct ipv4_type {};
00982 struct sha160_type {};
00983 struct sha32_type {};
00984 struct string_type {};
00985
00986
00988 MaceKey(ipv4_type t) : helper(new ipv4_MaceKey()), address_family(IPV4) { }
00990 MaceKey(ipv4_type t, uint32_t ipaddr, uint16_t port = 0, uint32_t pIp = INADDR_NONE, uint16_t pport = 0) : helper(new ipv4_MaceKey(ipaddr, port, pIp, pport)), address_family(IPV4) { }
00992 MaceKey(ipv4_type t, const std::string& addr) : helper(new ipv4_MaceKey(addr)), address_family(IPV4) { }
00994 MaceKey(ipv4_type t, const MaceAddr& maddr) : helper(new ipv4_MaceKey(maddr)), address_family(IPV4) { }
00995
00996
00997
00999 MaceKey(sha160_type t) : helper(new sha160_MaceKey()), address_family(SHA160) { }
01001 MaceKey(sha160_type t, int toHash) : helper(new sha160_MaceKey(toHash)), address_family(SHA160) { }
01003 MaceKey(sha160_type t, const uint32_t arr[5]) : helper(new sha160_MaceKey(arr)), address_family(SHA160) { }
01005 MaceKey(sha160_type t, const char arr[5*4]) : helper(new sha160_MaceKey(arr)), address_family(SHA160) { }
01007 MaceKey(sha160_type t, const std::string& toHash) : helper(new sha160_MaceKey(toHash)), address_family(SHA160) { }
01008
01009
01010
01012 MaceKey(sha32_type t) : helper(new sha32_MaceKey()), address_family(SHA32) { }
01014 MaceKey(sha32_type t, int toHash) : helper(new sha32_MaceKey(toHash)), address_family(SHA32) { }
01016 MaceKey(sha32_type t, const uint32_t arr[1]) : helper(new sha32_MaceKey(arr)), address_family(SHA32) { }
01018 MaceKey(sha32_type t, const char arr[4]) : helper(new sha32_MaceKey(arr)), address_family(SHA32) { }
01020 MaceKey(sha32_type t, const std::string& toHash) : helper(new sha32_MaceKey(toHash)), address_family(SHA32) { }
01021
01022
01023
01025 MaceKey(string_type t) : helper(new string_MaceKey()), address_family(STRING_ADDRESS) { }
01027 MaceKey(string_type t, const mace::string& u) : helper(new string_MaceKey(u)), address_family(STRING_ADDRESS) { }
01028
01030 MaceKey(const mace::string& a) {
01031 if(a.substr(0, 5) == "IPV4/") {
01032 address_family = IPV4;
01033 helper = HelperPtr(new ipv4_MaceKey(a.substr(5)));
01034 }
01035 else if(a.substr(0,7) == "SHA160/") {
01036 if(a.size() != 40+7) {
01037 throw(InvalidMaceKeyException("SHA160 Address must have 40 hexidecmal characters"));
01038 }
01039 address_family = SHA160;
01040 char arr[5*4];
01041 sscanf(a.c_str(), "SHA160/%8"PRIx32"%8"PRIx32"%8"PRIx32"%8"PRIx32"%8"PRIx32, (uint32_t *)(arr), (uint32_t *)(arr+4), (uint32_t *)(arr+8), (uint32_t *)(arr+12), (uint32_t *)(arr+16));
01042 *(((uint32_t*) arr)+0) = htonl(*(((uint32_t*) arr)+0));
01043 *(((uint32_t*) arr)+1) = htonl(*(((uint32_t*) arr)+1));
01044 *(((uint32_t*) arr)+2) = htonl(*(((uint32_t*) arr)+2));
01045 *(((uint32_t*) arr)+3) = htonl(*(((uint32_t*) arr)+3));
01046 *(((uint32_t*) arr)+4) = htonl(*(((uint32_t*) arr)+4));
01047 helper = HelperPtr(new sha160_MaceKey(arr));
01048 }
01049 else if(a.substr(0,6) == "SHA32/") {
01050 if(a.size() != 8+6) {
01051 throw(InvalidMaceKeyException("SHA32 Address must have 8 hexidecmal characters"));
01052 }
01053 address_family = SHA32;
01054 char arr[4];
01055 sscanf(a.c_str(), "SHA32/%8"PRIx32, (uint32_t *)(arr));
01056 *((uint32_t*) arr) = htonl(*((uint32_t*) arr));
01057 helper = HelperPtr(new sha32_MaceKey(arr));
01058 }
01059 else if(a.substr(0,7) == "STRING/") {
01060 address_family = STRING_ADDRESS;
01061 helper = HelperPtr(new string_MaceKey(a.substr(7)));
01062 }
01063 }
01064 };
01065
01066 const mace::MaceKey::ipv4_type ipv4 = mace::MaceKey::ipv4_type();
01067 const mace::MaceKey::sha160_type sha160 = mace::MaceKey::sha160_type();
01068 const mace::MaceKey::sha32_type sha32 = mace::MaceKey::sha32_type();
01069 const mace::MaceKey::string_type string_key = mace::MaceKey::string_type();
01070
01071
01076 class MaceKeyDiff : public PrintPrintable {
01077 friend MaceKey operator-(const MaceKey& to, const MaceKeyDiff& from) throw(InvalidMaceKeyException);
01078 friend MaceKey operator+(const MaceKey& to, const MaceKeyDiff& from) throw(InvalidMaceKeyException);
01079 public:
01080 enum type_t { ZERO, ___SIGNED, ___UNSIGNED, _INFINITY, _NEG_INFINITY };
01081 private:
01082 type_t type;
01083 int size;
01084 uint32_t* data;
01085 public:
01086 MaceKeyDiff() : type(ZERO), size(0), data(NULL) {}
01087 MaceKeyDiff(type_t t, int s = 0, uint32_t* d = NULL) : type(t), size(s), data(d) {}
01088 MaceKeyDiff(const MaceKeyDiff&);
01089 virtual ~MaceKeyDiff() { delete[] data; }
01090 void print(std::ostream&) const;
01098 int sign();
01100 bool isPositive() { return sign() > 0; }
01102 bool isNegative() { return sign() < 0; }
01104 bool isZero() { return sign() == 0; }
01113 MaceKeyDiff& abs();
01122 MaceKeyDiff& toSigned() {
01123 if(type == ___UNSIGNED) { type = ___SIGNED; }
01124 return *this;
01125 }
01136 MaceKeyDiff& toUnsigned() {
01137 if(type == ___SIGNED) { type = ___UNSIGNED; }
01138 return *this;
01139 }
01140 static MaceKeyDiff NEG_INF;
01141 static MaceKeyDiff INF;
01142 MaceKeyDiff& operator=(const MaceKeyDiff&);
01143 bool operator<(const MaceKeyDiff&) const;
01144 bool operator>(const MaceKeyDiff& right) const { return !(*this<=right); }
01145 bool operator==(const MaceKeyDiff&) const;
01146 bool operator<=(const MaceKeyDiff& right) const;
01147 bool operator>=(const MaceKeyDiff& right) const { return !(*this<right); }
01148 MaceKeyDiff operator>>(int bits) const;
01149 MaceKeyDiff operator+(const MaceKeyDiff&) const;
01150 MaceKeyDiff operator-(const MaceKeyDiff&) const;
01151 MaceKeyDiff operator+(uint32_t) const;
01152 MaceKeyDiff operator-(uint32_t) const;
01153 };
01154
01155 MaceKey operator+(const MaceKey&, const MaceKeyDiff&) throw(InvalidMaceKeyException);
01156 MaceKey operator-(const MaceKey&, const MaceKeyDiff&) throw(InvalidMaceKeyException);
01157 MaceKey operator+(const MaceKey&, uint32_t) throw(InvalidMaceKeyException);
01158 MaceKey operator-(const MaceKey&, uint32_t) throw(InvalidMaceKeyException);
01159 MaceKeyDiff operator-(const MaceKey&, const MaceKey&) throw(InvalidMaceKeyException);
01160 }
01161
01162
01163 namespace __gnu_cxx {
01164
01165 template<> struct hash<mace::MaceKey> {
01166 size_t operator()(const mace::MaceKey& x) const { return x.hashOf(); }
01167 };
01168
01169 template<> struct hash<mace::MaceKey*> {
01170 size_t operator()(const mace::MaceKey*& x) {
01171 return (x==NULL?0:x->hashOf());
01172 }
01173 };
01174
01175 }
01176
01177 #endif //__MACEKEY_H