On Wed, 2010-09-15 at 02:06 +0000, Amos Jeffries wrote:
> On Tue, 14 Sep 2010 23:55:20 +0100, Andrew Beverley <a...@andybev.com>
> wrote:
> >>  * Config.accessList.outgoingTos, Config.accessList.clientsideTos,
> >> Config.accessList.outgoingNfmark, Config.accessList.clientsideNfmark
> can
> >> become members of the Qos scope Config object. All the parsing /free
> >> stuff
> >> can be moved there too with some #define parse_...() etc for the legacy
> >> parser.
> >> 
> > 
> > I've moved all the configuration variables and functions to the Qos
> > scope. I have renamed parse_acl_tos(acl_tos ** head) as
> > Ip::Qos::Config::parseConfigAclTos(acl_tos ** head).
> > 
> > However, I'm unable to compile because of the following error:
> > 
> > Qos.cc: In member function ‘void
> > Ip::Qos::Config::parseConfigAclTos(acl_tos**)’:
> > Qos.cc:377: error: argument of type ‘void (Ip::Qos::Config::)(void*)’
> does
> > not match ‘void (*)(void*)’
> > 
> > The code at line 377 is:
> > 
> > CBDATA_INIT_TYPE_FREECB(acl_tos, freedConfigAclTos);
> > 
> > I have
> > 
> > CBDATA_TYPE(acl_tos);
> > 
> > specified before the parseConfigAclTos function.
> > 
> > Could you give me any ideas as to what I am doing wrong here? If you
> > need me to send through any more of the code then please let me know.
> 
> Do you have this with a cast?
>  #define parse_acl_tos(X) Ip::Qos::Config::parseConfigAclTos((acl_tos
> **)X)
> 
> with the cf.data.pre "TYPE: acl_tos" unchanged.

No, I had changed it. However, I have now changed it back to the above,
but still get the same error. Any other ideas?

Qos.cc: In member function ‘void Ip::Qos::Config::parseConfigAclTos(acl_tos**)’:
Qos.cc:377: error: argument of type ‘void (Ip::Qos::Config::)(void*)’ does not 
match ‘void (*)(void*)’

I have attached my current Qos.cc and Qos.h

Thanks,

Andy

#include "acl/Gadgets.h"
#include "ConfigParser.h"
#include "fde.h"
#include "HierarchyLogEntry.h"
#include "ip/tools.h"
#include "Qos.h"
#include "Parsing.h"
#include "squid.h"
#include "Store.h"

extern void dump_acl_list(StoreEntry * entry, ACLList * head);

/* Qos namespace */

void
Ip::Qos::getTosFromServer(const int server_fd, fde *clientFde)
{
#if USE_QOS_TOS 
    tos_t tos = 1;
    int tos_len = sizeof(tos); 
    clientFde->tosFromServer = 0;
    if (setsockopt(server_fd,SOL_IP,IP_RECVTOS,&tos,tos_len)==0) {
        unsigned char buf[512];
        int len = 512;
        if (getsockopt(server_fd,SOL_IP,IP_PKTOPTIONS,buf,(socklen_t*)&len) == 0) {
            /* Parse the PKTOPTIONS structure to locate the TOS data message
             * prepared in the kernel by the ZPH incoming TCP TOS preserving
             * patch.
             */
            unsigned char * pbuf = buf;
            while (pbuf-buf < len) {
                struct cmsghdr *o = (struct cmsghdr*)pbuf;
                if (o->cmsg_len<=0)
                    break;

                if (o->cmsg_level == SOL_IP && o->cmsg_type == IP_TOS) {
                    int *tmp = (int*)CMSG_DATA(o);
                    clientFde->tosFromServer = (tos_t)*tmp;
                    break;
                }
                pbuf += CMSG_LEN(o->cmsg_len);
            }
        } else {
            debugs(33, 1, "QOS: error in getsockopt(IP_PKTOPTIONS) on FD " << server_fd << " " << xstrerror());
        }
    } else {
        debugs(33, 1, "QOS: error in setsockopt(IP_RECVTOS) on FD " << server_fd << " " << xstrerror());
    }
#endif
}

