: Query supported CCIDs
Subsystems (2)
PATCH 2/9 : Query supported CCIDs
[DCCP]: Query supported CCIDs
This provides a data structure to record which CCIDs are locally supported and three accessor functions:
- a test function for internal use which is used to validate CCID requests made by the user;
- a copy function so that the list can be used for feature-negotiation;
- documented getsockopt() support so that the user can query capabilities.
The data structure is a table which is filled in at compile-time with the list of available CCIDs (which in turn depends on the Kconfig choices).
Using the copy function for cloning the list of supported CCIDs is useful for feature negotiation, since the negotiation is now with the full list of available CCIDs (e.g. {2, 3}) instead of the default value {2}. This means negotiation will not fail if the peer requests to use CCID3 instead of CCID2.
--- Documentation/networking/dccp.txt | 4 +++ include/linux/dccp.h | 1 net/dccp/ccid.c | 48 ++++++++++++++++++++++++++++++++++++++ net/dccp/ccid.h | 5 +++ net/dccp/feat.c | 4 +++ net/dccp/proto.c | 2 + 6 files changed, 64 insertions(+)
net/dccp/ccid.h +5 -0
@@ -80,6 +80,11 @@ static inline void *ccid_priv(const strureturn (void *)ccid->ccid_priv; } +extern int ccid_get_default_ccids (u8 **ccid_array,u8 *array_len); +extern bool ccid_support_check (u8 const *ccid_array,u8 array_len); +extern int ccid_getsockopt_available_ccids (struct sock *sk,int len, +char __user *,int __user *); +extern struct ccid *ccid_new (unsigned char id,struct sock *sk,int rx,gfp_t gfp);
net/dccp/ccid.c +48 -0
60 lines not on this page · raw message
net/dccp/feat.c +4 -0
@@ -374,6 +374,10 @@ static int dccp_feat_register_sp(struct !dccp_feat_sp_list_ok(feat, sp_val, sp_len))return -EINVAL ; +/* Avoid negotiating alien CCIDs by only advertising supported ones */ +if (feat =DCCPF_CCID && !ccid_support_check (sp_val, sp_len)) +return -EOPNOTSUPP ; +if (dccp_feat_clone_sp_val (&fval, sp_val, sp_len))return -ENOMEM ;
Documentation/networking/dccp.txt +4 -0
@@ -57,6 +57,10 @@ can be set before calling bind(). DCCP_SOCKOPT_GET_CUR_MPS is read-only and retrieves the current maximum packet size (application payload size) in bytes, see RFC 4340, section 14. +DCCP_SOCKOPT_AVAILABLE_CCIDS is also read-only and returns the list of CCIDs +supported by the endpoint (see include/linux/dccp.h for symbolic constants). +The caller needs to provide a sufficiently large (> 2) array of type uint8_t. + DCCP_SOCKOPT_SERVER_TIMEWAIT enables the server (listening socket) to hold timewait state when closing the connection (RFC 4340, 8.3). The usual case is that the closing server sends a CloseReq, whereupon the client holds timewait
include/linux/dccp.h +1 -0
@@ -212,6 +212,7 @@ struct dccp_so_feat {#define DCCP_SOCKOPT_SERVER_TIMEWAIT 6#define DCCP_SOCKOPT_SEND_CSCOV 10#define DCCP_SOCKOPT_RECV_CSCOV 11 +#define DCCP_SOCKOPT_AVAILABLE_CCIDS 12#define DCCP_SOCKOPT_CCID_RX_INFO 128#define DCCP_SOCKOPT_CCID_TX_INFO 192
net/dccp/proto.c +2 -0
@@ -617,6 +617,8 @@ static int do_dccp_getsockopt(struct soccase DCCP_SOCKOPT_GET_CUR_MPS : val = dp->dccps_mss_cache;break ; +case DCCP_SOCKOPT_AVAILABLE_CCIDS : +return ccid_getsockopt_available_ccids (sk, len, optval, optlen);case DCCP_SOCKOPT_SERVER_TIMEWAIT : val = dp->dccps_server_timewait;break ;
Em Fri, Sep 28, 2007 at 04:30:17PM +0100, Gerrit Renker escreveu:
Quoted 44 lines
[DCCP]: Query supported CCIDs
This provides a data structure to record which CCIDs are locally supported and three accessor functions:
- a test function for internal use which is used to validate CCID requests made by the user;
- a copy function so that the list can be used for feature-negotiation;
- documentedgetsockopt()support so that the user can query capabilities.The data structure is a table which is filled in at compile-time with the list of available CCIDs (which in turn depends on the
Kconfigchoices).Using the copy function for cloning the list of supported CCIDs is useful for feature negotiation, since the negotiation is now with the full list of available CCIDs (e.g. {2, 3}) instead of the default value {2}. This means negotiation will not fail if the peer requests to use CCID3 instead of CCID2.
Signed-off-by Gerrit Renker <[email protected]>--- Documentation/networking/dccp.txt | 4 +++ include/linux/dccp.h | 1 net/dccp/ccid.c | 48 ++++++++++++++++++++++++++++++++++++++ net/dccp/ccid.h | 5 +++ net/dccp/feat.c | 4 +++ net/dccp/proto.c | 2 + 6 files changed, 64 insertions(+)net/dccp/ccid.h +5
-0@@ -80,6 +80,11 @@ static inline void *ccid_priv(const strureturn (void *)ccid->ccid_priv; } +extern int ccid_get_default_ccids (u8 **ccid_array,u8 *array_len); +extern bool ccid_support_check (u8 const *ccid_array,u8 array_len); +extern int ccid_getsockopt_available_ccids (struct sock *sk,int len, +char __user *,int __user *); +extern struct ccid *ccid_new (unsigned char id,struct sock *sk,int rx,gfp_t gfp);
net/dccp/ccid.c line 21
Quoted 9 lines
net/dccp/ccid.c +6
-0@@ -13,6 +13,13 @@#include "ccid.h" +static u8 builtin_ccids[] = { +DCCPC_CCID2 ,/* CCID2 is supported by default */ +#if defined(CONFIG_IP_DCCP_CCID3) || defined(CONFIG_IP_DCCP_CCID3_MODULE) + DCCPC_CCID3, +#endif +};
This considers only code that was already merged. What about a new CCID that is not yet merged? I guess the table should be managed at ccid module registration time... but that would prevent autoloading on demand, so I think that a sysctl interface that tells the DCCP core infrastructure which are the ccids that are available is better.
Think also about an administrator deciding that even with the Linux kernel provided by his vendor containing modules for ccid2, 3, etc, he only accepts ccid3 or some other subset.
We could have as default a table built with the modules we know at dccp core build time to be available in the current kernel build, but not prevent others from being added or existing ones to be disabled.
So I think we can start with what you provided and implement my suggestions later.
- Arnaldo
Quoting Arnaldo Carvalho de Melo:
| > +static u8 builtin_ccids[] = {
| > + DCCPC_CCID2, /* CCID2 is supported by default */
| > +#if defined(CONFIG_IP_DCCP_CCID3) || defined(CONFIG_IP_DCCP_CCID3_MODULE)
| > + DCCPC_CCID3,
| > +#endif
| > +};
|
| This considers only code that was already merged. What about a new CCID
| that is not yet merged? I guess the table should be managed at ccid
| module registration time... but that would prevent autoloading on
| demand, so I think that a sysctl interface that tells the DCCP core
| infrastructure which are the ccids that are available is better.
|For each new CCID (which is likely to have a Kconfig option), the table would need a new entry. The table is not necessary for autoloading, this is handled separately, and there is flexibility in handling this. Currently (subsequent patch), all advertised CCIDs are autoloaded at socket creation time (only if this is the first socket call, not when the CCID modules are already loaded), since ccid_new() is later only called in interrupt context. But this has the nice byproduct that module loading is no longer needed - firing up the applications at either end is sufficient to have everything loaded.
| Think also about an administrator deciding that even with the Linux | kernel provided by his vendor containing modules for ccid2, 3, etc, he | only accepts ccid3 or some other subset.
That is an interesting thought - defining system-wide policies. The above table is much more primitive, it mainly is book-keeping to see what is there. Do you mean something like net.ipv4.tcp_available_congestion_control ?
| | We could have as default a table built with the modules we know at dccp | core build time to be available in the current kernel build, but not | prevent others from being added or existing ones to be disabled.
The disabling can also be done on a per-connection basis, via socket options. One pain with the server-priority negotiation (and reason for the table) is that when only a single value is used, then it only works if both ends happen to hit the same value. One can exploit this fact to limit the choices.
| So I think we can start with what you provided and implement my | suggestions later.
I am saving this in my todo folder and hope we can continue this thread.
Em Sat, Sep 29, 2007 at 05:24:18PM +0100, Gerrit Renker escreveu:
Quoted 23 lines
Quoting Arnaldo Carvalho de Melo:
| > +static u8 builtin_ccids[] = { | > + DCCPC_CCID2, /* CCID2 is supported by default */ | > +#if defined(CONFIG_IP_DCCP_CCID3) || defined(CONFIG_IP_DCCP_CCID3_MODULE) | > + DCCPC_CCID3, | > +#endif | > +}; | | This considers only code that was already merged. What about a new CCID | that is not yet merged? I guess the table should be managed at ccid | module registration time... but that would prevent autoloading on | demand, so I think that a sysctl interface that tells the DCCP core | infrastructure which are the ccids that are available is better. |For each new CCID (which is likely to have a
Kconfigoption), the table would need a new entry. The table is not necessary for autoloading, this is handled separately, and there is flexibility in handling this. Currently (subsequent patch), all advertised CCIDs are autoloaded at socket creation time (only if this is the first socket call, not when the CCID modules are already loaded), sinceccid_new()is later only called in interrupt context. But this has the nice byproduct that module loading is no longer needed - firing up the applications at either end is sufficient to have everything loaded.
Quoted 6 lines
| Think also about an administrator deciding that even with the Linux | kernel provided by his vendor containing modules for ccid2, 3, etc, he | only accepts ccid3 or some other subset.That is an interesting thought - defining system-wide policies. The above table is much more primitive, it mainly is book-keeping to see what is there. Do you mean something like net.ipv4.tcp_available_congestion_control ?
I haven't looked, but perhaps, its almost the same problem space. Almost because TCP doesn't have feature negotiation, its the app that can use a setsockopt to say what is the cong control module it wants to use, despite what the other end wants, heck, the other end can and probably will not even know if there were different cong control modules.
Quoted 10 lines
| | We could have as default a table built with the modules we know at dccp | core build time to be available in the current kernel build, but not | prevent others from being added or existing ones to be disabled.The disabling can also be done on a per-connection basis, via socket options. One pain with the server-priority negotiation (and reason for the table) is that when only a single value is used, then it only works if both ends happen to hit the same value. One can exploit this fact to limit the choices.
Quoted 3 lines
| So I think we can start with what you provided and implement my | suggestions later.I am saving this in my todo folder and hope we can continue this thread.
OK! For now my thoughts are more on what-is-best-in-the-long-term, what you have done so far is OK by me and I'll be reviewing those patches soon. One thing is the pointer in the request_sock case that I have to figure out what is best and possibly rework your patches to provide what I think is best.
- Arnaldo
| One thing is the pointer in the request_sock case that I have to | figure out what is best and possibly rework your patches to provide what | I think is best. |
I am looking forward to that - if you want me to change single patches, let me know.
I had one more thought regarding timestamping: currently CCID2 uses the old RFC2988 RTT mechanism from Jacobson's old 1988 paper. RFC 4341 says that the sampling should be done at most once per cwnd, but RFC 1323 says that this is insufficient for high-speed networking. And today it is almost impossible to buy a computer /not/ with a Gbps ethernet card.
In short - if you change the architecture, is is possible to keep a door open to add a timestamping-based RTT algorithm to CCID2? That has been your suggestion anyway some emails ago and I like the idea.
There is further stuff that can be shared - I have some ideas for using the ICSK_RETRANS to replace a lot of code duplication for the RTO timer in CCID2. Would make sense, since in OPEN/PARTOPEN state the retransmit timer is never used (only for Request/Close/CloseReq).
Quoted 12 lines · Gerrit Renker
[DCCP]: Query supported CCIDs
This provides a data structure to record which CCIDs are locally supported and three accessor functions:
- a test function for internal use which is used to validate CCID requests made by the user;
- a copy function so that the list can be used for feature-negotiation;
- documentedgetsockopt()support so that the user can query capabilities.The data structure is a table which is filled in at compile-time with the list of available CCIDs (which in turn depends on the
Kconfigchoices).
Quoted 6 lines
Using the copy function for cloning the list of supported CCIDs is useful for feature negotiation, since the negotiation is now with the full list of available CCIDs (e.g. {2, 3}) instead of the default value {2}. This means negotiation will not fail if the peer requests to use CCID3 instead of CCID2.
Signed-off-by Gerrit Renker <[email protected]>