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

📄 iprw.hh

📁 COPE the first practical network coding scheme which is developped on click
💻 HH
字号:
// -*- mode: c++; c-basic-offset: 4 -*-#ifndef CLICK_IPRW_HH#define CLICK_IPRW_HH#include <click/element.hh>#include <click/timer.hh>#include <click/bighashmap.hh>#include <click/ipflowid.hh>#include <clicknet/ip.h>CLICK_DECLSclass IPMapper;class IPRw : public Element { public:    class Pattern;    class Mapping;    typedef HashMap<IPFlowID, Mapping*> Map;    enum InputSpecName {	INPUT_SPEC_NOCHANGE, INPUT_SPEC_KEEP, INPUT_SPEC_DROP,	INPUT_SPEC_PATTERN, INPUT_SPEC_MAPPER    };    struct InputSpec {	int kind;	union {	    int output;	    struct {		Pattern* p;		int fport;		int rport;	    } pattern;		/* also used for INPUT_SPEC_KEEP */	    IPMapper* mapper;	} u;    };    IPRw();    ~IPRw();    enum ConfigurePhase {	CONFIGURE_PHASE_PATTERNS = CONFIGURE_PHASE_INFO,	CONFIGURE_PHASE_REWRITER = CONFIGURE_PHASE_DEFAULT,	CONFIGURE_PHASE_MAPPER = CONFIGURE_PHASE_REWRITER - 1,	CONFIGURE_PHASE_USER = CONFIGURE_PHASE_REWRITER + 1    };    int configure_phase() const 	{ return CONFIGURE_PHASE_REWRITER; }    int parse_input_spec(const String&, InputSpec&, String, ErrorHandler*);    virtual int notify_pattern(Pattern*, ErrorHandler*);    virtual Mapping* apply_pattern(Pattern*, int ip_p, const IPFlowID&, int, int) = 0;    virtual Mapping* get_mapping(int ip_p, const IPFlowID&) const = 0;  protected:    Vector<Pattern*> _all_patterns;    enum { GC_INTERVAL_SEC = 3600 };    void take_state_map(Map&, Mapping** free_head, Mapping** free_tail,			const Vector<Pattern*>&, const Vector<Pattern*>&);    void clear_map(Map&);    void clean_map(Map&, uint32_t last_jif);    void clean_map_free_tracked(Map&, Mapping*& free_head, Mapping*& free_tail,				uint32_t last_jif);    void incr_clean_map_free_tracked(Map&, Mapping*& head, Mapping*& tail,				     uint32_t last_jif);};class IPRw::Mapping { public:    enum { F_REVERSE = 1, F_MARKED = 2, F_FLOW_OVER = 4, F_FREE_TRACKED = 8,	   F_DST_ANNO = 16 };    Mapping(bool dst_anno);    void initialize(int ip_p, const IPFlowID& inf, const IPFlowID& outf, int output, uint16_t flags, Mapping* reverse);    static void make_pair(int ip_p, const IPFlowID& inf, const IPFlowID& outf,			  int foutput, int routput, Mapping* f, Mapping* r);    const IPFlowID& flow_id() const	{ return _mapto; }    Pattern* pattern() const		{ return _pat; }    int output() const 			{ return _output; }    bool is_primary() const		{ return !(_flags & F_REVERSE); }    const Mapping* primary() const { return is_primary() ? this : _reverse; }    Mapping* primary()		   { return is_primary() ? this : _reverse; }    Mapping* reverse() const		{ return _reverse; }    inline bool used_since(uint32_t) const;    void mark_used()			{ _used = click_jiffies(); }    bool marked() const			{ return (_flags & F_MARKED); }    void mark()				{ _flags |= F_MARKED; }    void unmark()			{ _flags &= ~F_MARKED; }    uint16_t sport() const		{ return _mapto.sport(); } // network    Mapping* free_next() const		{ return _free_next; }    void set_free_next(Mapping* m)	{ _free_next = m; }    bool session_over() const		{ return (_flags & F_FLOW_OVER) && (_reverse->_flags & F_FLOW_OVER); }    void set_session_over()		{ _flags |= F_FLOW_OVER; _reverse->_flags |= F_FLOW_OVER; }    void set_session_flow_over()	{ _flags |= F_FLOW_OVER; }    void clear_session_flow_over()	{ _flags &= ~F_FLOW_OVER; }    bool free_tracked() const		{ return (_flags & F_FREE_TRACKED); }    inline void add_to_free_tracked_tail(Mapping*& head, Mapping*& tail);    inline void clear_free_tracked();    void apply(WritablePacket*);    String unparse() const;  protected:    IPFlowID _mapto;    uint16_t _ip_csum_delta;    uint16_t _udp_csum_delta;    Mapping* _reverse;    uint16_t _flags;    uint8_t _ip_p;    uint8_t _output;    unsigned _used;    // these variables maintained by IPRw::Pattern    Pattern* _pat;    Mapping* _free_next;    friend class IPRw;    friend class IPRw::Pattern;    inline Mapping* free_from_list(Map&, bool notify);    inline void append_to_free(Mapping*& head, Mapping*& tail);};class IPRw::Pattern { public:    // Pattern is <saddr/sport[-sport2]/daddr/dport>.    // It is associated with a IPRewriter output port.    // It can be applied to a specific IPFlowID (<saddr/sport/daddr/dport>)    // to obtain a new IPFlowID rewritten according to the Pattern.    // Any Pattern component can be '-', which means that the corresponding    // IPFlowID component is left unchanged.     Pattern(const IPAddress&, int, const IPAddress&, int, bool is_napt, bool sequential, uint32_t variation);    static int parse(const String&, Pattern**, Element*, ErrorHandler*);    static int parse_with_ports(const String&, Pattern**,				int*, int*, Element*, ErrorHandler*);    void use()			{ _refcount++; }    void unuse()		{ if (--_refcount <= 0) delete this; }    int nmappings() const	{ return _nmappings; }      operator bool() const	{ return _saddr || _sport || _daddr || _dport; }    IPAddress daddr() const	{ return _daddr; }    bool allow_nat() const	{ return !_is_napt || _variation_top == 0; }    bool allow_napt() const	{ return _is_napt || _variation_top == 0; }    bool can_accept_from(const Pattern&) const;    bool create_mapping(int ip_p, const IPFlowID&, int fport, int rport, Mapping*, Mapping*, const Map&);    void accept_mapping(Mapping*);    inline void mapping_freed(Mapping*);    String unparse() const;  public:    IPAddress _saddr;    int _sport;			// host byte order    IPAddress _daddr;    int _dport;			// host byte order    uint32_t _variation_top;    uint32_t _variation_mask;    uint32_t _next_variation;    bool _is_napt;    bool _sequential;    int _refcount;    int _nmappings;    Pattern(const Pattern&);    Pattern& operator=(const Pattern&);    static int parse_napt(Vector<String>&, Pattern**, Element*, ErrorHandler*);    static int parse_nat(Vector<String>&, Pattern**, Element*, ErrorHandler*);    friend class Mapping;};class IPMapper { public:    IPMapper()				{ }    virtual ~IPMapper()			{ }    void notify_rewriter(IPRw*, ErrorHandler*);    virtual IPRw::Mapping* get_map(IPRw*, int ip_p, const IPFlowID&, Packet*);};inline voidIPRw::Mapping::append_to_free(Mapping*& head, Mapping*& tail){    assert((!head && !tail)	   || (head && tail && (head->_flags & F_FREE_TRACKED) && (tail->_flags & F_FREE_TRACKED)));    assert(!_free_next && !_reverse->_free_next);    if (tail)	tail = tail->_free_next = this;    else	head = tail = this;}inline voidIPRw::Mapping::add_to_free_tracked_tail(Mapping*& head, Mapping*& tail){    assert(!(_flags & F_FREE_TRACKED) && !(_reverse->_flags & F_FREE_TRACKED));    _flags |= F_FREE_TRACKED;    _reverse->_flags |= F_FREE_TRACKED;    primary()->append_to_free(head, tail);}inline voidIPRw::Mapping::clear_free_tracked(){    _flags &= ~F_FREE_TRACKED;    _reverse->_flags &= ~F_FREE_TRACKED;    _free_next = 0;    assert(_reverse->_free_next == 0);}inline boolIPRw::Mapping::used_since(uint32_t t) const{     return ((int32_t)(_used - t)) >= 0 || ((int32_t)(_reverse->_used - t)) >= 0;}CLICK_ENDDECLS#endif

⌨️ 快捷键说明

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