diff options
author | Gerrit Renker <gerrit@erg.abdn.ac.uk> | 2008-09-04 01:30:19 -0400 |
---|---|---|
committer | Gerrit Renker <gerrit@erg.abdn.ac.uk> | 2008-09-04 01:45:40 -0400 |
commit | d0c05fe4448db5cbdd886186860581f736f59ae9 (patch) | |
tree | 883543f6992615a8cf9404a8904d35cdde46ddc3 | |
parent | f76fd327a8b32d3ad5b51639faf6f54d18be0981 (diff) |
dccp ccid-3: Simplified handling of TX states
Since CCIDs are only used during the established phase of a connection,
they have very little internal state; this specifically reduces to:
* "no packet sent" if and only if s == 0, for the TX packet size s;
* when the first packet has been sent (i.e. `s' > 0), the question is whether
or not feedback has been received:
- if a feedback packet is received, "feedback = yes" is set,
- if the nofeedback timer expires, "feedback = no" is set.
Thus the CCID only needs to remember state about whether or not feedback
has been received. This is now implemented using a boolean flag, which is
toggled when a feedback packet arrives or the nofeedback timer expires.
Signed-off-by: Gerrit Renker <gerrit@erg.abdn.ac.uk>
-rw-r--r-- | net/dccp/ccids/ccid3.c | 41 | ||||
-rw-r--r-- | net/dccp/ccids/ccid3.h | 11 |
2 files changed, 8 insertions, 44 deletions
diff --git a/net/dccp/ccids/ccid3.c b/net/dccp/ccids/ccid3.c index f566eb76aeb2..5470a978be02 100644 --- a/net/dccp/ccids/ccid3.c +++ b/net/dccp/ccids/ccid3.c | |||
@@ -49,31 +49,6 @@ static int ccid3_debug; | |||
49 | /* | 49 | /* |
50 | * Transmitter Half-Connection Routines | 50 | * Transmitter Half-Connection Routines |
51 | */ | 51 | */ |
52 | #ifdef CONFIG_IP_DCCP_CCID3_DEBUG | ||
53 | static const char *ccid3_tx_state_name(enum ccid3_hc_tx_states state) | ||
54 | { | ||
55 | static char *ccid3_state_names[] = { | ||
56 | [TFRC_SSTATE_NO_SENT] = "NO_SENT", | ||
57 | [TFRC_SSTATE_NO_FBACK] = "NO_FBACK", | ||
58 | [TFRC_SSTATE_FBACK] = "FBACK", | ||
59 | }; | ||
60 | |||
61 | return ccid3_state_names[state]; | ||
62 | } | ||
63 | #endif | ||
64 | |||
65 | static void ccid3_hc_tx_set_state(struct sock *sk, | ||
66 | enum ccid3_hc_tx_states state) | ||
67 | { | ||
68 | struct ccid3_hc_tx_sock *hctx = ccid3_hc_tx_sk(sk); | ||
69 | enum ccid3_hc_tx_states oldstate = hctx->state; | ||
70 | |||
71 | ccid3_pr_debug("%s(%p) %-8.8s -> %s\n", | ||
72 | dccp_role(sk), sk, ccid3_tx_state_name(oldstate), | ||
73 | ccid3_tx_state_name(state)); | ||
74 | WARN_ON(state == oldstate); | ||
75 | hctx->state = state; | ||
76 | } | ||
77 | 52 | ||
78 | /* | 53 | /* |
79 | * Compute the initial sending rate X_init in the manner of RFC 3390: | 54 | * Compute the initial sending rate X_init in the manner of RFC 3390: |
@@ -206,16 +181,15 @@ static void ccid3_hc_tx_no_feedback_timer(unsigned long data) | |||
206 | goto restart_timer; | 181 | goto restart_timer; |
207 | } | 182 | } |
208 | 183 | ||
209 | ccid3_pr_debug("%s(%p, state=%s) - entry \n", dccp_role(sk), sk, | 184 | ccid3_pr_debug("%s(%p) entry with%s feedback\n", dccp_role(sk), sk, |
210 | ccid3_tx_state_name(hctx->state)); | 185 | hctx->feedback ? "" : "out"); |
211 | 186 | ||
212 | /* Ignore and do not restart after leaving the established state */ | 187 | /* Ignore and do not restart after leaving the established state */ |
213 | if ((1 << sk->sk_state) & ~(DCCPF_OPEN | DCCPF_PARTOPEN)) | 188 | if ((1 << sk->sk_state) & ~(DCCPF_OPEN | DCCPF_PARTOPEN)) |
214 | goto out; | 189 | goto out; |
215 | 190 | ||
216 | /* Reset feedback state to "no feedback received" */ | 191 | /* Reset feedback state to "no feedback received" */ |
217 | if (hctx->state == TFRC_SSTATE_FBACK) | 192 | hctx->feedback = false; |
218 | ccid3_hc_tx_set_state(sk, TFRC_SSTATE_NO_FBACK); | ||
219 | 193 | ||
220 | /* | 194 | /* |
221 | * Determine new allowed sending rate X as per draft rfc3448bis-00, 4.4 | 195 | * Determine new allowed sending rate X as per draft rfc3448bis-00, 4.4 |
@@ -290,7 +264,7 @@ static int ccid3_hc_tx_send_packet(struct sock *sk, struct sk_buff *skb) | |||
290 | if (unlikely(skb->len == 0)) | 264 | if (unlikely(skb->len == 0)) |
291 | return -EBADMSG; | 265 | return -EBADMSG; |
292 | 266 | ||
293 | if (hctx->state == TFRC_SSTATE_NO_SENT) { | 267 | if (hctx->s == 0) { |
294 | sk_reset_timer(sk, &hctx->no_feedback_timer, (jiffies + | 268 | sk_reset_timer(sk, &hctx->no_feedback_timer, (jiffies + |
295 | usecs_to_jiffies(TFRC_INITIAL_TIMEOUT))); | 269 | usecs_to_jiffies(TFRC_INITIAL_TIMEOUT))); |
296 | hctx->last_win_count = 0; | 270 | hctx->last_win_count = 0; |
@@ -324,8 +298,6 @@ static int ccid3_hc_tx_send_packet(struct sock *sk, struct sk_buff *skb) | |||
324 | } | 298 | } |
325 | ccid3_update_send_interval(hctx); | 299 | ccid3_update_send_interval(hctx); |
326 | 300 | ||
327 | ccid3_hc_tx_set_state(sk, TFRC_SSTATE_NO_FBACK); | ||
328 | |||
329 | } else { | 301 | } else { |
330 | delay = ktime_us_delta(hctx->t_nom, now); | 302 | delay = ktime_us_delta(hctx->t_nom, now); |
331 | ccid3_pr_debug("delay=%ld\n", (long)delay); | 303 | ccid3_pr_debug("delay=%ld\n", (long)delay); |
@@ -396,8 +368,8 @@ static void ccid3_hc_tx_packet_recv(struct sock *sk, struct sk_buff *skb) | |||
396 | /* | 368 | /* |
397 | * Update allowed sending rate X as per draft rfc3448bis-00, 4.2/3 | 369 | * Update allowed sending rate X as per draft rfc3448bis-00, 4.2/3 |
398 | */ | 370 | */ |
399 | if (hctx->state == TFRC_SSTATE_NO_FBACK) { | 371 | if (!hctx->feedback) { |
400 | ccid3_hc_tx_set_state(sk, TFRC_SSTATE_FBACK); | 372 | hctx->feedback = true; |
401 | 373 | ||
402 | if (hctx->t_rto == 0) { | 374 | if (hctx->t_rto == 0) { |
403 | /* | 375 | /* |
@@ -502,7 +474,6 @@ static int ccid3_hc_tx_init(struct ccid *ccid, struct sock *sk) | |||
502 | { | 474 | { |
503 | struct ccid3_hc_tx_sock *hctx = ccid_priv(ccid); | 475 | struct ccid3_hc_tx_sock *hctx = ccid_priv(ccid); |
504 | 476 | ||
505 | hctx->state = TFRC_SSTATE_NO_SENT; | ||
506 | hctx->hist = NULL; | 477 | hctx->hist = NULL; |
507 | setup_timer(&hctx->no_feedback_timer, | 478 | setup_timer(&hctx->no_feedback_timer, |
508 | ccid3_hc_tx_no_feedback_timer, (unsigned long)sk); | 479 | ccid3_hc_tx_no_feedback_timer, (unsigned long)sk); |
diff --git a/net/dccp/ccids/ccid3.h b/net/dccp/ccids/ccid3.h index 7884159937aa..1773a8dd36d8 100644 --- a/net/dccp/ccids/ccid3.h +++ b/net/dccp/ccids/ccid3.h | |||
@@ -70,13 +70,6 @@ enum ccid3_options { | |||
70 | TFRC_OPT_RECEIVE_RATE = 194, | 70 | TFRC_OPT_RECEIVE_RATE = 194, |
71 | }; | 71 | }; |
72 | 72 | ||
73 | /* TFRC sender states */ | ||
74 | enum ccid3_hc_tx_states { | ||
75 | TFRC_SSTATE_NO_SENT = 1, | ||
76 | TFRC_SSTATE_NO_FBACK, | ||
77 | TFRC_SSTATE_FBACK, | ||
78 | }; | ||
79 | |||
80 | /** struct ccid3_hc_tx_sock - CCID3 sender half-connection socket | 73 | /** struct ccid3_hc_tx_sock - CCID3 sender half-connection socket |
81 | * | 74 | * |
82 | * @x - Current sending rate in 64 * bytes per second | 75 | * @x - Current sending rate in 64 * bytes per second |
@@ -87,7 +80,7 @@ enum ccid3_hc_tx_states { | |||
87 | * @s - Packet size in bytes | 80 | * @s - Packet size in bytes |
88 | * @t_rto - Nofeedback Timer setting in usecs | 81 | * @t_rto - Nofeedback Timer setting in usecs |
89 | * @t_ipi - Interpacket (send) interval (RFC 3448, 4.6) in usecs | 82 | * @t_ipi - Interpacket (send) interval (RFC 3448, 4.6) in usecs |
90 | * @state - Sender state, one of %ccid3_hc_tx_states | 83 | * @feedback - Whether feedback has been received or not |
91 | * @last_win_count - Last window counter sent | 84 | * @last_win_count - Last window counter sent |
92 | * @t_last_win_count - Timestamp of earliest packet with | 85 | * @t_last_win_count - Timestamp of earliest packet with |
93 | * last_win_count value sent | 86 | * last_win_count value sent |
@@ -105,7 +98,7 @@ struct ccid3_hc_tx_sock { | |||
105 | u32 t_rto; | 98 | u32 t_rto; |
106 | u32 t_ipi; | 99 | u32 t_ipi; |
107 | u16 s; | 100 | u16 s; |
108 | enum ccid3_hc_tx_states state:8; | 101 | bool feedback:1; |
109 | u8 last_win_count; | 102 | u8 last_win_count; |
110 | ktime_t t_last_win_count; | 103 | ktime_t t_last_win_count; |
111 | struct timer_list no_feedback_timer; | 104 | struct timer_list no_feedback_timer; |