Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 122401
b: refs/heads/master
c: 0971d17
h: refs/heads/master
i:
  122399: 23c11ed
v: v3
  • Loading branch information
Gerrit Renker authored and David S. Miller committed Dec 2, 2008
1 parent 08145af commit f72913e
Show file tree
Hide file tree
Showing 3 changed files with 68 additions and 1 deletion.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 25f13048bce61f33f6a102e0bf377fd3922ed364
refs/heads/master: 0971d17ca3d80f61863f4750091a64448bf91600
2 changes: 2 additions & 0 deletions trunk/net/dccp/dccp.h
Original file line number Diff line number Diff line change
Expand Up @@ -443,6 +443,8 @@ static inline int dccp_ack_pending(const struct sock *sk)

extern int dccp_feat_finalise_settings(struct dccp_sock *dp);
extern int dccp_feat_server_ccid_dependencies(struct dccp_request_sock *dreq);
extern int dccp_feat_insert_opts(struct dccp_sock*, struct dccp_request_sock*,
struct sk_buff *skb);
extern void dccp_feat_list_purge(struct list_head *fn_list);

extern int dccp_insert_options(struct sock *sk, struct sk_buff *skb);
Expand Down
65 changes: 65 additions & 0 deletions trunk/net/dccp/feat.c
Original file line number Diff line number Diff line change
Expand Up @@ -272,6 +272,20 @@ int dccp_feat_clone_list(struct list_head const *from, struct list_head *to)
return -ENOMEM;
}

/**
* dccp_feat_valid_nn_length - Enforce length constraints on NN options
* Length is between 0 and %DCCP_OPTVAL_MAXLEN. Used for outgoing packets only,
* incoming options are accepted as long as their values are valid.
*/
static u8 dccp_feat_valid_nn_length(u8 feat_num)
{
if (feat_num == DCCPF_ACK_RATIO) /* RFC 4340, 11.3 and 6.6.8 */
return 2;
if (feat_num == DCCPF_SEQUENCE_WINDOW) /* RFC 4340, 7.5.2 and 6.5 */
return 6;
return 0;
}

static u8 dccp_feat_is_valid_nn_val(u8 feat_num, u64 val)
{
switch (feat_num) {
Expand Down Expand Up @@ -313,6 +327,57 @@ static u8 dccp_feat_sp_list_ok(u8 feat_num, u8 const *sp_list, u8 sp_len)
return 1;
}

/**
* dccp_feat_insert_opts - Generate FN options from current list state
* @skb: next sk_buff to be sent to the peer
* @dp: for client during handshake and general negotiation
* @dreq: used by the server only (all Changes/Confirms in LISTEN/RESPOND)
*/
int dccp_feat_insert_opts(struct dccp_sock *dp, struct dccp_request_sock *dreq,
struct sk_buff *skb)
{
struct list_head *fn = dreq ? &dreq->dreq_featneg : &dp->dccps_featneg;
struct dccp_feat_entry *pos, *next;
u8 opt, type, len, *ptr, nn_in_nbo[DCCP_OPTVAL_MAXLEN];
bool rpt;

/* put entries into @skb in the order they appear in the list */
list_for_each_entry_safe_reverse(pos, next, fn, node) {
opt = dccp_feat_genopt(pos);
type = dccp_feat_type(pos->feat_num);
rpt = false;

if (pos->empty_confirm) {
len = 0;
ptr = NULL;
} else {
if (type == FEAT_SP) {
len = pos->val.sp.len;
ptr = pos->val.sp.vec;
rpt = pos->needs_confirm;
} else if (type == FEAT_NN) {
len = dccp_feat_valid_nn_length(pos->feat_num);
ptr = nn_in_nbo;
dccp_encode_value_var(pos->val.nn, ptr, len);
} else {
DCCP_BUG("unknown feature %u", pos->feat_num);
return -1;
}
}

if (dccp_insert_fn_opt(skb, opt, pos->feat_num, ptr, len, rpt))
return -1;
if (pos->needs_mandatory && dccp_insert_option_mandatory(skb))
return -1;
/*
* Enter CHANGING after transmitting the Change option (6.6.2).
*/
if (pos->state == FEAT_INITIALISING)
pos->state = FEAT_CHANGING;
}
return 0;
}

/**
* __feat_register_nn - Register new NN value on socket
* @fn: feature-negotiation list to register with
Expand Down

0 comments on commit f72913e

Please sign in to comment.