void Ip::Qos::getNfmarkFromServer(const int server_fd, const fde *servFde, const fde *clientFde)
{
#if USE_QOS_NFMARK
    /* Allocate a new conntrack */
    if (struct nf_conntrack *ct = nfct_new()) {

        /* Prepare data needed to find the connection in the conntrack table.
         * We need the local and remote IP address, and the local and remote
         * port numbers.
         */

        Ip::Address serv_fde_local_conn;
        struct addrinfo *addr = NULL;
        serv_fde_local_conn.InitAddrInfo(addr);
        getsockname(server_fd, addr->ai_addr, &(addr->ai_addrlen));
        serv_fde_local_conn = *addr;
        serv_fde_local_conn.GetAddrInfo(addr);

        unsigned short serv_fde_local_port = ((struct sockaddr_in*)addr->ai_addr)->sin_port;
        struct in6_addr serv_fde_local_ip6;
        struct in_addr serv_fde_local_ip;

        if (Ip::EnableIpv6 && serv_fde_local_conn.IsIPv6()) {
            serv_fde_local_ip6 = ((struct sockaddr_in6*)addr->ai_addr)->sin6_addr;
            nfct_set_attr_u8(ct, ATTR_L3PROTO, AF_INET6);
            struct in6_addr serv_fde_remote_ip6;
            inet_pton(AF_INET6,servFde->ipaddr,(struct in6_addr*)&serv_fde_remote_ip6);
            nfct_set_attr(ct, ATTR_IPV6_DST, serv_fde_remote_ip6.s6_addr);
            nfct_set_attr(ct, ATTR_IPV6_SRC, serv_fde_local_ip6.s6_addr); 
        } else {
            serv_fde_local_ip = ((struct sockaddr_in*)addr->ai_addr)->sin_addr;
            nfct_set_attr_u8(ct, ATTR_L3PROTO, AF_INET);
            nfct_set_attr_u32(ct, ATTR_IPV4_DST, inet_addr(servFde->ipaddr));
            nfct_set_attr_u32(ct, ATTR_IPV4_SRC, serv_fde_local_ip.s_addr);  
        }

        nfct_set_attr_u8(ct, ATTR_L4PROTO, IPPROTO_TCP);
        nfct_set_attr_u16(ct, ATTR_PORT_DST, htons(servFde->remote_port));
        nfct_set_attr_u16(ct, ATTR_PORT_SRC, serv_fde_local_port);

        /* Open a handle to the conntrack */
        if (struct nfct_handle *h = nfct_open(CONNTRACK, 0)) {
            /* Register the callback. The callback function will record the mark value. */
            nfct_callback_register(h, NFCT_T_ALL, getNfMarkCallback, (void *)clientFde);  
            /* Query the conntrack table using the data previously set */
            int x = nfct_query(h, NFCT_Q_GET, ct);
            if (x == -1) {
                debugs(17, 2, "QOS: Failed to retrieve connection mark: (" << x << ") " << strerror(errno)
                  << " (Destination " << servFde->ipaddr << ":" << servFde->remote_port
                  << ", source " << serv_fde_local_conn << ")" );
            }
             
            nfct_close(h);
        } else {
            debugs(17, 2, "QOS: Failed to open conntrack handle for upstream netfilter mark retrieval.");
        }
        serv_fde_local_conn.FreeAddrInfo(addr);
        nfct_destroy(ct);

    } else {
        debugs(17, 2, "QOS: Failed to allocate new conntrack for upstream netfilter mark retrieval.");
    }
#endif
}

#if USE_QOS_NFMARK
int
Ip::Qos::getNfMarkCallback(enum nf_conntrack_msg_type type,
              struct nf_conntrack *ct,
              void *data)
{
        fde *clientFde = (fde *)data;
        clientFde->nfmarkFromServer = nfct_get_attr_u32(ct, ATTR_MARK);
        debugs(17, 3, "QOS: Retrieved connection mark value: " << clientFde->nfmarkFromServer);

        return NFCT_CB_CONTINUE;
}
#endif

