]> git.karo-electronics.de Git - mv-sheeva.git/blobdiff - net/dccp/dccp.h
Merge tag 'v2.6.37' of git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6
[mv-sheeva.git] / net / dccp / dccp.h
index 3ccef1b70feef57556f6b5a71c6ed84bc1a12f02..a8ed459508b294feb774c1597e788fa38313e995 100644 (file)
@@ -153,18 +153,27 @@ static inline u64 max48(const u64 seq1, const u64 seq2)
 }
 
 /**
- * dccp_loss_free  -  Evaluates condition for data loss from RFC 4340, 7.7.1
- * @s1:         start sequence number
- * @s2:  end sequence number
+ * dccp_loss_count - Approximate the number of lost data packets in a burst loss
+ * @s1:  last known sequence number before the loss ('hole')
+ * @s2:  first sequence number seen after the 'hole'
  * @ndp: NDP count on packet with sequence number @s2
- * Returns true if the sequence range s1...s2 has no data loss.
  */
-static inline bool dccp_loss_free(const u64 s1, const u64 s2, const u64 ndp)
+static inline u64 dccp_loss_count(const u64 s1, const u64 s2, const u64 ndp)
 {
        s64 delta = dccp_delta_seqno(s1, s2);
 
        WARN_ON(delta < 0);
-       return (u64)delta <= ndp + 1;
+       delta -= ndp + 1;
+
+       return delta > 0 ? delta : 0;
+}
+
+/**
+ * dccp_loss_free - Evaluate condition for data loss from RFC 4340, 7.7.1
+ */
+static inline bool dccp_loss_free(const u64 s1, const u64 s2, const u64 ndp)
+{
+       return dccp_loss_count(s1, s2, ndp) == 0;
 }
 
 enum {
@@ -234,8 +243,9 @@ extern void dccp_reqsk_send_ack(struct sock *sk, struct sk_buff *skb,
 extern void dccp_send_sync(struct sock *sk, const u64 seq,
                           const enum dccp_pkt_type pkt_type);
 
-extern void dccp_write_xmit(struct sock *sk, int block);
-extern void dccp_write_space(struct sock *sk);
+extern void   dccp_write_xmit(struct sock *sk);
+extern void   dccp_write_space(struct sock *sk);
+extern void   dccp_flush_write_queue(struct sock *sk, long *time_budget);
 
 extern void dccp_init_xmit_timers(struct sock *sk);
 static inline void dccp_clear_xmit_timers(struct sock *sk)
@@ -246,7 +256,6 @@ static inline void dccp_clear_xmit_timers(struct sock *sk)
 extern unsigned int dccp_sync_mss(struct sock *sk, u32 pmtu);
 
 extern const char *dccp_packet_name(const int type);
-extern const char *dccp_state_name(const int state);
 
 extern void dccp_set_state(struct sock *sk, const int state);
 extern void dccp_done(struct sock *sk);
@@ -415,6 +424,23 @@ static inline void dccp_update_gsr(struct sock *sk, u64 seq)
        dp->dccps_gsr = seq;
        /* Sequence validity window depends on remote Sequence Window (7.5.1) */
        dp->dccps_swl = SUB48(ADD48(dp->dccps_gsr, 1), dp->dccps_r_seq_win / 4);
+       /*
+        * Adjust SWL so that it is not below ISR. In contrast to RFC 4340,
+        * 7.5.1 we perform this check beyond the initial handshake: W/W' are
+        * always > 32, so for the first W/W' packets in the lifetime of a
+        * connection we always have to adjust SWL.
+        * A second reason why we are doing this is that the window depends on
+        * the feature-remote value of Sequence Window: nothing stops the peer
+        * from updating this value while we are busy adjusting SWL for the
+        * first W packets (we would have to count from scratch again then).
+        * Therefore it is safer to always make sure that the Sequence Window
+        * is not artificially extended by a peer who grows SWL downwards by
+        * continually updating the feature-remote Sequence-Window.
+        * If sequence numbers wrap it is bad luck. But that will take a while
+        * (48 bit), and this measure prevents Sequence-number attacks.
+        */
+       if (before48(dp->dccps_swl, dp->dccps_isr))
+               dp->dccps_swl = dp->dccps_isr;
        dp->dccps_swh = ADD48(dp->dccps_gsr, (3 * dp->dccps_r_seq_win) / 4);
 }
 
@@ -425,14 +451,16 @@ static inline void dccp_update_gss(struct sock *sk, u64 seq)
        dp->dccps_gss = seq;
        /* Ack validity window depends on local Sequence Window value (7.5.1) */
        dp->dccps_awl = SUB48(ADD48(dp->dccps_gss, 1), dp->dccps_l_seq_win);
+       /* Adjust AWL so that it is not below ISS - see comment above for SWL */
+       if (before48(dp->dccps_awl, dp->dccps_iss))
+               dp->dccps_awl = dp->dccps_iss;
        dp->dccps_awh = dp->dccps_gss;
 }
 
 static inline int dccp_ack_pending(const struct sock *sk)
 {
        const struct dccp_sock *dp = dccp_sk(sk);
-       return dp->dccps_timestamp_echo != 0 ||
-              (dp->dccps_hc_rx_ackvec != NULL &&
+       return (dp->dccps_hc_rx_ackvec != NULL &&
                dccp_ackvec_pending(dp->dccps_hc_rx_ackvec)) ||
               inet_csk_ack_scheduled(sk);
 }
@@ -449,7 +477,6 @@ extern int dccp_insert_options_rsk(struct dccp_request_sock*, struct sk_buff*);
 extern int dccp_insert_option_elapsed_time(struct sk_buff *skb, u32 elapsed);
 extern u32 dccp_timestamp(void);
 extern void dccp_timestamping_init(void);
-extern int dccp_insert_option_timestamp(struct sk_buff *skb);
 extern int dccp_insert_option(struct sk_buff *skb, unsigned char option,
                              const void *value, unsigned char len);