⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 counterflood.cc

📁 COPE the first practical network coding scheme which is developped on click
💻 CC
字号:
/* * CounterFlood.{cc,hh} -- DSR implementation * John Bicket * * Copyright (c) 1999-2001 Massachuscounterfloods Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, subject to the conditions * listed in the Click LICENSE file. These conditions include: you must * preserve this copyright notice, and you cannot mention the copyright * holders in advertising related to the Software without their permission. * The Software is provided WITHOUT ANY WARRANTY, EXPRESS OR IMPLIED. This * notice is a summary of the Click LICENSE file; the license in that file is * legally binding. */#include <click/config.h>#include "counterflood.hh"#include <click/ipaddress.hh>#include <click/confparse.hh>#include <click/error.hh>#include <click/glue.hh>#include <click/straccum.hh>#include <clicknet/ether.h>#include "srpacket.hh"CLICK_DECLSCounterFlood::CounterFlood()  :  Element(2,2),     _en(),     _et(0),     _packets_originated(0),     _packets_tx(0),     _packets_rx(0){  static unsigned char bcast_addr[] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };  _bcast = EtherAddress(bcast_addr);}CounterFlood::~CounterFlood(){}intCounterFlood::configure (Vector<String> &conf, ErrorHandler *errh){  int ret;  _debug = false;  _count = 1;  _max_delay_ms = 750;  _history = 100;  ret = cp_va_parse(conf, this, errh,                    cpKeywords,		    "ETHTYPE", cpUnsigned, "Ethernet encapsulation type", &_et,                    "IP", cpIPAddress, "IP address", &_ip,                    "BCAST_IP", cpIPAddress, "IP address", &_bcast_ip,		    "ETH", cpEtherAddress, "EtherAddress", &_en,		    "COUNT", cpInteger, "Count", &_count,		    "MAX_DELAY_MS", cpUnsigned, "Max Delay (ms)", &_max_delay_ms,		    /* below not required */		    "DEBUG", cpBool, "Debug", &_debug,		    "HISTORY", cpUnsigned, "history", &_history,                    cpEnd);  if (!_et)     return errh->error("ETHTYPE not specified");  if (!_ip)     return errh->error("IP not specified");  if (!_bcast_ip)     return errh->error("BCAST_IP not specified");  if (!_en)     return errh->error("ETH not specified");  return ret;}intCounterFlood::initialize (ErrorHandler *){  return 0;}voidCounterFlood::forward(Broadcast *bcast) {  if (_debug) {    click_chatter("%{element} seq %d my_expected_rx %d sending\n",		  this,		  bcast->_seq		  );  }  if (_debug) {    click_chatter("%{element} forwarding seq %d\n",		  this,		  bcast->_seq);  }  Packet *p_in = bcast->_p;  if (!p_in) {    return;  }  click_ether *eh_in = (click_ether *) p_in->data();  struct srpacket *pk_in = (struct srpacket *) (eh_in+1);  int hops = 1;  int len = 0;  if (bcast->_originated) {    hops = 1;    len = srpacket::len_with_data(hops, p_in->length());  } else {    hops = pk_in->num_links() + 1;    len = srpacket::len_with_data(hops, pk_in->data_len());  }  WritablePacket *p = Packet::make(len + sizeof(click_ether));  if (p == 0)    return;  click_ether *eh = (click_ether *) p->data();  struct srpacket *pk = (struct srpacket *) (eh+1);  memset(pk, '\0', len);  pk->_version = _sr_version;  pk->_type = PT_DATA;  pk->_flags = 0;  pk->_qdst = _bcast_ip;  pk->set_num_links(hops);  for (int x = 0; x < hops; x++) {    pk->set_link_node(x, pk_in->get_link_node(x));  }  pk->set_link_node(hops,_ip);  pk->set_next(hops);  pk->set_seq(bcast->_seq);  uint32_t link_seq = random();  pk->set_seq2(link_seq);  bcast->_sent_seq.push_back(link_seq);  if (bcast->_originated) {    memcpy(pk->data(), p_in->data(), p_in->length());    pk->set_data_len(p_in->length());  } else {    memcpy(pk->data(), pk_in->data(), pk_in->data_len());    pk->set_data_len(pk_in->data_len());  }  eh->ether_type = htons(_et);  memcpy(eh->ether_shost, _en.data(), 6);  memset(eh->ether_dhost, 0xff, 6);  output(0).push(p);  _packets_tx++;    bcast->_actually_sent = true;  bcast->_rx_from.push_back(_ip);  bcast->_rx_from_seq.push_back(link_seq);  }voidCounterFlood::forward_hook() {  Timestamp now = Timestamp::now();  for (int x = 0; x < _packets.size(); x++) {    if (now > _packets[x]._to_send) {      /* this timer has expired */      if (!_packets[x]._forwarded && 	  (!_count || _packets[x]._num_rx < _count)) {	/* we haven't forwarded this packet yet */	forward(&_packets[x]);      }      _packets[x]._forwarded = true;    }  }}voidCounterFlood::trim_packets() {  /* only keep track of the last _max_packets */  while ((_packets.size() > _history)) {    /* unschedule and remove packet*/    if (_debug) {      click_chatter("%{element} removing seq %d\n",		    this,		    _packets[0]._seq);    }    _packets[0].del_timer();    if (_packets[0]._p != 0) {      _packets[0]._p->kill();    }    _packets.pop_front();  }}voidCounterFlood::push(int port, Packet *p_in){  Timestamp now = Timestamp::now();    if (port == 1) {    _packets_originated++;    /* from me */    int index = _packets.size();    _packets.push_back(Broadcast());    _packets[index]._seq = random();    _packets[index]._originated = true;    _packets[index]._p = p_in->clone();    _packets[index]._num_rx = 0;    _packets[index]._first_rx = now;    _packets[index]._forwarded = true;    _packets[index]._actually_sent = false;    _packets[index].t = NULL;    _packets[index]._to_send = now;    if (_debug) {      click_chatter("%{element} original packet %d, seq %d\n",		    this,		    _packets_originated,		    _packets[index]._seq);    }    p_in->kill();    forward(&_packets[index]);  } else {    _packets_rx++;    click_ether *eh = (click_ether *) p_in->data();    struct srpacket *pk = (struct srpacket *) (eh+1);        uint32_t seq = pk->seq();    uint32_t link_seq = pk->seq2();    int index = -1;    for (int x = 0; x < _packets.size(); x++) {      if (_packets[x]._seq == seq) {	index = x;	break;      }    }    IPAddress src = pk->get_link_node(pk->num_links() - 1);    if (index == -1) {      /* haven't seen this packet before */      index = _packets.size();      _packets.push_back(Broadcast());      _packets[index]._seq = seq;      _packets[index]._originated = false;      _packets[index]._p = p_in->clone();      _packets[index]._num_rx = 0;      _packets[index]._first_rx = now;      _packets[index]._forwarded = false;      _packets[index]._actually_sent = false;      _packets[index].t = NULL;      _packets[index]._rx_from.push_back(src);      _packets[index]._rx_from_seq.push_back(link_seq);      /* schedule timer */      int delay_time = (random() % _max_delay_ms) + 1;      sr_assert(delay_time > 0);            _packets[index]._to_send = now + Timestamp::make_msec(delay_time);      _packets[index].t = new Timer(static_forward_hook, (void *) this);      _packets[index].t->initialize(this);      _packets[index].t->schedule_at(_packets[index]._to_send);      if (_debug) {	click_chatter("%{element} first_rx seq %d src %s",		      this,		      _packets[index]._seq,		      src.s().cc());      }      /* finally, clone the packet and push it out */      output(1).push(p_in);    } else {      if (_debug) {	click_chatter("%{element} extra_rx seq %d src %s",		      this,		      _packets[index]._seq,		      src.s().cc());      }      /* we've seen this packet before */      p_in->kill();    }    _packets[index]._num_rx++;    _packets[index]._rx_from.push_back(src);    _packets[index]._rx_from_seq.push_back(link_seq);        }  trim_packets();}StringCounterFlood::print_packets(){  StringAccum sa;  for (int x = 0; x < _packets.size(); x++) {    sa << "ip " << _ip;    sa << " seq " << _packets[x]._seq;    sa << " originated " << _packets[x]._originated;    sa << " actual_first_rx true";    sa << " num_rx " << _packets[x]._num_rx;    sa << " num_tx " << (int) _packets[x]._actually_sent;    sa << " sent_seqs ";    for (int y = 0; y < _packets[x]._sent_seq.size(); y++) {      sa << _packets[x]._sent_seq[y] << " ";    }    sa << " rx_from ";     for (int y = 0; y < _packets[x]._rx_from.size(); y++) {      sa << _packets[x]._rx_from[y] << " " << _packets[x]._rx_from_seq[y] << " ";    }    sa << "\n";  }  return sa.take_string();}StringCounterFlood::read_param(Element *e, void *vparam){  CounterFlood *f = (CounterFlood *) e;  switch ((int)vparam) {  case 0:			    return cp_unparse_bool(f->_debug) + "\n";  case 1:			    return String(f->_history) + "\n";  case 2:			    return String(f->_count) + "\n";  case 3:			    return String(f->_max_delay_ms) + "\n";  case 4:    return f->print_packets();  default:    return "";  }}int CounterFlood::write_param(const String &in_s, Element *e, void *vparam,			 ErrorHandler *errh){  CounterFlood *f = (CounterFlood *)e;  String s = cp_uncomment(in_s);  switch((int)vparam) {  case 0: {    //debug    bool debug;    if (!cp_bool(s, &debug))       return errh->error("debug parameter must be boolean");    f->_debug = debug;    break;  }  case 1: {			// history    int history;    if (!cp_integer(s, &history))      return errh->error("history parameter must be integer");    f->_history = history;    break;  }  case 2: {			// count    int count;    if (!cp_integer(s, &count))      return errh->error("count parameter must be integer");    f->_count = count;    break;  }  case 3: {			// max_delay_ms    int max_delay_ms;    if (!cp_integer(s, &max_delay_ms))      return errh->error("max_delay_ms parameter must be integer");    f->_max_delay_ms = max_delay_ms;    break;  }  case 5: {	// clear    f->_packets.clear();    break;  }  }  return 0;}voidCounterFlood::add_handlers(){  add_read_handler("debug", read_param, (void *) 0);  add_read_handler("history", read_param, (void *) 1);  add_read_handler("count", read_param, (void *) 2);  add_read_handler("max_delay_ms", read_param, (void *) 3);  add_read_handler("packets", read_param, (void *) 4);  add_write_handler("debug", write_param, (void *) 0);  add_write_handler("history", write_param, (void *) 1);  add_write_handler("count", write_param, (void *) 2);  add_write_handler("max_delay_ms", write_param , (void *) 3);  add_write_handler("clear", write_param, (void *) 5);}// generate Vector template instance#include <click/vector.cc>#include <click/dequeue.cc>#if EXPLICIT_TEMPLATE_INSTANCEStemplate class Vector<CounterFlood::Broadcast>;#endifCLICK_ENDDECLSEXPORT_ELEMENT(CounterFlood)

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -