Re: [MERGE] Initial netfilter mark patch for comment

2010-09-04 Thread Andrew Beverley
My latest revision of the patch for netfilter marking will follow soon. 

Before I post it, I will reply to comments on the previous version.

   
   Question number 2: what is stubQosConfig.cc? Does that also need
   updating for this patch?
   
  
  stub* are cut down set of all non-inline Ip::QosConfig methods and any 
  globals defined in QosConfig.h. Changes to the API need to be mirrored 
  there. The functions inside usually call fatal() to alert a wrong 
  linkage clearly during testing. In this particular case the parse 
  function will need to be duplicated there.
  
  Sorry, I need some clarification on this. I've looked at most of the
  other stub files, and most of the functions do indeed just return
  fatal(). However, the existing stubQosConfig.cc is almost identical to
  QosConfig.cc, with almost all of its code. Shall I change the functions
  to fatal()?
  
  Presumably I should add all the new functions into it (getTosLocalMiss,
  getNfmarkLocalMiss, getTosLocalHit, getNfmarkLocalHit, getUpstreamTOS,
  getUpstreamNfMark, isTosActive, isMarkActive, GetNfMarkCallback)?
 
 It does need another looking at and possibly stripping down. IIRC it was
 there from when QosConfig was a member of SquidConfig. I'll run a quick
 check myself now to see what breaks in the current usage if the currently
 defined stubs are stripped down.
 
 You will need to add the appropriate dead-end stubs for the new functions.

I've added stubs for all the non-inline functions. They just all call
fatal(). If I've not got this quite right then please let me know.

 
  
  In this version the new methods look they should be in the Ip::Qos 
  namespace.
  
* the new clientReplyContext::tosLocalMissValue() and 
  clientReplyContext::nfmarkLocalMissValue() methods particularly look 
  like they really should take the hier code as a second parameter. Both 
  fd and the hier if passed in should be const.
  
  I've moved them to Ip::Qos and added the parameters as const.
  
* the new FwdState getUpstream* methods are in a similar position but
  not quite so clear cut. If you can find  way to cleanly move them there
  great, otherwise it's not so much a bit deal yet.
  
  I've moved these, as well as most of the other QOS functions, into
  Ip::Qos. I have also removed the QosConfig namespace, as it didn't seem
  to fit with all these additional functions.
 
 We are moving the rest of Squid in general towards a model of
 Namespace::TheConfig containing the config data values pulled from
 squid.conf separate from the code which utilizes them.
 
 Please wait for Alex as well on this particular change.
 
 My thoughts on it are these;
 
 I like the moving of functions to IP::Qos including the existing ones.
 Under the coding guidelines the existence of class Qos calls for it to be
 in a file src/ip/Qos.h and .cc.

I have renamed the files from QosConfig to Qos.

As per previous discussions, the functions are now contained in a Qos
namespace, and the configuration (and functions) are kept in a Config
class.

 Several of the functions particularly the is*Active() can be inlined for
 better performance with _SQUID_INLINE_, which calls for a ip/Qos.cci file
 to define them and be conditionally included in the .h or .cc based on #if
 _USE_INLINE_.

I've moved what I consider to be the most appropriate functions inline.
If you disagree with my choices then please tell me.

 Some set*Mark and set*Tos functions woudl round out the API. To take the
 same parameters as the get*() ones, but which do the perform the
 setsockopt. So that paired lines of:
 unsigned int mark = Ip::Qos.getNfmarkLocalMiss(fd,
 http-request-hier);
 comm_set_nfmark(fd,mark);
 become
 Ip::Qos.setNfmarkLocalMiss(fd, http-request-hier);
 
 ... and thus comm.cc does not need anything about the MARK setsockopt.
 Mirroring the way it has nothing to do with the MARK/TOS getsockopt etc.

As per other emails, I have removed get*s and set*s and replaced with
do*s. I did experiment with keeping get*s and set*s and moving the get*s
to private space, but in all honesty, it just complicated the code
without achieving much. I think it's quite tidy now.

  
  I've carried out a fair bit of testing on the mark functionality today,
  and It Works For Me, but I'll be able to try it better in a production
  server in the coming weeks.
  
  Could you let me know if/what else I need to do before acceptance. I
  believe there are the following:
  
  - Confirm and implement stub function requirements
  - Factor the configure.in changes into Kinkie's autoconf-refactor?
 
 Those are the big ones. Along with getting the namespace change approved.
 
 The reconfigure straightening will change your dependency logic model a
 bit. Specifically such that the absence of --with-netfilter-conntrack
 (implicit / auto-detect case) results in the same auto-detect currently
 only done by explicit yes results, but which does not terminate in
 AC_MSG_ERROR.

Done.

The above configure 

Re: [MERGE] Initial netfilter mark patch for comment

2010-09-04 Thread Andrew Beverley
On Fri, 2010-08-13 at 18:19 -0600, Alex Rousskov wrote:
 On 08/11/2010 03:25 PM, Andrew Beverley wrote:
 
  I've moved these, as well as most of the other QOS functions, into
  Ip::Qos. I have also removed the QosConfig namespace, as it didn't seem
  to fit with all these additional functions.
 
 * A patch preamble with the proposed commit message would be nice.
 
 * I am not sure what Qos class is. It is not documented. If it is a QOS 
 configuration class, I understand why we have a global instance of it, 
 but the original QosConfig name seems better in that case. If it is not 
 a configuration class, then I am not sure why we have a global instance 
 of it. And the QosConfig file name does not seem to match the class name 
 any more.
 
 Perhaps we need two classes, one for configuration and one for 
 manipulation? Or a Qos namespace with a configuration class and global 
 manipulation functions? The latter seems more likely.

The latter has now been implemented.

 * My understanding is that class data members and public class methods 
 should be documented in the header. Others should be documented in the 
 .cc files. You may want to double check this rule with Amos before 
 moving comments though.

Comments moved to the header in Doxygen format.

 * Many Qos data members are not documented, including new ones.

Now documented, and underscore removed from names.

 * Pass HierarchyLogEntry by const reference, avoid copying. Once that is 
 done, move #include HierarchyLogEntry.h to the .cc file.

Done.

 * Do you need #include fde.h in src/ip/QosConfig.h or can you 
 pre-declare fde and include fde.h in the .cc file?

Now pre-declared.

 * s/ 0/  0/

Done.

 * This code:
 
  +if (tos_local_hit || tos_sibling_hit || tos_parent_hit || 
  preserve_miss_tos) {
  +return true;
  +} else {
  +return false;
  +}
 
 can be simply written as
 
  return tos_local_hit || tos_sibling_hit || tos_parent_hit || 
 preserve_miss_tos;
 
 Same for Ip::Qos::isMarkActive code.

Done.

 
 * Ip::Qos::isTosActive and Ip::Qos::isMarkActive should be const. When 
 that is fixed, you would be able to return const to 
 Ip::Qos::dumpConfigLine, I guess.

Done.

 * Ip::Qos::getNfmarkLocalMiss and many other get*() methods should be const.
 

Most of these have now been moved out of classes.

 * What is the purpose of memsetting Qos members to zero in the 
 destructor? Please remove the destructor itself if there is no reason to 
 reset the memory before freeing it.

Removed.

 * Use Doxygen /// comments when documenting members, such as upstreamTOS.

Done.

 * Do you need an L suffix for large unsigned constants like 0x? 
 Please investigate. I do not know the answer, but I recall seeing such 
 suffixes elsewhere:
 http://www.google.com/search?q=0x+vs+0xL

From what I can gather, the suffix is important in places like 'if'
statements when there is no assignment to a variable with a type (so
that you are comparing like with like). Therefore, I have added the U
suffix to 'if' statements, but I see no need when assigning values to
defined variables (although there would of course be no harm in doing
so).

Regards,

Andy




Re: [MERGE] Initial netfilter mark patch for comment

2010-08-22 Thread Alex Rousskov

On 08/21/2010 05:45 PM, Henrik Nordström wrote:

lör 2010-08-21 klockan 23:41 +0100 skrev Andrew Beverley:


I have documented all the functions and class data members. Could you
clarify whether *every* variable should be documented with doxygen
comments (including short-lived temporary ones within functions), or
just those that are part of classes/structs?


classes/structs.

temporary variables if their use may not be obvious to someone else
reading your code, but preferably code in such shape that variable use
is obvious.


For example, should 'tos' in the function below have doxygen comments?


No need for that imho.


Agreed. Especially true if you select meaningful names for local 
variables (e.g., headerBuf instead of b or ipCount instead of c).



BTW, if the documentation comment simply spells out the variable name, 
it is worse than no comment. For example,


private:
int isFoo; /// whether we are Foo

is useless but something like

int isFoo; /// caller expects Bar in the result

may shed more light than the variable name itself. Perhaps my 
foo/bar-based example is too abstract to make sense, but try to explain 
what the variable/function does to a person who could not guess it 
correctly from the name alone or, if the name is really obvious/clear, 
supply additional information instead of repeating (spelling out) the name.



Also, there is no requirement to document API implementation methods in 
kids unless you want to:


/// such and such API
class Parent {
/// checks computations results for exceeding INT_MAX
virtual bool willFit() const = 0;
virtual int calc() = 0; /// ...
...
};

/// Foo and bar, using such and such API
class Child: pubic Parent {
...

/* Parent API */
virtual bool willFit() const;
virtual int calc();
...
};

HTH,

Alex.


Re: [MERGE] Initial netfilter mark patch for comment

2010-08-21 Thread Andrew Beverley
On Fri, 2010-08-20 at 12:44 -0600, Alex Rousskov wrote:
 On 08/20/2010 11:06 AM, Andrew Beverley wrote:
  On Fri, 2010-08-13 at 18:19 -0600, Alex Rousskov wrote:
  On 08/11/2010 03:25 PM, Andrew Beverley wrote:
 
  I've moved these, as well as most of the other QOS functions, into
  Ip::Qos. I have also removed the QosConfig namespace, as it didn't seem
  to fit with all these additional functions.
 
  * A patch preamble with the proposed commit message would be nice.
 
  * I am not sure what Qos class is. It is not documented. If it is a QOS
  configuration class, I understand why we have a global instance of it,
  but the original QosConfig name seems better in that case. If it is not
  a configuration class, then I am not sure why we have a global instance
  of it. And the QosConfig file name does not seem to match the class name
  any more.
 
  Perhaps we need two classes, one for configuration and one for
  manipulation? Or a Qos namespace with a configuration class and global
  manipulation functions? The latter seems more likely.
 
 
  I was trying to copy the approach used by the Interceptor class, which
  has its configuration variables and methods in one class, with a global
  instance of it. I thought that it would keep things nice and tidy by
  having all qos aspects in one single class (with the configuration
  variables within private space).
 
 Trust me, I feel your pain. Copying existing code on its own does not 
 guarantee much because a lot of code is broken, unfortunately. [ I am 
 not saying Interceptor class is or is not broken because I have not 
 reviewed it. ]
 
 
  I'm happy to go with whatever approach you want though, and can separate
  the config aspects back out from the functions.
 
  Before I go ahead and do this, I want to check which option I should go
  for. As Alex says, the options are:
 
  1)
  - Reinstate the QosConfig class with the configuration variables as
  public members
  - Create a new class (QosFunctions?) with the relevant functions in
  - Create one global instance of each class,
 
 Rule of thumb: If you can use a namespace instead of a class, use a 
 namespace. For example, classes that only group related stateless 
 functions are usually a bad idea.
 
 
   or alternatively create a
   new instance of the functions class each time the functions need to be
   accessed (is the latter inefficient?)
 
 It is difficult for me to imagine a worse design (one class/instance per 
 function, perhaps?), but I am sure you can find it in Squid :-).
 
 
  2)
  - Reinstate the QosConfig class with the configuration variables as
  public members
  - Create the functions as global functions in the namespace
 
 This is the best option if functions do not share or keep state.
 
 Please note that QosConfig should become Qos::Config once you add Qos 
 namespace.
 
 
  3)
  - Keep everything in one class :-)
 
 
  If going with option 2, the functions can no longer be const (which most
  of them currently are).
 
 Well, if your methods do not share or keep state, they should not be 
 const. They should be static! Const means I use but do not modify the 
 state of my object. And if a class has nothing but static methods, it 
 should be a namespace in most cases...
 
 
 In summary,
 
 * Work inside Qos namespace.
 
 * Keep configuration state (data) inside Qos::Config class. You can use 
 a single global Qos::TheConfig current configuration instance of that 
 class if needed.
 
 * Functions that exist to interpret or modify configuration should be 
 Qos::Config methods (const if possible).
 
 * Functions that wrap library calls or otherwise manipulate some 
 external state/data that they do not and cannot own should be declared 
 outside Qos::Config and inside Qos.
 
 * If there is a non-configuration state/data that you can encapsulate 
 and manipulate in a class setting, then create more Qos::* classes.

Thanks Alex. An excellent explanation. I fully understand now, and have
gone with option 2 as you suggest, just keeping the isActive functions
in the config class.

Updated patch to follow soon.

Andy




Re: [MERGE] Initial netfilter mark patch for comment

2010-08-21 Thread Andrew Beverley

 * My understanding is that class data members and public class methods 
 should be documented in the header. Others should be documented in the 
 .cc files. You may want to double check this rule with Amos before 
 moving comments though.
 
 * Many Qos data members are not documented, including new ones.
 

I have documented all the functions and class data members. Could you
clarify whether *every* variable should be documented with doxygen
comments (including short-lived temporary ones within functions), or
just those that are part of classes/structs?

For example, should 'tos' in the function below have doxygen comments?


int
Ip::Qos::doTosLocalMiss(const int fd, const HierarchyLogEntry *hier)
{
unsigned char tos = 0;
if (Ip::Qos::TheConfig.tos_sibling_hit  hier-code==SIBLING_HIT ) {
tos = Ip::Qos::TheConfig.tos_sibling_hit;
debugs(33, 2, QOS: Sibling Peer hit with hier code=  hier-code  
, TOS=  (int)tos);
} else if (Ip::Qos::TheConfig.tos_parent_hit  hier-code==PARENT_HIT) {
tos = Ip::Qos::TheConfig.tos_parent_hit;
debugs(33, 2, QOS: Parent Peer hit with hier code=  hier-code  
, TOS=  (int)tos);
} else if (Ip::Qos::TheConfig.preserve_miss_tos  
Ip::Qos::TheConfig.preserve_miss_tos_mask) { 
tos = fd_table[fd].upstreamTOS  
Ip::Qos::TheConfig.preserve_miss_tos_mask;
debugs(33, 2, QOS: Preserving TOS on miss, TOS=  int(tos));
}
return setSockTos(fd, tos);
}



Thanks,

Andy




Re: [MERGE] Initial netfilter mark patch for comment

2010-08-21 Thread Henrik Nordström
lör 2010-08-21 klockan 23:41 +0100 skrev Andrew Beverley:

 I have documented all the functions and class data members. Could you
 clarify whether *every* variable should be documented with doxygen
 comments (including short-lived temporary ones within functions), or
 just those that are part of classes/structs?

classes/structs.

temporary variables if their use may not be obvious to someone else
reading your code, but preferably code in such shape that variable use
is obvious.

 For example, should 'tos' in the function below have doxygen comments?