int
Ip::Qos::doTosLocalMiss(const int fd, const HierarchyLogEntry *hier)
{
    tos_t tos = 0;
    if (Ip::Qos::TheConfig.tosSiblingHit && hier->code==SIBLING_HIT ) {
        tos = Ip::Qos::TheConfig.tosSiblingHit;
        debugs(33, 2, "QOS: Sibling Peer hit with hier code=" << hier->code << ", TOS=" << int(tos));
    } else if (Ip::Qos::TheConfig.tosParentHit && hier->code==PARENT_HIT) {
        tos = Ip::Qos::TheConfig.tosParentHit;
        debugs(33, 2, "QOS: Parent Peer hit with hier code=" << hier->code << ", TOS=" << int(tos));
    } else if (Ip::Qos::TheConfig.preserveMissTos && Ip::Qos::TheConfig.preserveMissTosMask) {
        tos = fd_table[fd].tosFromServer & Ip::Qos::TheConfig.preserveMissTosMask;
        debugs(33, 2, "QOS: Preserving TOS on miss, TOS=" << int(tos));
    }
    return setSockTos(fd, tos);
}

int
Ip::Qos::doNfmarkLocalMiss(const int fd, const HierarchyLogEntry *hier)
{
    nfmark_t mark = 0;
    if (Ip::Qos::TheConfig.markSiblingHit && hier->code==SIBLING_HIT ) {
        mark = Ip::Qos::TheConfig.markSiblingHit;
        debugs(33, 2, "QOS: Sibling Peer hit with hier code=" << hier->code << ", Mark=" << mark);
    } else if (Ip::Qos::TheConfig.markParentHit && hier->code==PARENT_HIT) {
        mark = Ip::Qos::TheConfig.markParentHit;
        debugs(33, 2, "QOS: Parent Peer hit with hier code=" << hier->code << ", Mark=" << mark);
    } else if (Ip::Qos::TheConfig.preserveMissMark) {
        mark = fd_table[fd].nfmarkFromServer & Ip::Qos::TheConfig.preserveMissMarkMask;
        debugs(33, 2, "QOS: Preserving mark on miss, Mark=" << mark);
    }
    return setSockNfmark(fd, mark);
}

int
Ip::Qos::doTosLocalHit(const int fd)
{
    debugs(33, 2, "QOS: Setting TOS for local hit, TOS=" << int(Ip::Qos::TheConfig.tosLocalHit));
    return setSockTos(fd, Ip::Qos::TheConfig.tosLocalHit);
}

int
Ip::Qos::doNfmarkLocalHit(const int fd)
{
    debugs(33, 2, "QOS: Setting netfilter mark for local hit, mark=" << Ip::Qos::TheConfig.markLocalHit);
    return setSockNfmark(fd, Ip::Qos::TheConfig.markLocalHit);
}

/* Qos::Config class */

Ip::Qos::Config Ip::Qos::TheConfig;

Ip::Qos::Config::Config()
{
    tosLocalHit = 0;
    tosSiblingHit = 0;
    tosParentHit = 0;
    preserveMissTos = false;
    preserveMissTosMask = 0xFF;
    markLocalHit = 0;
    markSiblingHit = 0;
    markParentHit = 0;
    preserveMissMark = false;
    preserveMissMarkMask = 0xFFFFFFFF;
}

