00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 #include <oasys/util/OptParser.h>
00018 #include "bundling/BundleDaemon.h"
00019 #include "contacts/ContactManager.h"
00020 #include "IPAnnounce.h"
00021 #include "conv_layers/IPConvergenceLayerUtils.h"
00022 #include "conv_layers/TCPConvergenceLayer.h"
00023 #include "conv_layers/UDPConvergenceLayer.h"
00024
00025 namespace dtn {
00026
00027 IPAnnounce::IPAnnounce()
00028 : cl_addr_(INADDR_ANY), cl_port_(TCPConvergenceLayer::TCPCL_DEFAULT_PORT)
00029 {
00030 }
00031
00032 bool
00033 IPAnnounce::configure(const std::string& name, ConvergenceLayer* cl,
00034 int argc, const char* argv[])
00035 {
00036 if (cl == NULL) return false;
00037
00038 cl_ = cl;
00039 name_ = name;
00040 type_.assign(cl->name());
00041
00042
00043 if (strncmp(cl_->name(),"tcp",3) != 0 &&
00044 strncmp(cl_->name(),"udp",3) != 0)
00045 {
00046 log_err("ip announce does not support cl type %s",
00047 cl_->name());
00048 return false;
00049 }
00050
00051
00052 oasys::OptParser p;
00053 p.addopt(new oasys::InAddrOpt("cl_addr",&cl_addr_));
00054 p.addopt(new oasys::UInt16Opt("cl_port",&cl_port_));
00055 p.addopt(new oasys::UIntOpt("interval",&interval_));
00056
00057 const char* invalid;
00058 if (! p.parse(argc, argv, &invalid))
00059 {
00060 log_err("bad parameter %s",invalid);
00061 return false;
00062 }
00063
00064 if (interval_ == 0)
00065 {
00066 log_err("interval must be greater than 0");
00067 return false;
00068 }
00069
00070
00071 interval_ *= 1000;
00072
00073 oasys::StringBuffer buf("%s:%d",intoa(cl_addr_),cl_port_);
00074 local_.assign(buf.c_str());
00075 return true;
00076 }
00077
00078 size_t
00079 IPAnnounce::format_advertisement(u_char* bp, size_t len)
00080 {
00081 EndpointID local(BundleDaemon::instance()->local_eid());
00082 size_t length = FOUR_BYTE_ALIGN(local.length() + sizeof(DiscoveryHeader));
00083
00084 if (len <= length)
00085 return 0;
00086
00087 DiscoveryHeader* hdr = (DiscoveryHeader*) bp;
00088 memset(hdr,0,len);
00089
00090 hdr->cl_type = IPDiscovery::str_to_type(type().c_str());
00091 hdr->interval = interval_ / 100;
00092 hdr->length = htons(length);
00093 hdr->inet_addr = cl_addr_;
00094 hdr->inet_port = htons(cl_port_);
00095 hdr->name_len = htons(local.length());
00096
00097 memcpy(hdr->sender_name,local.c_str(),local.length());
00098 ::gettimeofday(&data_sent_,0);
00099 return length;
00100 }
00101
00102 void
00103 IPAnnounce::handle_neighbor_discovered(const std::string& nexthop,
00104 const EndpointID& remote_eid)
00105 {
00106 (void)remote_eid;
00107 in_addr_t remote_addr;
00108 u_int16_t remote_port;
00109
00110 if (! IPConvergenceLayerUtils::parse_nexthop(logpath_, nexthop.c_str(),
00111 &remote_addr, &remote_port))
00112 return;
00113
00114 ContactManager* cm = BundleDaemon::instance()->contactmgr();
00115 Link* link = cm->find_link_to(cl_, nexthop);
00116
00117 if (link != NULL)
00118 return;
00119
00120 if (type() == "tcp")
00121 {
00122 TCPConvergenceLayer* tcpcl =
00123 dynamic_cast<TCPConvergenceLayer*>(cl_);
00124 ASSERT(tcpcl != NULL);
00125
00126 TCPConvergenceLayer::TCPLinkParams* params =
00127 dynamic_cast<TCPConvergenceLayer::TCPLinkParams*>
00128 (tcpcl->new_link_params());
00129
00130 params->remote_addr_ = remote_addr;
00131 params->remote_port_ = remote_port;
00132
00133 CLConnection* conn = tcpcl->new_connection(params);
00134 conn->start();
00135 }
00136 else
00137 if (type() == "udp")
00138 {
00139 log_warn("UDP beacon received from %s but UDP not yet supported",
00140 nexthop.c_str());
00141 }
00142 else
00143 {
00144 PANIC("unsupported CL type in IPAnnounce: %s",type().c_str());
00145 }
00146 }
00147
00148 }