feat.c (7483d45f0aee3afc0646d185cabd4af9f6cab58c) | feat.c (2c53040f018b6c36a46eec75b9b937aaa5f78e6d) |
---|---|
1/* 2 * net/dccp/feat.c 3 * 4 * Feature negotiation for the DCCP protocol (RFC 4340, section 6) 5 * 6 * Copyright (c) 2008 Gerrit Renker <gerrit@erg.abdn.ac.uk> 7 * Rewrote from scratch, some bits from earlier code by 8 * Copyright (c) 2005 Andrea Bittau <a.bittau@cs.ucl.ac.uk> --- 336 unchanged lines hidden (view full) --- 345} 346 347/** 348 * dccp_feat_activate - Activate feature value on socket 349 * @sk: fully connected DCCP socket (after handshake is complete) 350 * @feat_num: feature to activate, one of %dccp_feature_numbers 351 * @local: whether local (1) or remote (0) @feat_num is meant 352 * @fval: the value (SP or NN) to activate, or NULL to use the default value | 1/* 2 * net/dccp/feat.c 3 * 4 * Feature negotiation for the DCCP protocol (RFC 4340, section 6) 5 * 6 * Copyright (c) 2008 Gerrit Renker <gerrit@erg.abdn.ac.uk> 7 * Rewrote from scratch, some bits from earlier code by 8 * Copyright (c) 2005 Andrea Bittau <a.bittau@cs.ucl.ac.uk> --- 336 unchanged lines hidden (view full) --- 345} 346 347/** 348 * dccp_feat_activate - Activate feature value on socket 349 * @sk: fully connected DCCP socket (after handshake is complete) 350 * @feat_num: feature to activate, one of %dccp_feature_numbers 351 * @local: whether local (1) or remote (0) @feat_num is meant 352 * @fval: the value (SP or NN) to activate, or NULL to use the default value |
353 * |
|
353 * For general use this function is preferable over __dccp_feat_activate(). 354 */ 355static int dccp_feat_activate(struct sock *sk, u8 feat_num, bool local, 356 dccp_feat_val const *fval) 357{ 358 return __dccp_feat_activate(sk, dccp_feat_index(feat_num), local, fval); 359} 360 --- 80 unchanged lines hidden (view full) --- 441 return NULL; 442} 443 444/** 445 * dccp_feat_entry_new - Central list update routine (called by all others) 446 * @head: list to add to 447 * @feat: feature number 448 * @local: whether the local (1) or remote feature with number @feat is meant | 354 * For general use this function is preferable over __dccp_feat_activate(). 355 */ 356static int dccp_feat_activate(struct sock *sk, u8 feat_num, bool local, 357 dccp_feat_val const *fval) 358{ 359 return __dccp_feat_activate(sk, dccp_feat_index(feat_num), local, fval); 360} 361 --- 80 unchanged lines hidden (view full) --- 442 return NULL; 443} 444 445/** 446 * dccp_feat_entry_new - Central list update routine (called by all others) 447 * @head: list to add to 448 * @feat: feature number 449 * @local: whether the local (1) or remote feature with number @feat is meant |
450 * |
|
449 * This is the only constructor and serves to ensure the above invariants. 450 */ 451static struct dccp_feat_entry * 452 dccp_feat_entry_new(struct list_head *head, u8 feat, bool local) 453{ 454 struct dccp_feat_entry *entry; 455 456 list_for_each_entry(entry, head, node) --- 42 unchanged lines hidden (view full) --- 499} 500 501/** 502 * dccp_feat_push_confirm - Add a Confirm entry to the FN list 503 * @fn_list: feature-negotiation list to add to 504 * @feat: one of %dccp_feature_numbers 505 * @local: whether local (1) or remote (0) @feat_num is being confirmed 506 * @fval: pointer to NN/SP value to be inserted or NULL | 451 * This is the only constructor and serves to ensure the above invariants. 452 */ 453static struct dccp_feat_entry * 454 dccp_feat_entry_new(struct list_head *head, u8 feat, bool local) 455{ 456 struct dccp_feat_entry *entry; 457 458 list_for_each_entry(entry, head, node) --- 42 unchanged lines hidden (view full) --- 501} 502 503/** 504 * dccp_feat_push_confirm - Add a Confirm entry to the FN list 505 * @fn_list: feature-negotiation list to add to 506 * @feat: one of %dccp_feature_numbers 507 * @local: whether local (1) or remote (0) @feat_num is being confirmed 508 * @fval: pointer to NN/SP value to be inserted or NULL |
509 * |
|
507 * Returns 0 on success, a Reset code for further processing otherwise. 508 */ 509static int dccp_feat_push_confirm(struct list_head *fn_list, u8 feat, u8 local, 510 dccp_feat_val *fval) 511{ 512 struct dccp_feat_entry *new = dccp_feat_entry_new(fn_list, feat, local); 513 514 if (new == NULL) --- 171 unchanged lines hidden (view full) --- 686} 687 688/** 689 * __feat_register_nn - Register new NN value on socket 690 * @fn: feature-negotiation list to register with 691 * @feat: an NN feature from %dccp_feature_numbers 692 * @mandatory: use Mandatory option if 1 693 * @nn_val: value to register (restricted to 4 bytes) | 510 * Returns 0 on success, a Reset code for further processing otherwise. 511 */ 512static int dccp_feat_push_confirm(struct list_head *fn_list, u8 feat, u8 local, 513 dccp_feat_val *fval) 514{ 515 struct dccp_feat_entry *new = dccp_feat_entry_new(fn_list, feat, local); 516 517 if (new == NULL) --- 171 unchanged lines hidden (view full) --- 689} 690 691/** 692 * __feat_register_nn - Register new NN value on socket 693 * @fn: feature-negotiation list to register with 694 * @feat: an NN feature from %dccp_feature_numbers 695 * @mandatory: use Mandatory option if 1 696 * @nn_val: value to register (restricted to 4 bytes) |
697 * |
|
694 * Note that NN features are local by definition (RFC 4340, 6.3.2). 695 */ 696static int __feat_register_nn(struct list_head *fn, u8 feat, 697 u8 mandatory, u64 nn_val) 698{ 699 dccp_feat_val fval = { .nn = nn_val }; 700 701 if (dccp_feat_type(feat) != FEAT_NN || --- 53 unchanged lines hidden (view full) --- 755 return __feat_register_sp(&dccp_sk(sk)->dccps_featneg, feat, is_local, 756 0, list, len); 757} 758 759/** 760 * dccp_feat_nn_get - Query current/pending value of NN feature 761 * @sk: DCCP socket of an established connection 762 * @feat: NN feature number from %dccp_feature_numbers | 698 * Note that NN features are local by definition (RFC 4340, 6.3.2). 699 */ 700static int __feat_register_nn(struct list_head *fn, u8 feat, 701 u8 mandatory, u64 nn_val) 702{ 703 dccp_feat_val fval = { .nn = nn_val }; 704 705 if (dccp_feat_type(feat) != FEAT_NN || --- 53 unchanged lines hidden (view full) --- 759 return __feat_register_sp(&dccp_sk(sk)->dccps_featneg, feat, is_local, 760 0, list, len); 761} 762 763/** 764 * dccp_feat_nn_get - Query current/pending value of NN feature 765 * @sk: DCCP socket of an established connection 766 * @feat: NN feature number from %dccp_feature_numbers |
767 * |
|
763 * For a known NN feature, returns value currently being negotiated, or 764 * current (confirmed) value if no negotiation is going on. 765 */ 766u64 dccp_feat_nn_get(struct sock *sk, u8 feat) 767{ 768 if (dccp_feat_type(feat) == FEAT_NN) { 769 struct dccp_sock *dp = dccp_sk(sk); 770 struct dccp_feat_entry *entry; --- 14 unchanged lines hidden (view full) --- 785} 786EXPORT_SYMBOL_GPL(dccp_feat_nn_get); 787 788/** 789 * dccp_feat_signal_nn_change - Update NN values for an established connection 790 * @sk: DCCP socket of an established connection 791 * @feat: NN feature number from %dccp_feature_numbers 792 * @nn_val: the new value to use | 768 * For a known NN feature, returns value currently being negotiated, or 769 * current (confirmed) value if no negotiation is going on. 770 */ 771u64 dccp_feat_nn_get(struct sock *sk, u8 feat) 772{ 773 if (dccp_feat_type(feat) == FEAT_NN) { 774 struct dccp_sock *dp = dccp_sk(sk); 775 struct dccp_feat_entry *entry; --- 14 unchanged lines hidden (view full) --- 790} 791EXPORT_SYMBOL_GPL(dccp_feat_nn_get); 792 793/** 794 * dccp_feat_signal_nn_change - Update NN values for an established connection 795 * @sk: DCCP socket of an established connection 796 * @feat: NN feature number from %dccp_feature_numbers 797 * @nn_val: the new value to use |
798 * |
|
793 * This function is used to communicate NN updates out-of-band. 794 */ 795int dccp_feat_signal_nn_change(struct sock *sk, u8 feat, u64 nn_val) 796{ 797 struct list_head *fn = &dccp_sk(sk)->dccps_featneg; 798 dccp_feat_val fval = { .nn = nn_val }; 799 struct dccp_feat_entry *entry; 800 --- 124 unchanged lines hidden (view full) --- 925 } 926} 927 928/** 929 * dccp_feat_propagate_ccid - Resolve dependencies of features on choice of CCID 930 * @fn: feature-negotiation list to update 931 * @id: CCID number to track 932 * @is_local: whether TX CCID (1) or RX CCID (0) is meant | 799 * This function is used to communicate NN updates out-of-band. 800 */ 801int dccp_feat_signal_nn_change(struct sock *sk, u8 feat, u64 nn_val) 802{ 803 struct list_head *fn = &dccp_sk(sk)->dccps_featneg; 804 dccp_feat_val fval = { .nn = nn_val }; 805 struct dccp_feat_entry *entry; 806 --- 124 unchanged lines hidden (view full) --- 931 } 932} 933 934/** 935 * dccp_feat_propagate_ccid - Resolve dependencies of features on choice of CCID 936 * @fn: feature-negotiation list to update 937 * @id: CCID number to track 938 * @is_local: whether TX CCID (1) or RX CCID (0) is meant |
939 * |
|
933 * This function needs to be called after registering all other features. 934 */ 935static int dccp_feat_propagate_ccid(struct list_head *fn, u8 id, bool is_local) 936{ 937 const struct ccid_dependency *table = dccp_feat_ccid_deps(id, is_local); 938 int i, rc = (table == NULL); 939 940 for (i = 0; rc == 0 && table[i].dependent_feat != DCCPF_RESERVED; i++) --- 7 unchanged lines hidden (view full) --- 948 table[i].is_mandatory, 949 table[i].val); 950 return rc; 951} 952 953/** 954 * dccp_feat_finalise_settings - Finalise settings before starting negotiation 955 * @dp: client or listening socket (settings will be inherited) | 940 * This function needs to be called after registering all other features. 941 */ 942static int dccp_feat_propagate_ccid(struct list_head *fn, u8 id, bool is_local) 943{ 944 const struct ccid_dependency *table = dccp_feat_ccid_deps(id, is_local); 945 int i, rc = (table == NULL); 946 947 for (i = 0; rc == 0 && table[i].dependent_feat != DCCPF_RESERVED; i++) --- 7 unchanged lines hidden (view full) --- 955 table[i].is_mandatory, 956 table[i].val); 957 return rc; 958} 959 960/** 961 * dccp_feat_finalise_settings - Finalise settings before starting negotiation 962 * @dp: client or listening socket (settings will be inherited) |
963 * |
|
956 * This is called after all registrations (socket initialisation, sysctls, and 957 * sockopt calls), and before sending the first packet containing Change options 958 * (ie. client-Request or server-Response), to ensure internal consistency. 959 */ 960int dccp_feat_finalise_settings(struct dccp_sock *dp) 961{ 962 struct list_head *fn = &dp->dccps_featneg; 963 struct dccp_feat_entry *entry; --- 315 unchanged lines hidden (view full) --- 1279/** 1280 * dccp_feat_handle_nn_established - Fast-path reception of NN options 1281 * @sk: socket of an established DCCP connection 1282 * @mandatory: whether @opt was preceded by a Mandatory option 1283 * @opt: %DCCPO_CHANGE_L | %DCCPO_CONFIRM_R (NN only) 1284 * @feat: NN number, one of %dccp_feature_numbers 1285 * @val: NN value 1286 * @len: length of @val in bytes | 964 * This is called after all registrations (socket initialisation, sysctls, and 965 * sockopt calls), and before sending the first packet containing Change options 966 * (ie. client-Request or server-Response), to ensure internal consistency. 967 */ 968int dccp_feat_finalise_settings(struct dccp_sock *dp) 969{ 970 struct list_head *fn = &dp->dccps_featneg; 971 struct dccp_feat_entry *entry; --- 315 unchanged lines hidden (view full) --- 1287/** 1288 * dccp_feat_handle_nn_established - Fast-path reception of NN options 1289 * @sk: socket of an established DCCP connection 1290 * @mandatory: whether @opt was preceded by a Mandatory option 1291 * @opt: %DCCPO_CHANGE_L | %DCCPO_CONFIRM_R (NN only) 1292 * @feat: NN number, one of %dccp_feature_numbers 1293 * @val: NN value 1294 * @len: length of @val in bytes |
1295 * |
|
1287 * This function combines the functionality of change_recv/confirm_recv, with 1288 * the following differences (reset codes are the same): 1289 * - cleanup after receiving the Confirm; 1290 * - values are directly activated after successful parsing; 1291 * - deliberately restricted to NN features. 1292 * The restriction to NN features is essential since SP features can have non- 1293 * predictable outcomes (depending on the remote configuration), and are inter- 1294 * dependent (CCIDs for instance cause further dependencies). --- 79 unchanged lines hidden (view full) --- 1374 * dccp_feat_parse_options - Process Feature-Negotiation Options 1375 * @sk: for general use and used by the client during connection setup 1376 * @dreq: used by the server during connection setup 1377 * @mandatory: whether @opt was preceded by a Mandatory option 1378 * @opt: %DCCPO_CHANGE_L | %DCCPO_CHANGE_R | %DCCPO_CONFIRM_L | %DCCPO_CONFIRM_R 1379 * @feat: one of %dccp_feature_numbers 1380 * @val: value contents of @opt 1381 * @len: length of @val in bytes | 1296 * This function combines the functionality of change_recv/confirm_recv, with 1297 * the following differences (reset codes are the same): 1298 * - cleanup after receiving the Confirm; 1299 * - values are directly activated after successful parsing; 1300 * - deliberately restricted to NN features. 1301 * The restriction to NN features is essential since SP features can have non- 1302 * predictable outcomes (depending on the remote configuration), and are inter- 1303 * dependent (CCIDs for instance cause further dependencies). --- 79 unchanged lines hidden (view full) --- 1383 * dccp_feat_parse_options - Process Feature-Negotiation Options 1384 * @sk: for general use and used by the client during connection setup 1385 * @dreq: used by the server during connection setup 1386 * @mandatory: whether @opt was preceded by a Mandatory option 1387 * @opt: %DCCPO_CHANGE_L | %DCCPO_CHANGE_R | %DCCPO_CONFIRM_L | %DCCPO_CONFIRM_R 1388 * @feat: one of %dccp_feature_numbers 1389 * @val: value contents of @opt 1390 * @len: length of @val in bytes |
1391 * |
|
1382 * Returns 0 on success, a Reset code for ending the connection otherwise. 1383 */ 1384int dccp_feat_parse_options(struct sock *sk, struct dccp_request_sock *dreq, 1385 u8 mandatory, u8 opt, u8 feat, u8 *val, u8 len) 1386{ 1387 struct dccp_sock *dp = dccp_sk(sk); 1388 struct list_head *fn = dreq ? &dreq->dreq_featneg : &dp->dccps_featneg; 1389 bool server = false; --- 162 unchanged lines hidden --- | 1392 * Returns 0 on success, a Reset code for ending the connection otherwise. 1393 */ 1394int dccp_feat_parse_options(struct sock *sk, struct dccp_request_sock *dreq, 1395 u8 mandatory, u8 opt, u8 feat, u8 *val, u8 len) 1396{ 1397 struct dccp_sock *dp = dccp_sk(sk); 1398 struct list_head *fn = dreq ? &dreq->dreq_featneg : &dp->dccps_featneg; 1399 bool server = false; --- 162 unchanged lines hidden --- |