void
Ip::Qos::Config::parseConfigLine()
{
    /* parse options ... */
    char *token;
    /* These are set as appropriate and then used to check whether the initial loop has been done */
    bool mark = false;
    bool tos = false;
    /* Assume preserve is true. We don't set at initialisation as this affects isHitTosActive().
       We have to do this now, as we may never match the 'tos' parameter below */
#if !USE_QOS_TOS
    debugs(3, DBG_CRITICAL, "ERROR: Invalid option 'qos_flows'. QOS features not enabled in this build");
    self_destruct();
#endif

    while ( (token = strtok(NULL, w_space)) ) {

        // Work out TOS or mark. Default to TOS for backwards compatibility
        if (!(mark || tos)) {
            if (strncmp(token, "mark",4) == 0) {
#if USE_QOS_NFMARK && defined(_SQUID_LINUX_)
                mark = true;
                // Assume preserve is true. We don't set at initialisation as this affects isHitNfmarkActive()
                preserveMissMark = 1;
#elif defined(_SQUID_LINUX_)
                debugs(3, DBG_CRITICAL, "ERROR: Invalid parameter 'mark' in qos_flows option. "
                                            << "Netfilter marking only available for Linux environment");
                self_destruct();
#else
                debugs(3, DBG_CRITICAL, "ERROR: Invalid parameter 'mark' in qos_flows option. "
                                            << "Netfilter marking not enabled in this build");
                self_destruct();
#endif
            } else if (strncmp(token, "tos",3) == 0) {
                preserveMissTos = true;
                tos = true;
            } else {
                preserveMissTos = true;
                tos = true;
            }
        }

        if (strncmp(token, "local-hit=",10) == 0) {

            if (mark) {
                if (!xstrtoui(&token[10], NULL, &markLocalHit, 0, std::numeric_limits<nfmark_t>::max()))
                        debugs(3, DBG_CRITICAL, "ERROR: Bad mark local-hit value " << &token[10]);
            } else {
                unsigned int v = 0;
                if (!xstrtoui(&token[10], NULL, &v, 0, std::numeric_limits<tos_t>::max()))
                        debugs(3, DBG_CRITICAL, "ERROR: Bad TOS local-hit value " << &token[10]);
                tosLocalHit = (tos_t)v;
            }

        } else if (strncmp(token, "sibling-hit=",12) == 0) {

            if (mark) {
                if (!xstrtoui(&token[12], NULL, &markSiblingHit, 0, std::numeric_limits<nfmark_t>::max()))
                        debugs(3, DBG_CRITICAL, "ERROR: Bad mark sibling-hit value " << &token[12]);
            } else {
                unsigned int v = 0;
                if (!xstrtoui(&token[12], NULL, &v, 0, std::numeric_limits<tos_t>::max()))
                        debugs(3, DBG_CRITICAL, "ERROR: Bad TOS sibling-hit value " << &token[12]);
                tosSiblingHit = (tos_t)v;
            }

        } else if (strncmp(token, "parent-hit=",11) == 0) {

            if (mark) {
                if (!xstrtoui(&token[11], NULL, &markParentHit, 0, std::numeric_limits<nfmark_t>::max()))
                        debugs(3, DBG_CRITICAL, "ERROR: Bad mark parent-hit value " << &token[11]);
            } else {
                unsigned int v = 0;
                if (!xstrtoui(&token[11], NULL, &v, 0, std::numeric_limits<tos_t>::max()))
                        debugs(3, DBG_CRITICAL, "ERROR: Bad TOS parent-hit value " << &token[11]);
                tosParentHit = (tos_t)v;
            }

        } else if (strcmp(token, "disable-preserve-miss") == 0) {

            if (preserveMissTosMask!=0xFFU || preserveMissMarkMask!=0xFFFFFFFFU) {
                debugs(3, DBG_CRITICAL, "ERROR: miss-mask feature cannot be set with disable-preserve-miss");
            }
            if (mark) {
                preserveMissMark = false;
                preserveMissMarkMask = 0;
            } else {
                preserveMissTos = false;
                preserveMissTosMask = 0;
            }

        } else if (strncmp(token, "miss-mask=",10) == 0) {

            if (mark && preserveMissMark) {
                if (!xstrtoui(&token[10], NULL, &preserveMissMarkMask, 0, std::numeric_limits<nfmark_t>::max()))
                        debugs(3, DBG_CRITICAL, "ERROR: Bad mark miss-mark value " << &token[10]);
            } else if (preserveMissTos) {
                unsigned int v = 0;
                if (!xstrtoui(&token[10], NULL, &v, 0, std::numeric_limits<tos_t>::max()))
                        debugs(3, DBG_CRITICAL, "ERROR: Bad TOS miss-mark value " << &token[10]);
                preserveMissTosMask = (tos_t)v;
            } else {
                debugs(3, DBG_CRITICAL, "ERROR: miss-mask feature cannot be set with disable-preserve-miss");
            }

        }
    }
}