No need for that imho.

Regards
Henrik



Re: [MERGE] Initial netfilter mark patch for comment

2010-08-20 Thread Andrew Beverley
On Fri, 2010-08-13 at 18:19 -0600, Alex Rousskov wrote:
 On 08/11/2010 03:25 PM, Andrew Beverley wrote:
 
  I've moved these, as well as most of the other QOS functions, into
  Ip::Qos. I have also removed the QosConfig namespace, as it didn't seem
  to fit with all these additional functions.
 
 * A patch preamble with the proposed commit message would be nice.
 
 * I am not sure what Qos class is. It is not documented. If it is a QOS 
 configuration class, I understand why we have a global instance of it, 
 but the original QosConfig name seems better in that case. If it is not 
 a configuration class, then I am not sure why we have a global instance 
 of it. And the QosConfig file name does not seem to match the class name 
 any more.
 
 Perhaps we need two classes, one for configuration and one for 
 manipulation? Or a Qos namespace with a configuration class and global 
 manipulation functions? The latter seems more likely.
 

I was trying to copy the approach used by the Interceptor class, which
has its configuration variables and methods in one class, with a global
instance of it. I thought that it would keep things nice and tidy by
having all qos aspects in one single class (with the configuration
variables within private space).

I'm happy to go with whatever approach you want though, and can separate
the config aspects back out from the functions.

Before I go ahead and do this, I want to check which option I should go
for. As Alex says, the options are:

1)
- Reinstate the QosConfig class with the configuration variables as
public members
- Create a new class (QosFunctions?) with the relevant functions in
- Create one global instance of each class, or alternatively create a
new instance of the functions class each time the functions need to be
accessed (is the latter inefficient?)

2)
- Reinstate the QosConfig class with the configuration variables as
public members
- Create the functions as global functions in the namespace

3)
- Keep everything in one class :-)


If going with option 2, the functions can no longer be const (which most
of them currently are).

Thanks,

Andy




Re: [MERGE] Initial netfilter mark patch for comment

2010-08-17 Thread Amos Jeffries


Andrew,
 Seems the netfilter guys found a major problem with strtoul(). 
Thankfully the same fix should work for us as well.



Luciano Coelho wrote:
snip

 Not easily.  I found that there is a bug in strtoul (and strtoull for
 that matter) that causes the long to overflow if there are valid digits
 after the maximum possible digits for the base.  For example if you try
 to strtoul 0xf (with 9 f's) the strtoul will overflow and come
 up with a bogus result.  I can't easily truncate the string to avoid
 this problem, because with decimal or octal, the same valid value would
 take more spaces.  I could do some magic here, checking whether it's a
 hex, dec or oct and truncate appropriately, but that would be very ugly.

 So the simplest way I came up with was to use strtoull and return
 -EINVAL if the value exceeds 32 bits. ;)




Amos
--
Please be using
  Current Stable Squid 2.7.STABLE9 or 3.1.6
  Beta testers wanted for 3.2.0.1


Re: [MERGE] Initial netfilter mark patch for comment

2010-08-17 Thread Andrew Beverley
   Seems the netfilter guys found a major problem with strtoul(). 
 Thankfully the same fix should work for us as well.
 
 
 Luciano Coelho wrote:
 snip
  
   Not easily.  I found that there is a bug in strtoul (and strtoull for
   that matter) that causes the long to overflow if there are valid digits
   after the maximum possible digits for the base.  For example if you try
   to strtoul 0xf (with 9 f's) the strtoul will overflow and come
   up with a bogus result.  I can't easily truncate the string to avoid
   this problem, because with decimal or octal, the same valid value would
   take more spaces.  I could do some magic here, checking whether it's a
   hex, dec or oct and truncate appropriately, but that would be very ugly.
  
   So the simplest way I came up with was to use strtoull and return
   -EINVAL if the value exceeds 32 bits. ;)
  

Thanks for that Amos. I have to admit that when I was doing my initial
browse of the iptables mark module, I noticed that they had their own
xtables_strtoui function which limited the size. I'll check this out a
bit more thoroughly.

I'm away at the moment with minimal internet access, but I hope to pick
up again on the patch shortly.

Cheers,

Andy




Re: [MERGE] Initial netfilter mark patch for comment

2010-08-13 Thread Alex Rousskov

On 08/11/2010 03:25 PM, Andrew Beverley wrote:


I've moved these, as well as most of the other QOS functions, into
Ip::Qos. I have also removed the QosConfig namespace, as it didn't seem
to fit with all these additional functions.


* A patch preamble with the proposed commit message would be nice.

* I am not sure what Qos class is. It is not documented. If it is a QOS 
configuration class, I understand why we have a global instance of it, 
but the original QosConfig name seems better in that case. If it is not 
a configuration class, then I am not sure why we have a global instance 
of it. And the QosConfig file name does not seem to match the class name 
any more.


Perhaps we need two classes, one for configuration and one for 
manipulation? Or a Qos namespace with a configuration class and global 
manipulation functions? The latter seems more likely.


* My understanding is that class data members and public class methods 
should be documented in the header. Others should be documented in the 
.cc files. You may want to double check this rule with Amos before 
moving comments though.


* Many Qos data members are not documented, including new ones.

* Pass HierarchyLogEntry by const reference, avoid copying. Once that is 
done, move #include HierarchyLogEntry.h to the .cc file.


* Do you need #include fde.h in src/ip/QosConfig.h or can you 
pre-declare fde and include fde.h in the .cc file?


* s/ 0/  0/

* This code:


+if (tos_local_hit || tos_sibling_hit || tos_parent_hit || 
preserve_miss_tos) {
+return true;
+} else {
+return false;
+}


can be simply written as

return tos_local_hit || tos_sibling_hit || tos_parent_hit || 
preserve_miss_tos;


Same for Ip::Qos::isMarkActive code.


* Ip::Qos::isTosActive and Ip::Qos::isMarkActive should be const. When 
that is fixed, you would be able to return const to 
Ip::Qos::dumpConfigLine, I guess.


* Ip::Qos::getNfmarkLocalMiss and many other get*() methods should be const.


* What is the purpose of memsetting Qos members to zero in the 
destructor? Please remove the destructor itself if there is no reason to 
reset the memory before freeing it.


* Use Doxygen /// comments when documenting members, such as upstreamTOS.

* Do you need an L suffix for large unsigned constants like 0x? 
Please investigate. I do not know the answer, but I recall seeing such 
suffixes elsewhere:

http://www.google.com/search?q=0x+vs+0xL


Thank you,

Alex.



Re: [MERGE] Initial netfilter mark patch for comment

2010-08-13 Thread Amos Jeffries

Alex Rousskov wrote:

On 08/11/2010 03:25 PM, Andrew Beverley wrote:


I've moved these, as well as most of the other QOS functions, into
Ip::Qos. I have also removed the QosConfig namespace, as it didn't seem
to fit with all these additional functions.


* A patch preamble with the proposed commit message would be nice.

* I am not sure what Qos class is. It is not documented. If it is a QOS 
configuration class, I understand why we have a global instance of it, 
but the original QosConfig name seems better in that case. If it is not 
a configuration class, then I am not sure why we have a global instance 
of it. And the QosConfig file name does not seem to match the class name 
any more.


Perhaps we need two classes, one for configuration and one for 
manipulation? Or a Qos namespace with a configuration class and global 
manipulation functions? The latter seems more likely.


* My understanding is that class data members and public class methods 
should be documented in the header. Others should be documented in the 
.cc files. You may want to double check this rule with Amos before 
moving comments though.


true.



* Many Qos data members are not documented, including new ones.

