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

📄 aggregateipaddrpair.cc

📁 COPE the first practical network coding scheme which is developped on click
💻 CC
字号:
/* * aggregateipflows.{cc,hh} -- set aggregate annotation based on IP addr pair * Eddie Kohler * * Copyright (c) 2001-2003 International Computer Science Institute * Copyright (c) 2005 Regents of the University of California * * 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 "aggregateipaddrpair.hh"#include <click/error.hh>#include <click/hashmap.hh>#include <click/straccum.hh>#include <click/confparse.hh>#include <clicknet/ip.h>#include <clicknet/tcp.h>#include <clicknet/udp.h>#include <clicknet/icmp.h>#include <click/packet_anno.hh>#include <click/handlercall.hh>CLICK_DECLS#define SEC_OLDER(s1, s2)	((int)(s1 - s2) < 0)static inline booloperator==(const AggregateIPAddrPair::HostPair &a, const AggregateIPAddrPair::HostPair &b){    return a.a == b.a && a.b == b.b;}static inline uint32_thashcode(const AggregateIPAddrPair::HostPair &a){    return (a.a << 12) + a.b + ((a.a >> 20) & 0x1F);}// actual AggregateIPAddrPair operationsAggregateIPAddrPair::AggregateIPAddrPair()    : Element(1, 1){}AggregateIPAddrPair::~AggregateIPAddrPair(){}void *AggregateIPAddrPair::cast(const char *n){    if (strcmp(n, "AggregateNotifier") == 0)	return (AggregateNotifier *)this;    else if (strcmp(n, "AggregateIPAddrPair") == 0)	return (Element *)this;    else	return Element::cast(n);}intAggregateIPAddrPair::configure(Vector<String> &conf, ErrorHandler *errh){    _timeout = 0;    _gc_interval = 20 * 60;        if (cp_va_parse(conf, this, errh,		    cpKeywords,		    "TIMEOUT", cpSeconds, "timeout for address pairs", &_timeout,		    "REAP", cpSeconds, "garbage collection interval", &_gc_interval,		    cpEnd) < 0)	return -1;        return 0;}intAggregateIPAddrPair::initialize(ErrorHandler *errh){    _next = 1;    _active_sec = _gc_sec = 0;    _timestamp_warning = false;        return 0;}inline voidAggregateIPAddrPair::packet_emit_hook(const Packet *p, const click_ip *iph, FlowInfo *finfo){    // check whether this indicates the flow is over    if (iph->ip_p == IP_PROTO_TCP && IP_FIRSTFRAG(iph)	/* 3.Feb.2004 - NLANR dumps do not contain full TCP headers! So relax	   the following length check to just make sure the flags are	   there. */	&& p->transport_length() >= 14	&& PAINT_ANNO(p) < 2) {	// ignore ICMP errors	if (p->tcp_header()->th_flags & TH_RST)	    finfo->_flow_over = 3;	else if (p->tcp_header()->th_flags & TH_FIN)	    finfo->_flow_over |= (1 << PAINT_ANNO(p));	else if (p->tcp_header()->th_flags & TH_SYN)	    finfo->_flow_over = 0;    }    // count packets    if (stats() && PAINT_ANNO(p) < 2) {	StatFlowInfo *sinfo = static_cast<StatFlowInfo *>(finfo);	sinfo->_packets[PAINT_ANNO(p)]++;    }}voidAggregateIPAddrPair::assign_aggregate(Map &table, HostPairInfo *hpinfo, int emit_before_sec){    Packet *first = hpinfo->_fragment_head;    uint16_t want_ip_id = good_ip_header(first)->ip_id;    // find FlowInfo    FlowInfo *finfo = 0;    if (AGGREGATE_ANNO(first)) {	for (finfo = hpinfo->_flows; finfo && finfo->_aggregate != AGGREGATE_ANNO(first); finfo = finfo->_next)	    /* nada */;    } else {	for (Packet *p = first; !finfo && p; p = p->next()) {	    const click_ip *iph = good_ip_header(p);	    if (iph->ip_id == want_ip_id) {		if (IP_FIRSTFRAG(iph)) {		    uint32_t ports = *(reinterpret_cast<const uint32_t *>(reinterpret_cast<const uint8_t *>(iph) + (iph->ip_hl << 2)));		    if (PAINT_ANNO(p) & 1)			ports = flip_ports(ports);		    finfo = find_flow_info(table, hpinfo, ports, PAINT_ANNO(p) & 1, p);		}	    }	}    }    // if no FlowInfo found, delete packet    if (!finfo) {	hpinfo->_fragment_head = first->next();	first->kill();	return;    }    // emit packets at the beginning of the list that have the same IP ID    const click_ip *iph;    while (first && (iph = good_ip_header(first)) && iph->ip_id == want_ip_id	   && (SEC_OLDER(first->timestamp_anno().sec(), emit_before_sec)	       || !IP_ISFRAG(iph))) {	Packet *p = first;	hpinfo->_fragment_head = first = p->next();	p->set_next(0);	bool was_fragment = IP_ISFRAG(iph);	SET_AGGREGATE_ANNO(p, finfo->aggregate());	// actually emit packet	if (finfo->reverse())	    SET_PAINT_ANNO(p, PAINT_ANNO(p) ^ 1);	finfo->_last_timestamp = p->timestamp_anno();	packet_emit_hook(p, iph, finfo);		output(0).push(p);	// if not a fragment, know we don't have more fragments	if (!was_fragment)	    return;    }        // assign aggregate annotation to other packets with the same IP ID    for (Packet *p = first; p; p = p->next())	if (good_ip_header(p)->ip_id == want_ip_id)	    SET_AGGREGATE_ANNO(p, finfo->aggregate());}voidAggregateIPAddrPair::reap_map(Map &table, uint32_t timeout, uint32_t done_timeout){    timeout = _active_sec - timeout;    done_timeout = _active_sec - done_timeout;    int frag_timeout = _active_sec - _fragment_timeout;    // free completed flows and emit fragments    for (Map::iterator iter = table.begin(); iter; iter++) {	HostPairInfo *hpinfo = &iter.value();	// fragments	while (hpinfo->_fragment_head && hpinfo->_fragment_head->timestamp_anno().sec() < frag_timeout)	    assign_aggregate(table, hpinfo, frag_timeout);	// can't delete any flows if there are fragments	if (hpinfo->_fragment_head)	    continue;	// completed flows	FlowInfo **pprev = &hpinfo->_flows;	FlowInfo *f = *pprev;	while (f) {	    // circular comparison	    if (SEC_OLDER(f->_last_timestamp.sec(), (f->_flow_over == 3 ? done_timeout : timeout))) {		notify(f->_aggregate, AggregateListener::DELETE_AGG, 0);		*pprev = f->_next;		delete_flowinfo(iter.key(), f);	    } else		pprev = &f->_next;	    f = *pprev;	}	// XXX never free host pairs    }}voidAggregateIPAddrPair::reap(){    if (_gc_sec) {	reap_map(_tcp_map, _tcp_timeout, _tcp_done_timeout);	reap_map(_udp_map, _udp_timeout, _udp_timeout);    }    _gc_sec = _active_sec + _gc_interval;}// XXX timing when fragments are merged back in?Packet *AggregateIPAddrPair::simple_action(Packet *p){    const click_ip *iph = p->ip_header();    if (iph) {	HostPair hosts(iph->ip_src.s_addr, iph->ip_dst.s_addr);	int paint = 0;	if (hosts.a != iph->ip_src.s_addr)	    paint ^= 1;	HostPairInfo *hpinfo = m.findp_force(hosts);	if (!hpinfo->aggregate) {	    hpinfo->aggregate = next | paint;	    if (++next == 0)		++next;	}	if (_timeout > 0) {	    // assign timestamp if no timestamp given	    if (!p->timestamp_anno()) {		if (!_timestamp_warning) {		    click_chatter("%{element}: warning: packet received without timestamp", this);		    _timestamp_warning = true;		}		p->timestamp_anno().set_now();	    }	    hpinfo->timestamp = p->timestamp_anno();	    _active_sec = p->timestamp_anno().sec();	    if (_active_sec > _gc_sec)		reap();	}	SET_AGGREGATE_ANNO(p, hpinfo->aggregate ^ paint);	return p;	    } else	checked_output_push(1, p);}enum { H_CLEAR };intAggregateIPAddrPair::write_handler(const String &, Element *e, void *thunk, ErrorHandler *){    AggregateIPAddrPair *af = static_cast<AggregateIPAddrPair *>(e);    switch ((intptr_t)thunk) {      case H_CLEAR: {	  int active_sec = af->_active_sec, gc_sec = af->_gc_sec;	  af->_active_sec = af->_gc_sec = 0x7FFFFFFF;	  af->reap();	  af->_active_sec = active_sec, af->_gc_sec = gc_sec;	  return 0;      }      default:	return -1;    }}voidAggregateIPAddrPair::add_handlers(){    add_write_handler("clear", write_handler, (void *)H_CLEAR);}ELEMENT_REQUIRES(userlevel AggregateNotifier false)EXPORT_ELEMENT(AggregateIPAddrPair)#include <click/bighashmap.cc>CLICK_ENDDECLS

⌨️ 快捷键说明

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