aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorGerrit Renker <gerrit@erg.abdn.ac.uk>2008-09-04 01:30:19 -0400
committerGerrit Renker <gerrit@erg.abdn.ac.uk>2008-09-04 01:45:29 -0400
commitc664d4f4e2963ee355b1b0e77461eb844d1b288d (patch)
treeb799cbd6bc0b3764a527b1b7b71012215b67e62f /net
parentf8a644c07e6f38b2c3cbaf99990e867d670d207b (diff)
dccp: Preference list reconciliation
This provides two functions to * reconcile preference lists (with appropriate return codes) and * reorder the preference list if successful reconciliation changed the preferred value. The patch also removes the old code for processing SP/NN Change options, since new code to process these is mostly there already; related references have been commented out. The code for processing Change options follows in the next patch. Signed-off-by: Gerrit Renker <gerrit@erg.abdn.ac.uk> Acked-by: Ian McDonald <ian.mcdonald@jandi.co.nz>
Diffstat (limited to 'net')
-rw-r--r--net/dccp/feat.c77
1 files changed, 75 insertions, 2 deletions
diff --git a/net/dccp/feat.c b/net/dccp/feat.c
index da686464462d..d53077bd40bf 100644
--- a/net/dccp/feat.c
+++ b/net/dccp/feat.c
@@ -718,6 +718,76 @@ static int dccp_feat_update(struct sock *sk, u8 type, u8 feat, u8 val)
718 return 0; 718 return 0;
719} 719}
720 720
721/* Select the first entry in @servlist that also occurs in @clilist (6.3.1) */
722static int dccp_feat_preflist_match(u8 *servlist, u8 slen, u8 *clilist, u8 clen)
723{
724 u8 c, s;
725
726 for (s = 0; s < slen; s++)
727 for (c = 0; c < clen; c++)
728 if (servlist[s] == clilist[c])
729 return servlist[s];
730 return -1;
731}
732
733/**
734 * dccp_feat_prefer - Move preferred entry to the start of array
735 * Reorder the @array_len elements in @array so that @preferred_value comes
736 * first. Returns >0 to indicate that @preferred_value does occur in @array.
737 */
738static u8 dccp_feat_prefer(u8 preferred_value, u8 *array, u8 array_len)
739{
740 u8 i, does_occur = 0;
741
742 if (array != NULL) {
743 for (i = 0; i < array_len; i++)
744 if (array[i] == preferred_value) {
745 array[i] = array[0];
746 does_occur++;
747 }
748 if (does_occur)
749 array[0] = preferred_value;
750 }
751 return does_occur;
752}
753
754/**
755 * dccp_feat_reconcile - Reconcile SP preference lists
756 * @fval: SP list to reconcile into
757 * @arr: received SP preference list
758 * @len: length of @arr in bytes
759 * @is_server: whether this side is the server (and @fv is the server's list)
760 * @reorder: whether to reorder the list in @fv after reconciling with @arr
761 * When successful, > 0 is returned and the reconciled list is in @fval.
762 * A value of 0 means that negotiation failed (no shared entry).
763 */
764static int dccp_feat_reconcile(dccp_feat_val *fv, u8 *arr, u8 len,
765 bool is_server, bool reorder)
766{
767 int rc;
768
769 if (!fv->sp.vec || !arr) {
770 DCCP_CRIT("NULL feature value or array");
771 return 0;
772 }
773
774 if (is_server)
775 rc = dccp_feat_preflist_match(fv->sp.vec, fv->sp.len, arr, len);
776 else
777 rc = dccp_feat_preflist_match(arr, len, fv->sp.vec, fv->sp.len);
778
779 if (!reorder)
780 return rc;
781 if (rc < 0)
782 return 0;
783
784 /*
785 * Reorder list: used for activating features and in dccp_insert_fn_opt.
786 */
787 return dccp_feat_prefer(rc, fv->sp.vec, fv->sp.len);
788}
789
790#ifdef __this_is_the_old_framework_and_will_be_removed_later_in_a_subsequent_patch
721static int dccp_feat_reconcile(struct sock *sk, struct dccp_opt_pend *opt, 791static int dccp_feat_reconcile(struct sock *sk, struct dccp_opt_pend *opt,
722 u8 *rpref, u8 rlen) 792 u8 *rpref, u8 rlen)
723{ 793{
@@ -913,6 +983,7 @@ static int dccp_feat_nn(struct sock *sk, u8 type, u8 feature, u8 *val, u8 len)
913 983
914 return 0; 984 return 0;
915} 985}
986#endif /* (later) */
916 987
917static void dccp_feat_empty_confirm(struct dccp_minisock *dmsk, 988static void dccp_feat_empty_confirm(struct dccp_minisock *dmsk,
918 u8 type, u8 feature) 989 u8 type, u8 feature)
@@ -988,12 +1059,14 @@ int dccp_feat_change_recv(struct sock *sk, u8 type, u8 feature, u8 *val, u8 len)
988 switch (feature) { 1059 switch (feature) {
989 /* deal with SP features */ 1060 /* deal with SP features */
990 case DCCPF_CCID: 1061 case DCCPF_CCID:
991 rc = dccp_feat_sp(sk, type, feature, val, len); 1062 /* XXX Obsoleted by next patch
1063 rc = dccp_feat_sp(sk, type, feature, val, len); */
992 break; 1064 break;
993 1065
994 /* deal with NN features */ 1066 /* deal with NN features */
995 case DCCPF_ACK_RATIO: 1067 case DCCPF_ACK_RATIO:
996 rc = dccp_feat_nn(sk, type, feature, val, len); 1068 /* XXX Obsoleted by next patch
1069 rc = dccp_feat_nn(sk, type, feature, val, len); */
997 break; 1070 break;
998 1071
999 /* XXX implement other features */ 1072 /* XXX implement other features */