* Pass HierarchyLogEntry by const reference, avoid copying. Once that is 
done, move #include HierarchyLogEntry.h to the .cc file.


* Do you need #include fde.h in src/ip/QosConfig.h or can you 
pre-declare fde and include fde.h in the .cc file?


* s/ 0/  0/

* This code:

+if (tos_local_hit || tos_sibling_hit || tos_parent_hit || 
preserve_miss_tos) {

+return true;
+} else {
+return false;
+}


can be simply written as

return tos_local_hit || tos_sibling_hit || tos_parent_hit || 
preserve_miss_tos;


Same for Ip::Qos::isMarkActive code.


NP: with () brackets for easier reading of the compound statement please.




* Ip::Qos::isTosActive and Ip::Qos::isMarkActive should be const. When 
that is fixed, you would be able to return const to 
Ip::Qos::dumpConfigLine, I guess.


* Ip::Qos::getNfmarkLocalMiss and many other get*() methods should be 
const.



* What is the purpose of memsetting Qos members to zero in the 
destructor? Please remove the destructor itself if there is no reason to 
reset the memory before freeing it.


* Use Doxygen /// comments when documenting members, such as upstreamTOS.

* Do you need an L suffix for large unsigned constants like 0x? 
Please investigate. I do not know the answer, but I recall seeing such 
suffixes elsewhere:

http://www.google.com/search?q=0x+vs+0xL


I thought that indicated long type to be used. When stored as 64-bit 
values.


Which brings up a question of whether it really is an architecture 
dependent int field or uint32_t for mark.


Amos
--
Please be using
  Current Stable Squid 2.7.STABLE9 or 3.1.6
  Beta testers wanted for 3.2.0.1


Re: [MERGE] Initial netfilter mark patch for comment

2010-08-12 Thread Andrew Beverley
  stub* are cut down set of all non-inline Ip::QosConfig methods and any 
  globals defined in QosConfig.h. Changes to the API need to be mirrored 
  there. The functions inside usually call fatal() to alert a wrong 
  linkage clearly during testing. In this particular case the parse 
  function will need to be duplicated there.
  
  Sorry, I need some clarification on this. I've looked at most of the
  other stub files, and most of the functions do indeed just return
  fatal(). However, the existing stubQosConfig.cc is almost identical to
  QosConfig.cc, with almost all of its code. Shall I change the functions
  to fatal()?
  
  Presumably I should add all the new functions into it (getTosLocalMiss,
  getNfmarkLocalMiss, getTosLocalHit, getNfmarkLocalHit, getUpstreamTOS,
  getUpstreamNfMark, isTosActive, isMarkActive, GetNfMarkCallback)?
 
 It does need another looking at and possibly stripping down. IIRC it was
 there from when QosConfig was a member of SquidConfig. I'll run a quick
 check myself now to see what breaks in the current usage if the currently
 defined stubs are stripped down.
 
 You will need to add the appropriate dead-end stubs for the new functions.

Okay, I'll work on a stripped down fatal() for the time being.

  I've moved these, as well as most of the other QOS functions, into
  Ip::Qos. I have also removed the QosConfig namespace, as it didn't seem
  to fit with all these additional functions.
 
 We are moving the rest of Squid in general towards a model of
 Namespace::TheConfig containing the config data values pulled from
 squid.conf separate from the code which utilizes them.
 
 Please wait for Alex as well on this particular change.

I did consider having the config values in a separate Config class, and
I'm happy to change to this, I just thought that it was neater having
them in the same class. It also means that the configuration values do
not need to be public, which I thought was generally a Good Thing.

 My thoughts on it are these;
 
 I like the moving of functions to IP::Qos including the existing ones.
 Under the coding guidelines the existence of class Qos calls for it to be
 in a file src/ip/Qos.h and .cc.
 Several of the functions particularly the is*Active() can be inlined for
 better performance with _SQUID_INLINE_, which calls for a ip/Qos.cci file
 to define them and be conditionally included in the .h or .cc based on #if
 _USE_INLINE_.

No problem. My initial thoughts are that I should do get*LocalMiss,
get*LocalHit and is*Active (and possibly the new set functions).

 Some set*Mark and set*Tos functions woudl round out the API. To take the
 same parameters as the get*() ones, but which do the perform the
 setsockopt. So that paired lines of:
 unsigned int mark = Ip::Qos.getNfmarkLocalMiss(fd,
 http-request-hier);
 comm_set_nfmark(fd,mark);
 become
 Ip::Qos.setNfmarkLocalMiss(fd, http-request-hier);
 
 ... and thus comm.cc does not need anything about the MARK setsockopt.
 Mirroring the way it has nothing to do with the MARK/TOS getsockopt etc.

I like that; I'll make the changes. I guess there is then no need for
getTosLocalHit() and getNfMarkLocalHit(), as all they do is return the
appropriate private variables, although I could leave them there to keep
everything consistent.

  
  I've carried out a fair bit of testing on the mark functionality today,
  and It Works For Me, but I'll be able to try it better in a production
  server in the coming weeks.
  
  Could you let me know if/what else I need to do before acceptance. I
  believe there are the following:
  
  - Confirm and implement stub function requirements
  - Factor the configure.in changes into Kinkie's autoconf-refactor?
 
 Those are the big ones. Along with getting the namespace change approved.
 
 The reconfigure straightening will change your dependency logic model a
 bit. Specifically such that the absence of --with-netfilter-conntrack
 (implicit / auto-detect case) results in the same auto-detect currently
 only done by explicit yes results, but which does not terminate in
 AC_MSG_ERROR.

No problem. Any idea when the autoconf-refactor will appear in trunk?

Andy




Re: [MERGE] Initial netfilter mark patch for comment

2010-08-12 Thread Amos Jeffries

Andrew Beverley wrote:
stub* are cut down set of all non-inline Ip::QosConfig methods and any 
globals defined in QosConfig.h. Changes to the API need to be mirrored 
there. The functions inside usually call fatal() to alert a wrong 
linkage clearly during testing. In this particular case the parse 
function will need to be duplicated there.

Sorry, I need some clarification on this. I've looked at most of the
other stub files, and most of the functions do indeed just return
fatal(). However, the existing stubQosConfig.cc is almost identical to
QosConfig.cc, with almost all of its code. Shall I change the functions
to fatal()?

Presumably I should add all the new functions into it (getTosLocalMiss,
getNfmarkLocalMiss, getTosLocalHit, getNfmarkLocalHit, getUpstreamTOS,
getUpstreamNfMark, isTosActive, isMarkActive, GetNfMarkCallback)?

It does need another looking at and possibly stripping down. IIRC it was
there from when QosConfig was a member of SquidConfig. I'll run a quick
check myself now to see what breaks in the current usage if the currently
defined stubs are stripped down.

You will need to add the appropriate dead-end stubs for the new functions.


Okay, I'll work on a stripped down fatal() for the time being.


I've moved these, as well as most of the other QOS functions, into
Ip::Qos. I have also removed the QosConfig namespace, as it didn't seem
to fit with all these additional functions.

We are moving the rest of Squid in general towards a model of
Namespace::TheConfig containing the config data values pulled from
squid.conf separate from the code which utilizes them.

Please wait for Alex as well on this particular change.


I did consider having the config values in a separate Config class, and
I'm happy to change to this, I just thought that it was neater having
them in the same class. It also means that the configuration values do
not need to be public, which I thought was generally a Good Thing.


Yes. We've thrown various ideas about how to do a live zero-downtime 
reconfigure around. TheConfig were working towards those. That set are 
in the gap really. I suppose it depends on it matters if one of the 
marks is set at the top of a big config and another at the end.


The way you have them as privates for now should be okay. Worst case we 
abstract to a public again later as needed.