void
Ip::Qos::Config::dumpConfigLine(char *entry, const char *name) const
{
    char *p = entry;
    if (isHitTosActive()) {

        p += snprintf(p, 11, "%s", name); // strlen("qos_flows ");
        p += snprintf(p, 4, "%s", "tos");

        if (tosLocalHit > 0) {
            p += snprintf(p, 16, " local-hit=0x%02X", tosLocalHit);
        }
        if (tosSiblingHit > 0) {
            p += snprintf(p, 18, " sibling-hit=0x%02X", tosSiblingHit);
        }
        if (tosParentHit > 0) {
            p += snprintf(p, 17, " parent-hit=0x%02X", tosParentHit);
        }
        if (preserveMissTos == 0) {
            p += snprintf(p, 23, " disable-preserve-miss");
        }
        if (preserveMissTos && preserveMissTosMask != 0) {
            p += snprintf(p, 16, " miss-mask=0x%02X", preserveMissTosMask);
        }
        p += snprintf(p, 2, "\n");
    }
    
    if (isHitNfmarkActive()) {
        p += snprintf(p, 11, "%s", name); // strlen("qos_flows ");
        p += snprintf(p, 5, "%s", "mark");

        if (markLocalHit > 0) {
            p += snprintf(p, 22, " local-hit=0x%02X", markLocalHit);
        }
        if (markSiblingHit > 0) {
            p += snprintf(p, 24, " sibling-hit=0x%02X", markSiblingHit);
        }
        if (markParentHit > 0) {
            p += snprintf(p, 23, " parent-hit=0x%02X", markParentHit);
        }
        if (preserveMissMark == 0) {
            p += snprintf(p, 23, " disable-preserve-miss");
        }
        if (preserveMissMark && preserveMissMarkMask != 0) {
            p += snprintf(p, 22, " miss-mask=0x%02X", preserveMissMarkMask);
        }
        p += snprintf(p, 2, "\n");
    }
}

CBDATA_TYPE(acl_tos);
static ConfigParser LegacyParser = ConfigParser();

void
Ip::Qos::Config::parseConfigAclTos(acl_tos ** head)
{
    acl_tos *l;
    acl_tos **tail = head;      /* sane name below */
    unsigned int tos;           /* Initially uint for strtoui. Casted to tos_t before return */
    char *token = strtok(NULL, w_space);

    if (!token) {
        self_destruct();
        return;
    }

    if (!xstrtoui(token, NULL, &tos, 0, std::numeric_limits<tos_t>::max())) {
        self_destruct();
        return;
    }

    CBDATA_INIT_TYPE_FREECB(acl_tos, freedConfigAclTos);

    l = cbdataAlloc(acl_tos);

    l->tos = (tos_t)tos;

    aclParseAclList(LegacyParser, &l->aclList);

    while (*tail)
        tail = &(*tail)->next;

    *tail = l;
}

void
Ip::Qos::Config::dumpConfigAclTos(StoreEntry * entry, const char *name, acl_tos * head)
{
    acl_tos *l;

    for (l = head; l; l = l->next) {
        if (l->tos > 0)
            storeAppendPrintf(entry, "%s 0x%02X", name, l->tos);
        else
            storeAppendPrintf(entry, "%s none", name);

        dump_acl_list(entry, l->aclList);

        storeAppendPrintf(entry, "\n");
    }
}

void
Ip::Qos::Config::freedConfigAclTos(void *data)
{
    acl_tos *l = static_cast<acl_tos *>(data);
    aclDestroyAclList(&l->aclList);
}
 
void
Ip::Qos::Config::freeConfigAclTos(acl_tos ** head)
{
    while (*head) {
        acl_tos *l = *head;
        *head = l->next;   
        l->next = NULL;    
        cbdataFree(l);     
    }
}

#if !_USE_INLINE_
#include "Qos.cci"
#endif
#ifndef SQUID_QOSCONFIG_H
#define SQUID_QOSCONFIG_H

#include "config.h"

