@@ -237,6 +237,40 @@ static int dccp_feat_push_change(struct list_head *fn_list, u8 feat, u8 local,
237237 return 0 ;
238238}
239239
240+ /**
241+ * dccp_feat_push_confirm - Add a Confirm entry to the FN list
242+ * @fn_list: feature-negotiation list to add to
243+ * @feat: one of %dccp_feature_numbers
244+ * @local: whether local (1) or remote (0) @feat_num is being confirmed
245+ * @fval: pointer to NN/SP value to be inserted or NULL
246+ * Returns 0 on success, a Reset code for further processing otherwise.
247+ */
248+ static int dccp_feat_push_confirm (struct list_head * fn_list , u8 feat , u8 local ,
249+ dccp_feat_val * fval )
250+ {
251+ struct dccp_feat_entry * new = dccp_feat_entry_new (fn_list , feat , local );
252+
253+ if (new == NULL )
254+ return DCCP_RESET_CODE_TOO_BUSY ;
255+
256+ new -> feat_num = feat ;
257+ new -> is_local = local ;
258+ new -> state = FEAT_STABLE ; /* transition in 6.6.2 */
259+ new -> needs_confirm = 1 ;
260+ new -> empty_confirm = (fval == NULL );
261+ new -> val .nn = 0 ; /* zeroes the whole structure */
262+ if (!new -> empty_confirm )
263+ new -> val = * fval ;
264+ new -> needs_mandatory = 0 ;
265+
266+ return 0 ;
267+ }
268+
269+ static int dccp_push_empty_confirm (struct list_head * fn_list , u8 feat , u8 local )
270+ {
271+ return dccp_feat_push_confirm (fn_list , feat , local , NULL );
272+ }
273+
240274static inline void dccp_feat_list_pop (struct dccp_feat_entry * entry )
241275{
242276 list_del (& entry -> node );
@@ -955,7 +989,6 @@ static int dccp_feat_nn(struct sock *sk, u8 type, u8 feature, u8 *val, u8 len)
955989
956990 return 0 ;
957991}
958- #endif /* (later) */
959992
960993static void dccp_feat_empty_confirm (struct dccp_minisock * dmsk ,
961994 u8 type , u8 feature )
@@ -1066,6 +1099,7 @@ int dccp_feat_change_recv(struct sock *sk, u8 type, u8 feature, u8 *val, u8 len)
10661099}
10671100
10681101EXPORT_SYMBOL_GPL (dccp_feat_change_recv );
1102+ #endif /* (later) */
10691103
10701104int dccp_feat_confirm_recv (struct sock * sk , u8 type , u8 feature ,
10711105 u8 * val , u8 len )
@@ -1206,6 +1240,150 @@ int dccp_feat_clone(struct sock *oldsk, struct sock *newsk)
12061240
12071241EXPORT_SYMBOL_GPL (dccp_feat_clone );
12081242
1243+ /**
1244+ * dccp_feat_change_recv - Process incoming ChangeL/R options
1245+ * @fn: feature-negotiation list to update
1246+ * @is_mandatory: whether the Change was preceded by a Mandatory option
1247+ * @opt: %DCCPO_CHANGE_L or %DCCPO_CHANGE_R
1248+ * @feat: one of %dccp_feature_numbers
1249+ * @val: NN value or SP value/preference list
1250+ * @len: length of @val in bytes
1251+ * @server: whether this node is the server (1) or the client (0)
1252+ */
1253+ static u8 dccp_feat_change_recv (struct list_head * fn , u8 is_mandatory , u8 opt ,
1254+ u8 feat , u8 * val , u8 len , const bool server )
1255+ {
1256+ u8 defval , type = dccp_feat_type (feat );
1257+ const bool local = (opt == DCCPO_CHANGE_R );
1258+ struct dccp_feat_entry * entry ;
1259+ dccp_feat_val fval ;
1260+
1261+ if (len == 0 || type == FEAT_UNKNOWN ) /* 6.1 and 6.6.8 */
1262+ goto unknown_feature_or_value ;
1263+
1264+ /*
1265+ * Negotiation of NN features: Change R is invalid, so there is no
1266+ * simultaneous negotiation; hence we do not look up in the list.
1267+ */
1268+ if (type == FEAT_NN ) {
1269+ if (local || len > sizeof (fval .nn ))
1270+ goto unknown_feature_or_value ;
1271+
1272+ /* 6.3.2: "The feature remote MUST accept any valid value..." */
1273+ fval .nn = dccp_decode_value_var (val , len );
1274+ if (!dccp_feat_is_valid_nn_val (feat , fval .nn ))
1275+ goto unknown_feature_or_value ;
1276+
1277+ return dccp_feat_push_confirm (fn , feat , local , & fval );
1278+ }
1279+
1280+ /*
1281+ * Unidirectional/simultaneous negotiation of SP features (6.3.1)
1282+ */
1283+ entry = dccp_feat_list_lookup (fn , feat , local );
1284+ if (entry == NULL ) {
1285+ /*
1286+ * No particular preferences have been registered. We deal with
1287+ * this situation by assuming that all valid values are equally
1288+ * acceptable, and apply the following checks:
1289+ * - if the peer's list is a singleton, we accept a valid value;
1290+ * - if we are the server, we first try to see if the peer (the
1291+ * client) advertises the default value. If yes, we use it,
1292+ * otherwise we accept the preferred value;
1293+ * - else if we are the client, we use the first list element.
1294+ */
1295+ if (dccp_feat_clone_sp_val (& fval , val , 1 ))
1296+ return DCCP_RESET_CODE_TOO_BUSY ;
1297+
1298+ if (len > 1 && server ) {
1299+ defval = dccp_feat_default_value (feat );
1300+ if (dccp_feat_preflist_match (& defval , 1 , val , len ) > -1 )
1301+ fval .sp .vec [0 ] = defval ;
1302+ } else if (!dccp_feat_is_valid_sp_val (feat , fval .sp .vec [0 ])) {
1303+ kfree (fval .sp .vec );
1304+ goto unknown_feature_or_value ;
1305+ }
1306+
1307+ /* Treat unsupported CCIDs like invalid values */
1308+ if (feat == DCCPF_CCID && !ccid_support_check (fval .sp .vec , 1 )) {
1309+ kfree (fval .sp .vec );
1310+ goto not_valid_or_not_known ;
1311+ }
1312+
1313+ return dccp_feat_push_confirm (fn , feat , local , & fval );
1314+
1315+ } else if (entry -> state == FEAT_UNSTABLE ) { /* 6.6.2 */
1316+ return 0 ;
1317+ }
1318+
1319+ if (dccp_feat_reconcile (& entry -> val , val , len , server , true)) {
1320+ entry -> empty_confirm = 0 ;
1321+ } else if (is_mandatory ) {
1322+ return DCCP_RESET_CODE_MANDATORY_ERROR ;
1323+ } else if (entry -> state == FEAT_INITIALISING ) {
1324+ /*
1325+ * Failed simultaneous negotiation (server only): try to `save'
1326+ * the connection by checking whether entry contains the default
1327+ * value for @feat. If yes, send an empty Confirm to signal that
1328+ * the received Change was not understood - which implies using
1329+ * the default value.
1330+ * If this also fails, we use Reset as the last resort.
1331+ */
1332+ WARN_ON (!server );
1333+ defval = dccp_feat_default_value (feat );
1334+ if (!dccp_feat_reconcile (& entry -> val , & defval , 1 , server , true))
1335+ return DCCP_RESET_CODE_OPTION_ERROR ;
1336+ entry -> empty_confirm = 1 ;
1337+ }
1338+ entry -> needs_confirm = 1 ;
1339+ entry -> needs_mandatory = 0 ;
1340+ entry -> state = FEAT_STABLE ;
1341+ return 0 ;
1342+
1343+ unknown_feature_or_value :
1344+ if (!is_mandatory )
1345+ return dccp_push_empty_confirm (fn , feat , local );
1346+
1347+ not_valid_or_not_known :
1348+ return is_mandatory ? DCCP_RESET_CODE_MANDATORY_ERROR
1349+ : DCCP_RESET_CODE_OPTION_ERROR ;
1350+ }
1351+
1352+ /**
1353+ * dccp_feat_parse_options - Process Feature-Negotiation Options
1354+ * @sk: for general use and used by the client during connection setup
1355+ * @dreq: used by the server during connection setup
1356+ * @mandatory: whether @opt was preceded by a Mandatory option
1357+ * @opt: %DCCPO_CHANGE_L | %DCCPO_CHANGE_R | %DCCPO_CONFIRM_L | %DCCPO_CONFIRM_R
1358+ * @feat: one of %dccp_feature_numbers
1359+ * @val: value contents of @opt
1360+ * @len: length of @val in bytes
1361+ * Returns 0 on success, a Reset code for ending the connection otherwise.
1362+ */
1363+ int dccp_feat_parse_options (struct sock * sk , struct dccp_request_sock * dreq ,
1364+ u8 mandatory , u8 opt , u8 feat , u8 * val , u8 len )
1365+ {
1366+ struct dccp_sock * dp = dccp_sk (sk );
1367+ struct list_head * fn = dreq ? & dreq -> dreq_featneg : & dp -> dccps_featneg ;
1368+ bool server = false;
1369+
1370+ switch (sk -> sk_state ) {
1371+ /*
1372+ * Negotiation during connection setup
1373+ */
1374+ case DCCP_LISTEN :
1375+ server = true; /* fall through */
1376+ case DCCP_REQUESTING :
1377+ switch (opt ) {
1378+ case DCCPO_CHANGE_L :
1379+ case DCCPO_CHANGE_R :
1380+ return dccp_feat_change_recv (fn , mandatory , opt , feat ,
1381+ val , len , server );
1382+ }
1383+ }
1384+ return 0 ; /* ignore FN options in all other states */
1385+ }
1386+
12091387int dccp_feat_init (struct sock * sk )
12101388{
12111389 struct dccp_sock * dp = dccp_sk (sk );
0 commit comments