My thoughts on it are these;

I like the moving of functions to IP::Qos including the existing ones.
Under the coding guidelines the existence of class Qos calls for it to be
in a file src/ip/Qos.h and .cc.
Several of the functions particularly the is*Active() can be inlined for
better performance with _SQUID_INLINE_, which calls for a ip/Qos.cci file
to define them and be conditionally included in the .h or .cc based on #if
_USE_INLINE_.


No problem. My initial thoughts are that I should do get*LocalMiss,
get*LocalHit and is*Active (and possibly the new set functions).


Some set*Mark and set*Tos functions woudl round out the API. To take the
same parameters as the get*() ones, but which do the perform the
setsockopt. So that paired lines of:
unsigned int mark = Ip::Qos.getNfmarkLocalMiss(fd,
http-request-hier);
comm_set_nfmark(fd,mark);
become
Ip::Qos.setNfmarkLocalMiss(fd, http-request-hier);

... and thus comm.cc does not need anything about the MARK setsockopt.
Mirroring the way it has nothing to do with the MARK/TOS getsockopt etc.


I like that; I'll make the changes. I guess there is then no need for
getTosLocalHit() and getNfMarkLocalHit(), as all they do is return the
appropriate private variables, although I could leave them there to keep
everything consistent.


Hmm, if they are fully unused then it makes more sense to drop and call 
the set*() methods do*().





I've carried out a fair bit of testing on the mark functionality today,
and It Works For Me, but I'll be able to try it better in a production
server in the coming weeks.

Could you let me know if/what else I need to do before acceptance. I
believe there are the following:

- Confirm and implement stub function requirements
- Factor the configure.in changes into Kinkie's autoconf-refactor?

Those are the big ones. Along with getting the namespace change approved.

The reconfigure straightening will change your dependency logic model a
bit. Specifically such that the absence of --with-netfilter-conntrack
(implicit / auto-detect case) results in the same auto-detect currently
only done by explicit yes results, but which does not terminate in
AC_MSG_ERROR.


No problem. Any idea when the autoconf-refactor will appear in trunk?


Um two days ago. :)

Sign of a good clean merge: nobody notices.

Amos
--
Please be using
  Current Stable Squid 2.7.STABLE9 or 3.1.6
  Beta testers wanted for 3.2.0.1


Re: [MERGE] Initial netfilter mark patch for comment

2010-08-11 Thread Andrew Beverley
Updated patch attached; comments below.

  If we can move to strtoul, I would like to change 'tos' to char
  throughout. Currently it is possible to set it to invalid values in
  squid.conf, which then cause problems with dumpConfigLine.
  
  Question number 2: what is stubQosConfig.cc? Does that also need
  updating for this patch?
  
 
 stub* are cut down set of all non-inline Ip::QosConfig methods and any 
 globals defined in QosConfig.h. Changes to the API need to be mirrored 
 there. The functions inside usually call fatal() to alert a wrong 
 linkage clearly during testing. In this particular case the parse 
 function will need to be duplicated there.

Sorry, I need some clarification on this. I've looked at most of the
other stub files, and most of the functions do indeed just return
fatal(). However, the existing stubQosConfig.cc is almost identical to
QosConfig.cc, with almost all of its code. Shall I change the functions
to fatal()?

Presumably I should add all the new functions into it (getTosLocalMiss,
getNfmarkLocalMiss, getTosLocalHit, getNfmarkLocalHit, getUpstreamTOS,
getUpstreamNfMark, isTosActive, isMarkActive, GetNfMarkCallback)?

 I have failed to find any problems with strtoul. Looks like it can be 
 used. Although we may have to find a GPLv2 compatible implementation.

I have kept the strtoul parts, and changed (almost) all of the tos
variables to unsigned char.

 
 In this version the new methods look they should be in the Ip::Qos 
 namespace.
 
   * the new clientReplyContext::tosLocalMissValue() and 
 clientReplyContext::nfmarkLocalMissValue() methods particularly look 
 like they really should take the hier code as a second parameter. Both 
 fd and the hier if passed in should be const.

I've moved them to Ip::Qos and added the parameters as const.

   * the new FwdState getUpstream* methods are in a similar position but 
 not quite so clear cut. If you can find  way to cleanly move them there 
 great, otherwise it's not so much a bit deal yet.

I've moved these, as well as most of the other QOS functions, into
Ip::Qos. I have also removed the QosConfig namespace, as it didn't seem
to fit with all these additional functions.

 * Thank you for the extra documentation on comm_set_tos().
 
 * Please remove the bits touching comm_set_v6only() its 'tos' field is 
 not related to QoS. Just acronym confusion.

My mistake, removed.

I've carried out a fair bit of testing on the mark functionality today,
and It Works For Me, but I'll be able to try it better in a production
server in the coming weeks.

Could you let me know if/what else I need to do before acceptance. I
believe there are the following:

- Confirm and implement stub function requirements
- Factor the configure.in changes into Kinkie's autoconf-refactor?

Regards,

Andy

=== modified file 'configure.in'
--- configure.in	2010-08-10 15:37:53 +
+++ configure.in	2010-08-11 13:32:45 +
@@ -1112,6 +1112,34 @@
 fi
 AC_SUBST(SSLLIB)
 
+dnl Allow user to specify libnetfilter_conntrack (needed for QOS netfilter marking)
+AC_ARG_WITH(netfilter-conntrack,
+  AS_HELP_STRING([--with-netfilter-conntrack=PATH],
+ [Compile with the Netfilter conntrack libraries. The path to
+  the development libraries and headers
+  installation can be specified if outside of the
+  system standard directories]), [ 
+case $with_netfilter_conntrack in
+  no)
+: # Nothing special to do here
+;;
+  yes)
+AC_CHECK_LIB([netfilter_conntrack], [nfct_query],,
+  AC_MSG_ERROR([libnetfilter-conntrack library not found. Needed for netfilter-conntrack support]),
+  [-lnetfilter_conntrack])
+AC_CHECK_HEADERS([libnetfilter_conntrack/libnetfilter_conntrack.h \
+  libnetfilter_conntrack/libnetfilter_conntrack_tcp.h])
+;;
+  *)  
+if test ! -d $withval ; then
+  AC_MSG_ERROR([--with-netfilter-conntrack path does not point to a directory])
+fi
+LDFLAGS=-L$with_netfilter_conntrack/lib $LDFLAGS
+CPPFLAGS=-I$with_netfilter_conntrack/include $CPPFLAGS
+with_netfilter_conntrack=yes
+;;
+  esac
+])
 
 AC_ARG_ENABLE(forw-via-db,
   AS_HELP_STRING([--enable-forw-via-db],[Enable Forw/Via database]), [
@@ -1990,10 +2018,19 @@
 SQUID_YESNO([$enableval],
 [unrecognized argument to --enable-zph-qos: $enableval])
 ])