#if HAVE_LIBNETFILTER_CONNTRACK_LIBNETFILTER_CONNTRACK_H
#include <libnetfilter_conntrack/libnetfilter_conntrack.h>
#endif

#if HAVE_LIBNETFILTER_CONNTRACK_LIBNETFILTER_CONNTRACK_TCP_H
#include <libnetfilter_conntrack/libnetfilter_conntrack_tcp.h>
#endif

#if HAVE_LIMITS
#include <limits>
#endif

// Forward-declarations
class fde;
class HierarchyLogEntry;

namespace Ip
{

/**
 * QOS namespace contains all the QOS functionality: global functions within
 * the namespace and the configuration parameters within a config class.
 */
namespace Qos
{

    /**
    * Function to retrieve the TOS value of the inbound packet.
    * Called by FwdState::dispatch if QOS options are enabled.
    * @param server_fd Server side descriptor of connection to get TOS for
    * @param clientFde Pointer to client side fde instance to set tosFromServer in
    */ 
    void getTosFromServer(const int server_fd, fde *clientFde);
    
    /**
    * Function to retrieve the netfilter mark value of the connection
    * to the upstream server. Called by FwdState::dispatch if QOS
    * options are enabled.
    * @param server_fd Server side descriptor of connection to get mark for
    * @param servFde Pointer to server side fde instance to get mark for
    * @param clientFde Pointer to client side fde instance to set nfmarkFromServer in
    */
    void getNfmarkFromServer(const int server_fd, const fde *servFde, const fde *clientFde);

#if USE_QOS_NFMARK
    /**          
    * Callback function to mark connection once it's been found.
    * This function is called by the libnetfilter_conntrack
    * libraries, during nfct_query in Ip::Qos::getNfmarkFromServer.
    * nfct_callback_register is used to register this function.   
    * @param nf_conntrack_msg_type Type of conntrack message
    * @param nf_conntrack Pointer to the conntrack structure
    * @param clientFde Pointer to client side fde instance to set nfmarkFromServer in
    */
    int getNfMarkCallback(enum nf_conntrack_msg_type type, struct nf_conntrack *ct, void *clientFde);
#endif

    /**
    * Function to work out and then apply to the socket the appropriate
    * TOS value to set on packets when items have not been retrieved from
    * local cache. Called by clientReplyContext::sendMoreData if QOS is  
    * enabled for TOS.
    * @param fd Descriptor of socket to set the TOS for
    * @param HierarchyLogEntry Pointer to hier structure of request
    */
    int doTosLocalMiss(const int fd, const HierarchyLogEntry *hier);
    
    /**
    * Function to work out and then apply to the socket the appropriate
    * netfilter mark value to set on packets when items have not been  
    * retrieved from local cache. Called by clientReplyContext::sendMoreData
    * if QOS is enabled for TOS.
    * @param fd Descriptor of socket to set the mark for
    * @param HierarchyLogEntry Pointer to hier structure of request
    */
    int doNfmarkLocalMiss(const int fd, const HierarchyLogEntry *hier);
    
    /**
    * Function to work out and then apply to the socket the appropriate
    * TOS value to set on packets when items *have* been retrieved from
    * local cache. Called by clientReplyContext::doGetMoreData if QOS is
    * enabled for TOS.
    * @param fd Descriptor of socket to set the TOS for
    */
    int doTosLocalHit(const int fd);
    
    /**
    * Function to work out and then apply to the socket the appropriate
    * netfilter mark value to set on packets when items *have* been
    * retrieved from local cache. Called by clientReplyContext::doGetMoreData
    * if QOS is enabled for TOS.
    * @param fd Descriptor of socket to set the mark for
    */
    int doNfmarkLocalHit(const int fd);
    
    /**
    * Function to set the TOS value of packets. Sets the value on the socket
    * which then gets copied to the packets.
    * @param fd Descriptor of socket to set the TOS for
    */   
    _SQUID_INLINE_ int setSockTos(int fd, tos_t tos);
    
    /**
    * Function to set the netfilter mark value of packets. Sets the value on the
    * socket which then gets copied to the packets. Called from Ip::Qos::doNfmarkLocalMiss
    * @param fd Descriptor of socket to set the mark for
    */ 
    _SQUID_INLINE_ int setSockNfmark(int fd, nfmark_t mark);

/**
 * QOS configuration class. Contains all the parameters for QOS functions as well
 * as functions to check whether either TOS or MARK QOS is enabled.
 */
class Config
{
public:

    Config();
    ~Config() {};

    void parseConfigLine();

    /**
     * Dump all the configuration values
     *
     * NOTE: Due to the low-level nature of the library these
     * objects are part of the dump function must be self-contained.
     * which means no StoreEntry references. Just a basic char* buffer.
     */
    void dumpConfigLine(char *entry, const char *name) const;

    void parseConfigAclTos(acl_tos ** head);
    void dumpConfigAclTos(StoreEntry * entry, const char *name, acl_tos * head);
    void freedConfigAclTos(void *data);
    void freeConfigAclTos(acl_tos ** head);

    /// Whether we should modify TOS flags based on cache hits and misses.
    _SQUID_INLINE_ bool isHitTosActive() const;
    
    /// Whether we should modify netfilter marks based on cache hits and misses.
    _SQUID_INLINE_ bool isHitNfmarkActive() const;

    /**
    * Iterates through any outgoing_nfmark or clientside_nfmark configuration parameters
    * to find out if any Netfilter marking is required.
    * This function is used on initialisation to define capabilities required (Netfilter
    * marking requires CAP_NET_ADMIN).
    */ 
    _SQUID_INLINE_ bool isAclNfmarkActive();

    /**
    * Iterates through any outgoing_tos or clientside_tos configuration parameters
    * to find out if packets should be marked with TOS flags.
    */
    _SQUID_INLINE_ bool isAclTosActive();

    tos_t tosLocalHit;                  ///< TOS value to apply to local cache hits
    tos_t tosSiblingHit;                ///< TOS value to apply to hits from siblings
    tos_t tosParentHit;                 ///< TOS value to apply to hits from parent
    bool preserveMissTos;               ///< Whether to preserve the TOS value of the inbound packet for misses
    tos_t preserveMissTosMask;          ///< The mask to apply when preserving the TOS of misses

    nfmark_t markLocalHit;              ///< Netfilter mark value to apply to local cache hits
    nfmark_t markSiblingHit;            ///< Netfilter mark value to apply to hits from siblings
    nfmark_t markParentHit;             ///< Netfilter mark value to apply to hits from parent
    bool preserveMissMark;              ///< Whether to preserve netfilter mark value of inbound connection
    nfmark_t preserveMissMarkMask;      ///< The mask to apply when preserving the netfilter mark of misses

    acl_tos *tosToServer;		///< The TOS that packets to the web server should be marked with, based on ACL
    acl_tos *tosToClient;		///< The TOS that packets to the client should be marked with, based on ACL
    acl_nfmark *nfmarkToServer;		///< The MARK that packets to the web server should be marked with, based on ACL
    acl_nfmark *nfmarkToClient;		///< The MARK that packets to the client should be marked with, based on ACL

};

/// Globally available instance of Qos::Config
extern Config TheConfig;

/* legacy parser access wrappers */
#define parse_QosConfig(X)	(X)->parseConfigLine()
#define free_QosConfig(X)
#define dump_QosConfig(e,n,X) do { \
		char temp[256]; /* random number. change as needed. max config line length. */ \
		(X).dumpConfigLine(temp,n); \
	        storeAppendPrintf(e, "%s", temp); \
	} while(0);

#define parse_acl_tos(X)	Ip::Qos::Config::parseConfigAclTos((acl_tos **)X)
#define dump_acl_tos(X)		Ip::Qos::Config::dumpConfigAclTos((acl_tos **)X)
#define freed_acl_tos(X)	Ip::Qos::Config::freedConfigAclTos((acl_tos **)X)
#define free_acl_tos(X)		Ip::Qos::Config::freeConfigAclTos((acl_tos **)X)

}; // namespace Qos

}; // namespace Ip

#if _USE_INLINE_
#include "Qos.cci"
#endif

#endif /* SQUID_QOSCONFIG_H */

Reply via email to