00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 #ifndef _DTN_PROPHET_
00018 #define _DTN_PROPHET_
00019
00020 #include <sys/types.h>
00021 #include <oasys/thread/SpinLock.h>
00022 #include <oasys/util/URL.h>
00023 #include "naming/EndpointID.h"
00024
00030 namespace dtn {
00031
00032 struct Prophet {
00033
00037 static const double DEFAULT_P_ENCOUNTER = 0.75;
00038
00042 static const double DEFAULT_BETA = 0.25;
00043
00047 static const double DEFAULT_GAMMA = 0.99;
00048
00053 static const u_int DEFAULT_KAPPA = 100;
00054
00055
00056
00060 static const u_int8_t HELLO_INTERVAL = 255;
00061
00065 static const u_int HELLO_DEAD = 20;
00066
00070 static const u_int DEFAULT_NUM_F_MAX = 5;
00071
00075 static const u_int DEFAULT_NUM_F_MIN = 3;
00076
00080 static const u_int AGE_PERIOD = 1800;
00081
00085 static const u_int8_t PROPHET_VERSION = 0x01;
00086
00091 struct ProphetHeader {
00092 u_int8_t version;
00093 u_int8_t flags;
00094
00124 u_int8_t result;
00143 u_int8_t code;
00159 u_int16_t sender_instance;
00174 u_int16_t receiver_instance;
00181 u_int32_t transaction_id;
00190 u_int16_t submessage_flag:1;
00199 u_int16_t submessage_num:15;
00205 u_int16_t length;
00206 } __attribute__((packed));
00207
00212 typedef enum {
00213 UnknownResult = 0x0,
00214 NoSuccessAck = 0x1,
00215 AckAll = 0x2,
00216 Success = 0x3,
00217 Failure = 0x4,
00218 ReturnReceipt = 0x5
00219 } header_result_t;
00220
00221 typedef enum {
00222 UNKNOWN_TLV = 0x00,
00223 HELLO_TLV = 0x01,
00224 ERROR_TLV = 0x02,
00225 RIBD_TLV = 0xA0,
00226 RIB_TLV = 0xA1,
00227 BUNDLE_TLV = 0XA2,
00228 } prophet_tlv_t;
00229
00247 struct HelloTLVHeader {
00248 u_int8_t type;
00249 u_int8_t unused__:5;
00259 u_int8_t HF:3;
00264 u_int16_t length;
00272 u_int8_t timer;
00280 u_int8_t name_length;
00286 u_char sender_name[0];
00287 } __attribute__((packed));
00288
00293 typedef enum {
00294 HF_UNKNOWN = 0x0,
00295 SYN = 0x1,
00296 SYNACK = 0x2,
00297 ACK = 0x3,
00298 RSTACK = 0x4
00299 } hello_hf_t;
00300
00305 struct ErrorTLVHeader {
00306 u_int8_t type;
00307 u_int8_t flags;
00308
00312 u_int16_t length;
00313 } __attribute__((packed));
00314
00325 struct RIBDTLVHeader {
00326 u_int8_t type;
00327 u_int8_t flags;
00328
00332 u_int16_t length;
00333 u_int16_t entry_count;
00334 u_int16_t unused__;
00335 } __attribute__((packed));
00336
00341 struct RoutingAddressString {
00349 u_int16_t string_id;
00350 u_int8_t length;
00351 u_int8_t unused__;
00352 u_char ra_string[0];
00353 } __attribute__((packed));
00354
00364 struct RIBTLVHeader {
00365 u_int8_t type;
00366
00379 u_int8_t flags;
00384 u_int16_t length;
00385 u_int16_t rib_string_count;
00386 u_int16_t unused__;
00387 } __attribute__((packed));
00388
00393 typedef enum {
00394 RELAY_NODE = 1 << 0,
00395 CUSTODY_NODE = 1 << 1,
00396 INTERNET_GW_NODE = 1 << 2
00397 } rib_header_flag_t;
00398
00403 struct RIBEntry {
00407 u_int16_t string_id;
00414 u_int8_t pvalue;
00427 u_int8_t flags;
00428 } __attribute__((packed));
00429
00448 struct BundleOfferTLVHeader {
00449 u_int8_t type;
00450 u_int8_t flags;
00451
00455 u_int16_t length;
00459 u_int16_t offer_count;
00460 u_int16_t unused__;
00461 } __attribute__((packed));
00462
00467 struct BundleOfferEntry {
00472 u_int16_t dest_string_id;
00497 u_int8_t b_flags;
00498 u_int8_t unused__;
00499 u_int32_t creation_timestamp;
00500 } __attribute__((packed));
00501
00502 typedef struct BundleOfferTLVHeader BundleResponseTLVHeader;
00503 typedef struct BundleOfferEntry BundleResponseEntry;
00504
00509 typedef enum {
00510 CUSTODY_OFFERED = 1 << 0,
00511 PROPHET_ACK = 1 << 7
00512 } bundle_offer_flags_t;
00513
00518 typedef enum {
00519 CUSTODY_ACCEPTED = 1 << 0,
00520 BUNDLE_ACCEPTED = 1 << 1
00521 } bundle_response_flags_t;
00522
00527 typedef enum {
00528 INVALID_FS = 0,
00529 GRTR,
00530 GTMX,
00531 GRTR_PLUS,
00532 GTMX_PLUS,
00533 GRTR_SORT,
00534 GRTR_MAX
00535 } fwd_strategy_t;
00536
00541 typedef enum {
00542 INVALID_QP = 0,
00543 FIFO,
00544 MOFO,
00545 MOPR,
00546 LINEAR_MOPR,
00547 SHLI,
00548 LEPR
00549 } q_policy_t;
00550
00555 class UniqueID {
00556 public:
00557 static u_int32_t tid() {
00558 return instance()->get_tid();
00559 }
00560
00561 static u_int16_t instance_id() {
00562 return instance()->get_instance_id();
00563 }
00564
00565 static UniqueID* instance() {
00566 if (instance_ == NULL)
00567 PANIC("UniqueID::init not called yet");
00568 return instance_;
00569 }
00570
00571 static void init() {
00572 if (instance_ != NULL)
00573 PANIC("UniqueID already initialized");
00574 instance_ = new UniqueID();
00575 }
00576 protected:
00577 UniqueID() :
00578 tid_(1),
00579 iid_(0),
00580 lock_(new oasys::SpinLock()) {}
00581 ~UniqueID() { delete lock_; }
00582
00583 u_int32_t get_tid() {
00584 oasys::ScopeLock l(lock_,"Prophet::UniqueID::tid()");
00585 return tid_++;
00586 }
00587 u_int16_t get_instance_id() {
00588 oasys::ScopeLock l(lock_,"Prophet::UniqueID::instance()");
00589 iid_++;
00590
00591 if (iid_ == 0)
00592 iid_++;
00593 return iid_;
00594 }
00595 u_int32_t tid_;
00596 u_int16_t iid_;
00597 oasys::SpinLock* lock_;
00598 static UniqueID* instance_;
00599 };
00600
00601 static const size_t ProphetHeaderSize =
00602 sizeof(struct ProphetHeader);
00603
00604 static const size_t HelloTLVHeaderSize =
00605 sizeof(struct HelloTLVHeader);
00606
00607 static const size_t ErrorTLVHeaderSize =
00608 sizeof(struct ErrorTLVHeader);
00609
00610 static const size_t RIBDTLVHeaderSize =
00611 sizeof(struct RIBDTLVHeader);
00612
00613 static const size_t RoutingAddressStringSize =
00614 sizeof(struct RoutingAddressString);
00615
00616 static const size_t RIBTLVHeaderSize =
00617 sizeof(struct RIBTLVHeader);
00618
00619 static const size_t RIBEntrySize =
00620 sizeof(struct RIBEntry);
00621
00622 static const size_t BundleOfferTLVHeaderSize =
00623 sizeof(struct BundleOfferTLVHeader);
00624
00625 static const size_t BundleResponseTLVHeaderSize =
00626 BundleOfferTLVHeaderSize;
00627
00628 static const size_t BundleOfferEntrySize =
00629 sizeof(struct BundleOfferEntry);
00630
00631 static const size_t BundleReponseEntrySize =
00632 BundleOfferEntrySize;
00633
00634 static const char*
00635 tlv_to_str(Prophet::prophet_tlv_t tlv)
00636 {
00637 switch(tlv) {
00638 case Prophet::HELLO_TLV: return "HELLO_TLV";
00639 case Prophet::RIBD_TLV: return "RIBD_TLV";
00640 case Prophet::RIB_TLV: return "RIB_TLV";
00641 case Prophet::BUNDLE_TLV: return "BUNDLE_TLV";
00642 case Prophet::ERROR_TLV:
00643 case Prophet::UNKNOWN_TLV:
00644 default:
00645 PANIC("Unimplemented prophet typecode %u",tlv);
00646 }
00647 }
00648
00649 static const char*
00650 result_to_str(Prophet::header_result_t hr)
00651 {
00652 switch(hr) {
00653 case Prophet::NoSuccessAck: return "NoSuccessAck";
00654 case Prophet::AckAll: return "AckAll";
00655 case Prophet::Success: return "Success";
00656 case Prophet::Failure: return "Failure";
00657 case Prophet::ReturnReceipt: return "ReturnReceipt";
00658 case Prophet::UnknownResult:
00659 default:
00660 PANIC("Undefined prophet header result: %d",hr);
00661 }
00662 }
00663
00664 static const char*
00665 hf_to_str(Prophet::hello_hf_t hf)
00666 {
00667 switch(hf) {
00668 case Prophet::SYN: return "SYN";
00669 case Prophet::SYNACK: return "SYNACK";
00670 case Prophet::ACK: return "ACK";
00671 case Prophet::RSTACK: return "RSTACK";
00672 case Prophet::HF_UNKNOWN:
00673 default:
00674 PANIC("Unrecognized prophet HF code %u",hf);
00675 }
00676 }
00677
00678 static const char*
00679 fs_to_str(Prophet::fwd_strategy_t fs)
00680 {
00681 switch(fs) {
00682 #define CASE(_f_s) case Prophet::_f_s: return # _f_s
00683 CASE(GRTR);
00684 CASE(GTMX);
00685 CASE(GRTR_PLUS);
00686 CASE(GTMX_PLUS);
00687 CASE(GRTR_SORT);
00688 CASE(GRTR_MAX);
00689 #undef CASE
00690 default: return "Unknown forwarding strategy";
00691 }
00692 }
00693
00694 static const char*
00695 qp_to_str(Prophet::q_policy_t qp)
00696 {
00697 switch(qp) {
00698 #define CASE(_q_p) case Prophet::_q_p: return # _q_p
00699 CASE(FIFO);
00700 CASE(MOFO);
00701 CASE(MOPR);
00702 CASE(LINEAR_MOPR);
00703 CASE(SHLI);
00704 CASE(LEPR);
00705 #undef CASE
00706 default: return "Unknown queuing policy";
00707 }
00708 }
00709
00713 static EndpointID eid_to_routeid(const EndpointID& eid)
00714 {
00715 oasys::URL eid_url(eid.str());
00716 EndpointID route;
00717 route.assign(eid.scheme_str(),"//" + eid_url.host_);
00718 return route;
00719 }
00720
00724 static EndpointIDPattern eid_to_route(const EndpointID& eid)
00725 {
00726 EndpointID route = eid_to_routeid(eid);
00727 route.assign(eid.str() + "/*");
00728 return route;
00729 }
00730
00731 };
00732
00733 };
00734
00735 #endif // _DTN_PROPHET_