aboutsummaryrefslogtreecommitdiffstats
path: root/net/dccp/feat.c
diff options
context:
space:
mode:
authorGerrit Renker <gerrit@erg.abdn.ac.uk>2008-11-17 01:49:52 -0500
committerDavid S. Miller <davem@davemloft.net>2008-11-17 01:49:52 -0500
commit0c1168398ecbfacbb27203b281bde20ec9f78017 (patch)
tree3298379e950bba174b46e53102f265829340fa6d /net/dccp/feat.c
parent3f2c31d90327f21d76d296af34aa4ca547932ff4 (diff)
dccp: Mechanism to resolve CCID dependencies
This adds a hook to resolve features whose value depends on the choice of CCID. It is done at the server since it can only be done after the CCID values have been negotiated; i.e. the client will add its CCID preference list on the Change options sent in the Request, which will be reconciled with the local preference list of the server. The concept is documented on http://www.erg.abdn.ac.uk/users/gerrit/dccp/notes/feature_negotiation/\ implementation_notes.html#ccid_dependencies Signed-off-by: Gerrit Renker <gerrit@erg.abdn.ac.uk> Acked-by: Ian McDonald <ian.mcdonald@jandi.co.nz> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/dccp/feat.c')
-rw-r--r--net/dccp/feat.c37
1 files changed, 37 insertions, 0 deletions
diff --git a/net/dccp/feat.c b/net/dccp/feat.c
index 4c4144147325..4f86a48723f6 100644
--- a/net/dccp/feat.c
+++ b/net/dccp/feat.c
@@ -166,6 +166,18 @@ static void dccp_feat_entry_destructor(struct dccp_feat_entry *entry)
166 * - SP values are always freshly allocated 166 * - SP values are always freshly allocated
167 * - list is sorted in increasing order of feature number (faster lookup) 167 * - list is sorted in increasing order of feature number (faster lookup)
168 */ 168 */
169static struct dccp_feat_entry *dccp_feat_list_lookup(struct list_head *fn_list,
170 u8 feat_num, bool is_local)
171{
172 struct dccp_feat_entry *entry;
173
174 list_for_each_entry(entry, fn_list, node)
175 if (entry->feat_num == feat_num && entry->is_local == is_local)
176 return entry;
177 else if (entry->feat_num > feat_num)
178 break;
179 return NULL;
180}
169 181
170/** 182/**
171 * dccp_feat_entry_new - Central list update routine (called by all others) 183 * dccp_feat_entry_new - Central list update routine (called by all others)
@@ -560,6 +572,31 @@ int dccp_feat_finalise_settings(struct dccp_sock *dp)
560 return 0; 572 return 0;
561} 573}
562 574
575/**
576 * dccp_feat_server_ccid_dependencies - Resolve CCID-dependent features
577 * It is the server which resolves the dependencies once the CCID has been
578 * fully negotiated. If no CCID has been negotiated, it uses the default CCID.
579 */
580int dccp_feat_server_ccid_dependencies(struct dccp_request_sock *dreq)
581{
582 struct list_head *fn = &dreq->dreq_featneg;
583 struct dccp_feat_entry *entry;
584 u8 is_local, ccid;
585
586 for (is_local = 0; is_local <= 1; is_local++) {
587 entry = dccp_feat_list_lookup(fn, DCCPF_CCID, is_local);
588
589 if (entry != NULL && !entry->empty_confirm)
590 ccid = entry->val.sp.vec[0];
591 else
592 ccid = dccp_feat_default_value(DCCPF_CCID);
593
594 if (dccp_feat_propagate_ccid(fn, ccid, is_local))
595 return -1;
596 }
597 return 0;
598}
599
563static int dccp_feat_update_ccid(struct sock *sk, u8 type, u8 new_ccid_nr) 600static int dccp_feat_update_ccid(struct sock *sk, u8 type, u8 new_ccid_nr)
564{ 601{
565 struct dccp_sock *dp = dccp_sk(sk); 602 struct dccp_sock *dp = dccp_sk(sk);