-SQUID_DEFINE_BOOL(USE_ZPH_QOS,${enable_zph_qos:=no},
+SQUID_DEFINE_BOOL(USE_QOS_TOS,${enable_zph_qos:=no},
   [Enable Zero Penalty Hit QOS. When set, Squid will alter the
TOS field of HIT responses to help policing network traffic])
 AC_MSG_NOTICE([ZPH QOS enabled: $enable_zph_qos])
+if test $enable_zph_qos = yes ; then
+if test $with_netfilter_conntrack = yes ; then
+AC_MSG_NOTICE([QOS netfilter marking enabled: $with_netfilter_conntrack])
+SQUID_DEFINE_BOOL(USE_QOS_NFMARK,$with_netfilter_conntrack,
+  [Enable support for QOS 

Re: [MERGE] Initial netfilter mark patch for comment

2010-08-11 Thread Amos Jeffries
On Wed, 11 Aug 2010 22:25:45 +0100, Andrew Beverley a...@andybev.com
wrote:
 Updated patch attached; comments below.
 
  If we can move to strtoul, I would like to change 'tos' to char
  throughout. Currently it is possible to set it to invalid values in
  squid.conf, which then cause problems with dumpConfigLine.
  
  Question number 2: what is stubQosConfig.cc? Does that also need
  updating for this patch?
  
 
 stub* are cut down set of all non-inline Ip::QosConfig methods and any 
 globals defined in QosConfig.h. Changes to the API need to be mirrored 
 there. The functions inside usually call fatal() to alert a wrong 
 linkage clearly during testing. In this particular case the parse 
 function will need to be duplicated there.
 
 Sorry, I need some clarification on this. I've looked at most of the
 other stub files, and most of the functions do indeed just return
 fatal(). However, the existing stubQosConfig.cc is almost identical to
 QosConfig.cc, with almost all of its code. Shall I change the functions
 to fatal()?
 
 Presumably I should add all the new functions into it (getTosLocalMiss,
 getNfmarkLocalMiss, getTosLocalHit, getNfmarkLocalHit, getUpstreamTOS,
 getUpstreamNfMark, isTosActive, isMarkActive, GetNfMarkCallback)?

It does need another looking at and possibly stripping down. IIRC it was
there from when QosConfig was a member of SquidConfig. I'll run a quick
check myself now to see what breaks in the current usage if the currently
defined stubs are stripped down.

You will need to add the appropriate dead-end stubs for the new functions.


 
 In this version the new methods look they should be in the Ip::Qos 
 namespace.
 
   * the new clientReplyContext::tosLocalMissValue() and 
 clientReplyContext::nfmarkLocalMissValue() methods particularly look 
 like they really should take the hier code as a second parameter. Both 
 fd and the hier if passed in should be const.
 
 I've moved them to Ip::Qos and added the parameters as const.
 
   * the new FwdState getUpstream* methods are in a similar position but

 not quite so clear cut. If you can find  way to cleanly move them there

 great, otherwise it's not so much a bit deal yet.
 
 I've moved these, as well as most of the other QOS functions, into
 Ip::Qos. I have also removed the QosConfig namespace, as it didn't seem
 to fit with all these additional functions.

We are moving the rest of Squid in general towards a model of
Namespace::TheConfig containing the config data values pulled from
squid.conf separate from the code which utilizes them.

Please wait for Alex as well on this particular change.

My thoughts on it are these;

I like the moving of functions to IP::Qos including the existing ones.
Under the coding guidelines the existence of class Qos calls for it to be
in a file src/ip/Qos.h and .cc.
Several of the functions particularly the is*Active() can be inlined for
better performance with _SQUID_INLINE_, which calls for a ip/Qos.cci file
to define them and be conditionally included in the .h or .cc based on #if
_USE_INLINE_.

Some set*Mark and set*Tos functions woudl round out the API. To take the
same parameters as the get*() ones, but which do the perform the
setsockopt. So that paired lines of:
unsigned int mark = Ip::Qos.getNfmarkLocalMiss(fd,
http-request-hier);
comm_set_nfmark(fd,mark);
become
Ip::Qos.setNfmarkLocalMiss(fd, http-request-hier);

... and thus comm.cc does not need anything about the MARK setsockopt.
Mirroring the way it has nothing to do with the MARK/TOS getsockopt etc.

 
 I've carried out a fair bit of testing on the mark functionality today,
 and It Works For Me, but I'll be able to try it better in a production
 server in the coming weeks.
 
 Could you let me know if/what else I need to do before acceptance. I
 believe there are the following:
 
 - Confirm and implement stub function requirements
 - Factor the configure.in changes into Kinkie's autoconf-refactor?

Those are the big ones. Along with getting the namespace change approved.

The reconfigure straightening will change your dependency logic model a
bit. Specifically such that the absence of --with-netfilter-conntrack
(implicit / auto-detect case) results in the same auto-detect currently
only done by explicit yes results, but which does not terminate in
AC_MSG_ERROR.

Amos


Re: [MERGE] Initial netfilter mark patch for comment

2010-08-07 Thread Andrew Beverley
On Mon, 2010-08-02 at 12:03 -0600, Alex Rousskov wrote: 
 On 08/01/2010 05:47 PM, Andrew Beverley wrote:
  Please find attached the first version of the netfilter mark patch. I've
  not yet tested it extensively, but would welcome some initial feedback
  or comments.

Thanks for the prompt reply. Please find attached an updated version of
the patch, which includes fixes to all the feedback below. It remains
not-extensively tested, but is attached for further comments.

 * It would be nice to get a proposed commit message describing the 
 changes as a patch preamble. Among other things, this will allow 
 reviewers to understand the overall scope and intent of your work.

Sorry about that, this is new to me. As you've probably gathered, the
aim of this patch is to implement the existing TOS functionality, but as
netfilter marking.

 * comm_set_mark() has a very generic name. Many things can be marked, 
 for many reasons. Can you come up with a better, more specific one?

Renamed to comm_set_nfmark.

 * comm_set_mark() is not documented but is a part of the public Comm API.
 

Now documented in the source code. Is that the only place to document?

 * getNfctMark() definition #ifdef conditions are inconsistent with its 
 declaration and use #ifdefs.

Fixed.

 * getNfctMark() is static but does not start with a capital letter.

Fixed.

 * getNfctMark() might belong to fde rather than FwdState because it does 
 not use FwdState. I am not sure about this one, but it may indicate a 
 general design problem -- a callback with no connection to the caller.

I thought about moving to fde, but I feel it sits better in FwdState as
although it is not called directly within it, it is called as a result
of other code in there.

getNfctMark() has been renamed to GetNfMarkCallback

 * Please document who calls getNfctMark() and when.
 

Comments added.

 * If getNfctMark() is an async callback that will be called some time 
 after the nfct_callback_register returns, how do you know that clientFde 
 is still a valid pointer _and_ is pointing to the same connection 
 information?
 
 * If getNfctMark() is an async callback that will be called at some 
 random time after the nfct_callback_register returns, is it safe to use 
 debugs()?

I'm pretty sure it's synchronous: if I add a 3 second delay in the
callback, then the rest of the code isn't executed until the callback
has finished, and the conntrack information is still found.

 * Please use Doxygen /** or /// comments for method descriptions.
 

Fixed.

 * Please declare local variables when you first use them, if possible. 
 For example,

Fixed.

 * Please add a comment why ct = nfct_new() is not leaking memory despite 
 no matching delete/free OR fix the leak.

nfct_destory() added. Thanks for pointing this out.

 * upstreamMark member documentation should be fixed. What does that 
 member store/mean? I understand that you were copying the documentation 
 bug from upstreamTOS, but I hope we do not have to replicate that.

upstreamMark and upstreamTOS fixed.

 * Please break out new code into a new FwdState method(s) instead of 
 making FwdState::dispatch longer and uglier.

I have added 2 new methods: getUpstreamTOS() and getUpstreamNfMark()

 * Same comment applies to src/client_side_reply.cc code, including the 
 old QOS code already there. It should be extracted from regular methods 
 as they are getting difficult to follow, especially with all the ifdefs.

I have added tosLocalMissValue() and nfmarkLocalMissValue()

 * The new code implements a non-critical feature because errors do not 
 terminate transactions. Yet, most errors are reported at level 1 to 
 cache.log. We often have to modify the code to remove excessive 
 cache.log pollution because it hurts busy proxies. Do you need to use 
 level-1 reporting? Of every error? Or perhaps the code should just 
 increment some stats counters?

I have moved most of the general errors to level 2.

 * Is there a way to defer most support checks to runtime (like 
 comm_set_mark does it), to minimize the use of #ifdefs in the core code? 
 For example, can we use one #ifdef variable for both USE_QOS_NFMARK and 
 USE_ZPH_QOS code, in most contexts? They are intermixed in the code in a 
 complex ways that I find difficult to follow.

I have simplified this and removed as many as possible. I have added
isTosActive() and isMarkActive() as suggested by Amos, and used these
instead. Some of the code relies on the libnetfilter_conntrack
libraries, so I have had to keep that inside #ifdefs.

This leads me on to my first question: why not just remove USE_ZPH_QOS
and the compilation option --enable-zph-qos? With the attached patch,
the code only runs when specified in squid.conf, and it has no other
dependencies. The ZPH kernel patch part can remain in the _SQUID_LINUX
tests.

 * The USE_QOS_NFMARK and USE_ZPH_QOS naming seems inconsistent.
 

I have renamed USE_ZPH_QOS to USE_QOS_TOS. However, see my question
above.

 The above review 

Re: [MERGE] Initial netfilter mark patch for comment

2010-08-02 Thread Alex Rousskov

On 08/01/2010 05:47 PM, Andrew Beverley wrote:

Please find attached the first version of the netfilter mark patch. I've
not yet tested it extensively, but would welcome some initial feedback
or comments.


* It would be nice to get a proposed commit message describing the 
changes as a patch preamble. Among other things, this will allow 
reviewers to understand the overall scope and intent of your work.


* comm_set_mark() has a very generic name. Many things can be marked, 
for many reasons. Can you come up with a better, more specific one?


* comm_set_mark() is not documented but is a part of the public Comm API.


* getNfctMark() definition #ifdef conditions are inconsistent with its 
declaration and use #ifdefs.


* getNfctMark() is static but does not start with a capital letter.

* getNfctMark() might belong to fde rather than FwdState because it does 
not use FwdState. I am not sure about this one, but it may indicate a 
general design problem -- a callback with no connection to the caller.


* Please document who calls getNfctMark() and when.

* If getNfctMark() is an async callback that will be called some time 
after the nfct_callback_register returns, how do you know that clientFde 
is still a valid pointer _and_ is pointing to the same connection 
information?


* If getNfctMark() is an async callback that will be called at some 
random time after the nfct_callback_register returns, is it safe to use 
debugs()?


* Please use Doxygen /** or /// comments for method descriptions.

* Please declare local variables when you first use them, if possible. 
For example,


+ struct nf_conntrack *ct;
+ ct = nfct_new();
+ if (ct) {

should be written as

  if (struct nf_conntrack *ct = nfct_new()) {


The struct nfct_handle *h case is much worse as the declaration and 
use are very far apart.




* Please add a comment why ct = nfct_new() is not leaking memory despite 
no matching delete/free OR fix the leak.


* upstreamMark member documentation should be fixed. What does that 
member store/mean? I understand that you were copying the documentation 
bug from upstreamTOS, but I hope we do not have to replicate that.


* Please break out new code into a new FwdState method(s) instead of 
making FwdState::dispatch longer and uglier.


* Same comment applies to src/client_side_reply.cc code, including the 
old QOS code already there. It should be extracted from regular methods 
as they are getting difficult to follow, especially with all the ifdefs.


* The new code implements a non-critical feature because errors do not 
terminate transactions. Yet, most errors are reported at level 1 to 
cache.log. We often have to modify the code to remove excessive 
cache.log pollution because it hurts busy proxies. Do you need to use 
level-1 reporting? Of every error? Or perhaps the code should just 
increment some stats counters?


* Is there a way to defer most support checks to runtime (like 
comm_set_mark does it), to minimize the use of #ifdefs in the core code? 
For example, can we use one #ifdef variable for both USE_QOS_NFMARK and 
USE_ZPH_QOS code, in most contexts? They are intermixed in the code in a 
complex ways that I find difficult to follow.


* The USE_QOS_NFMARK and USE_ZPH_QOS naming seems inconsistent.

The above review does not answer your questions below, and I am sorry 
for that. I hope Amos or others do better. I agree with many Amos' 
comments, and I especially encourage you to reduce and simplify #ifs and 
#ifdefs if possible, following Amos' hints.


Thank you,

Alex.



My comments are:

- The existing TOS patch cannot be disabled at runtime. As such, this
mark patch cannot be either. Would it be preferable to only enable them
both if the qos_flows config option is present? This would also have the
advantage of being able to add CAP_NET_ADMIN as appropriate at runtime.

- I have used sscanf instead of strtoul for both TOS and MARK in
QosConfig.cc (sscanf doesn't auto-detect the format of unsigned long
int). As a result, the tos variable could be changed to type char, which
is what it should be in my opinion. Should I do this?

- The code in forward.cc to obtain all the data needed to locate the
connection information is messy. Is there a better way to achieve it?
Conntrack needs to be passed local and remote port numbers and IP
addresses.

Is it too late to get this in v3.2? I will update the appropriate
release-notes once I know.


[MERGE] Initial netfilter mark patch for comment

2010-08-01 Thread Andrew Beverley
Please find attached the first version of the netfilter mark patch. I've
not yet tested it extensively, but would welcome some initial feedback
or comments.

My comments are:

- The existing TOS patch cannot be disabled at runtime. As such, this
mark patch cannot be either. Would it be preferable to only enable them
both if the qos_flows config option is present? This would also have the
advantage of being able to add CAP_NET_ADMIN as appropriate at runtime.

- I have used sscanf instead of strtoul for both TOS and MARK in
QosConfig.cc (sscanf doesn't auto-detect the format of unsigned long
int). As a result, the tos variable could be changed to type char, which
is what it should be in my opinion. Should I do this?

- The code in forward.cc to obtain all the data needed to locate the
connection information is messy. Is there a better way to achieve it?
Conntrack needs to be passed local and remote port numbers and IP
addresses.

Is it too late to get this in v3.2? I will update the appropriate
release-notes once I know.

Thanks,

Andy

# Bazaar merge directive format 2 (Bazaar 0.90)
# revision_id: a...@andybev.com-20100801233324-uoy4sp2e3uszw5qn
# target_branch: file:///home/andrew/squid-repo/trunk/
# testament_sha1: 4bd1e0b517dc3322fa114f30fb26ff2483cb3410
# timestamp: 2010-08-02 00:34:42 +0100
# base_revision_id: squ...@treenet.co.nz-20100801134158-\
#   vhc003yv3ikwao7e
# 
# Begin patch
=== modified file 'configure.in'
--- configure.in	2010-08-01 06:29:48 +
+++ configure.in	2010-08-01 20:09:13 +
@@ -1146,6 +1146,32 @@
 fi
 AC_SUBST(SSLLIB)
 
+dnl Allow user to specify libnetfilter_conntrack (needed for QOS netfilter marking)
+AC_ARG_WITH(netfilter-conntrack,
+  AS_HELP_STRING([--with-netfilter-conntrack=PATH],
+ [Compile with the Netfilter conntrack libraries. The path to
+  the development libraries and headers
+  installation can be specified if outside of the
+  system standard directories]), [ 
+case $with_netfilter_conntrack in
+  no)
+: # Nothing special to do here
+;;
+  yes)
+AC_CHECK_LIB([netfilter_conntrack], [nfct_query],,
+  AC_MSG_ERROR([libnetfilter-conntrack library not found. Needed for netfilter-conntrack support]),
+  [-lnetfilter_conntrack])
+;;
+  *)  
+if test ! -d $withval ; then
+  AC_MSG_ERROR([--with-netfilter-conntrack path does not point to a directory])
+fi
+LDFLAGS=-L$with_netfilter_conntrack/lib $LDFLAGS
+CPPFLAGS=-I$with_netfilter_conntrack/include $CPPFLAGS
+with_netfilter_conntrack=yes
+;;
+  esac
+])
 
 AC_ARG_ENABLE(forw-via-db,
   AS_HELP_STRING([--enable-forw-via-db],[Enable Forw/Via database]), [
@@ -2061,6 +2087,15 @@
   [Enable Zero Penalty Hit QOS. When set, Squid will alter the
TOS field of HIT responses to help policing network traffic])
 AC_MSG_NOTICE([ZPH QOS enabled: $enable_zph_qos])
+if test $enable_zph_qos = yes ; then
+if test $with_netfilter_conntrack = yes ; then
+SQUID_DEFINE_BOOL(USE_QOS_NFMARK,$with_netfilter_conntrack,
+  [Enable support for QOS netfilter packet marking])
+else
+AC_MSG_WARN([--with-netfilter-conntrack not enabled. QOS features will not support Netfilter marking.])
+fi
+AC_MSG_NOTICE([QOS netfilter marking enabled: $with_netfilter_conntrack])
+fi
 
 dnl --with-maxfd present for compatibility with Squid-2.
 dnl undocumented in ./configure --help  to encourage using the Squid-3 directive.

=== modified file 'src/cf.data.pre'
--- src/cf.data.pre	2010-07-29 13:04:44 +
+++ src/cf.data.pre	2010-08-01 20:09:13 +
@@ -1532,18 +1532,23 @@
 LOC: Ip::Qos::TheConfig
 DOC_START
 	Allows you to select a TOS/DSCP value to mark outgoing
-	connections with, based on where the reply was sourced.
+	connections with, based on where the reply was sourced.	For
+	platforms using netfilter, allows you to set a netfilter mark
+	value instead of, or in addition to, a TOS value.
 
 	TOS values really only have local significance - so you should
 	know what you're specifying. For more information, see RFC2474,
 	RFC2475, and RFC3260.
 
 	The TOS/DSCP byte must be exactly that - octet value 0x00-0xFF.
-	Note that in practice often only values up to 0x3F are usable
-	as the two highest bits have been redefined for use by ECN
-	(RFC3168).
-
-	This setting is configured by setting the source TOS values:
+	Note that in practice often only values up to 0x3F are usable as
+	the two highest bits have been redefined for use by ECN (RFC3168).
+
+Mark values can be any unsigned integer value (normally up to 0x)
+
+	This setting is configured by setting the following values:
+
+tos|markWhether to set TOS or netfilter mark values
 
 	local-hit=0xFF		Value to mark local cache hits.
 
@@ -1551,23 +1556,26 @@
 
 	parent-hit=0xFF		Value to mark hits from parent peers.
 
-
-	NOTE: 'miss' preserve feature is only 

Re: [MERGE] Initial netfilter mark patch for comment

2010-08-01 Thread Amos Jeffries
On Mon, 02 Aug 2010 00:47:15 +0100, Andrew Beverley a...@andybev.com
wrote:
 Please find attached the first version of the netfilter mark patch. I've
 not yet tested it extensively, but would welcome some initial feedback
 or comments.
 
 My comments are:
 
 - The existing TOS patch cannot be disabled at runtime. As such, this
 mark patch cannot be either. Would it be preferable to only enable them
 both if the qos_flows config option is present? This would also have the
 advantage of being able to add CAP_NET_ADMIN as appropriate at runtime.
 
 - I have used sscanf instead of strtoul for both TOS and MARK in
 QosConfig.cc (sscanf doesn't auto-detect the format of unsigned long
 int). As a result, the tos variable could be changed to type char, which
 is what it should be in my opinion. Should I do this?
 
 - The code in forward.cc to obtain all the data needed to locate the
 connection information is messy. Is there a better way to achieve it?
 Conntrack needs to be passed local and remote port numbers and IP
 addresses.
 

The mess around local port can be cleaned up (see comments below). The
remote ip:port mess seems as clean as it can be in the current code.

 
 Is it too late to get this in v3.2? I will update the appropriate
 release-notes once I know.

Not too late. This can come under a header of polish on the existing QoS
feature. We have a a bit more flexibility on that kind of change.

The changes to qos_flows needs to be mentioned in section 3.2 changes to
existing tags and the --with option to section 4.2 new ./configure
options. Both are alphabetical lists.


Audit Results:

configure.in: chunk line 2087
 * QOS netfilter marking enabled: $with_netfilter_conntrack if ZPH QoS
is enabled, but regardless of whether NFMARK was defined.
  The notice needs to be inside the top part of your inner if statement.

 * Please also add an
AC_CHECK_HEADERS([libnetfilter_conntrack/libnetfilter_conntrack.h
libnetfilter_conntrack/libnetfilter_conntrack_tcp.h])
 That way you can error-out early in the ./configure build process with a
useful AC_MSG_ERROR() and also wrap the headers in forward.cc according to
squid coding style.
 NP: this check is also one that can be cached AC_CHECK_CACHED() I think.

src/cf.data.pre typo:
in the case of TOS preservation require your kernel to be patch with
 == s /patch/patched/

src/comm.cc:
 * Please use DBG_IMPORTANT instead of '1' and '0' in debugs. Also, IMO
both should indicate WARNING:, unless the one currently logged at level 1
is common and trivial, in which case it should be dropped to level 2+.

The CRITICAL level as much as possible should be restricted to ERROR:
(serious but recoverable or only affecting this users request) and FATAL:
(non-recoverable, Squid about to shutdown).
The IMPORTANT level should be WARNING: and similar. Stuff that can be
administratively fixed etc.


src/forward.cc:
 * Wrap system includes in #if HAVE_*
  ** also they appear to be duplicate included in forward.h and
forward.cc, please only include in the forward.h.

 * Please remove the defined(_SQUID_LINUX_) around getNfctMark. We build
on non-linux systems with possible netfilter support (kFreeBSD and hurd).

 * our source format requires function result type to be on a separate
line in .cc:
 +int
 +FwdState::getNfctMark

 * also related to the above. The old ZPH TOS _SQUID_LINUX_ wrapper was
only there due to the preserve-miss patch being linux kernel specific. I
think your new preserve for marks not depending on kernel patching is
likely not to need it, so the wrapping there can be re-worked a bit to only
depend on USE_ZPH_QOS and USE_QOS_NFMARK. If you make this change the docs
will also need updating.

 * You run the sequence:
+serv_fde_local_conn.InitAddrInfo(addr);
+serv_fde_local_conn.FreeAddrInfo(addr);
+serv_fde_local_conn.GetAddrInfo(addr);

 ** The GetAddrInfo allocates dynamic memory and needs to be paired with a
FreeAddrInfo() of its own.
 ** The structures created locally by Init inside addr should be able to
be used throughout the sequence. Unless there is some garbage produced by
getaddrinfo() please remove the Get and move the Free down below where you
are finished with the addr variable and it's content:

+serv_fde_local_conn.FreeAddrInfo(addr);
+} else {
+debugs(17, 1, Failed to allocate new conntrack);

 * 

 * following nfct_query() you can output serv_fde_local_conn directly in
the debugs() argument instead of fiddling with inet_ntop to find its
content. That will handle all the display mess and output src ip:port as a
twinned pair. If the debugs result shows no port it means there was none
set.

 * again with the debugs level s/1/DBG_IMPORTANT/ and tagged WARNING: if
it's an error important message. Or bump to level 2+ if its not.

src/ip/QosConfig.cc:
 * Ip::Qos::QosConfig::parseConfigLine again with the s/0/DBG_CRITICAL/.
This one I think will screw up TOS settings if it continues so a FATAL: