diff options
Diffstat (limited to 'net/dccp/feat.c')
-rw-r--r-- | net/dccp/feat.c | 37 |
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 | */ |
169 | static 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 | */ | ||
580 | int 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 | |||
563 | static int dccp_feat_update_ccid(struct sock *sk, u8 type, u8 new_ccid_nr) | 600 | static 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); |