// ruleset.h
// part of ezbounce

#ifndef __RULESET_H
#define __RULESET_H

#include "general.h"
#include "linkedlist.h"
#include "debug.h"

/* 
 *  holds information stored in
 *  allow|deny {
 *     from ...
 *     to ...
 *  }
 *  blocks in the configuration file
 */


class ruleset
{
public:

    static const char FROM, TO;
    static const int  UNLIMITED;
    /* check if this guy is permitted to connect to the server*/
    virtual int is_allowed(const char *address, unsigned short port, 
                           char *buffer4reason, size_t) = 0;
    /* check if this guy may connect to "to" */
    virtual int is_allowed_to(const char *from, const char *to,
                              unsigned short port, char *buffer4reason, size_t) = 0;
    /* checks if host & port are in its list of addresses */
    virtual bool does_match(const char *host, unsigned short port, char t) = 0;
    /* add a host name to the list of ppl that can connect */
    virtual bool add_host_from(const char *address, const char *ports,
                               const char *reason, int max) = 0;
    /* add a host name to the list of places ppl can connect to */
    virtual bool add_host_to(const char *address, const char *ports,
                             const char *reason, int max) = 0;

    virtual int register_connection(char t, const char *, const char *, unsigned short)
    {
        DEBUG("Increasing %s usage count of %p to %d\n", ((t == FROM) ? "FROM" : "TO"), this, (t == FROM ? num_registered_from + 1 : num_registered_to + 1));
        return (t == FROM) ? ++num_registered_from : ++num_registered_to;
    }
    virtual int unregister_connection(char t, const char *, const char *, unsigned short) 
    {
        DEBUG("Decreasing %s usage count of %p to %d\n", ((t == FROM) ? "FROM" : "TO"), this,(t == FROM ? num_registered_from - 1 : num_registered_to - 1));
        return (t == FROM) ? --num_registered_from : --num_registered_to;
    }

    ruleset();
    virtual ~ruleset();
    
    static list<ruleset> * sync_lists(list<ruleset> * , list<ruleset> * );
    static int find_matching(const char *, unsigned short, list<ruleset> *, list<ruleset> *);
    static int list_is_allowed_from(list<ruleset> *, const char * , unsigned short, char *, long);
    static int list_is_allowed_to(list<ruleset> *, const char *, const char *, unsigned short, char *, long);
    static int list_register_from(list<ruleset> *, const char *, unsigned short);
    static int list_register_to(list<ruleset> *, const char *, unsigned short);
    static int list_unregister_from(list<ruleset> *, const char *, unsigned short);
    static int list_unregister_to(list<ruleset> *, const char *, unsigned short);

    bool operator == (/* const */ ruleset &);

    bool dead() const
    {
        return (obsolete && !num_registered_to && !num_registered_from);
    }

protected:
    struct rs_host 
    {
        char *address, *ports, *reason, type;
        int  max, num;
        ~rs_host();
        rs_host(char, const char *, const char *, const char *, int);
    };

    list<rs_host> from_hosts;
    list<rs_host> to_hosts;

    /* these keep track of register_connection() and unregister_connection calls */
    unsigned num_registered_to, num_registered_from;
    bool obsolete;
};

class allowed_ruleset : public ruleset
{
public:
    bool add_host_to( const char *, const char *, const char *, int);
    bool add_host_from( const char *, const char *, const char *, int);
    int is_allowed(const char *, unsigned short, char *, size_t);
    int is_allowed_to(const char*, const char*, unsigned short, char *, size_t);
    bool does_match(const char *from, unsigned short port, char t);
    int register_connection(char,const char *, const char *, unsigned short);
    int unregister_connection(char, const char * , const char *, unsigned short);
};

class denied_ruleset : public ruleset
{
public:
    bool add_host_to(const char *, const char *, const char *, int);
    bool add_host_from(const char *, const char *, const char *, int);
    int is_allowed(const char *, unsigned short, char *, size_t);
    int is_allowed_to(const char*, const char *, unsigned short, char *, size_t);
    bool does_match(const char *from, unsigned short port, char t);
    int register_connection(char, const char *, const char *, unsigned short);
    int unregister_connection(char, const char * , const char *, unsigned short);      
};

extern list<ruleset> * shitlist;

#endif


syntax highlighted by Code2HTML, v. 0.9.1