]> Pileus Git - ~andy/linux/blobdiff - net/ipv4/tcp.c
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6
[~andy/linux] / net / ipv4 / tcp.c
index 2cbfa6df7976cc5a732ac9944ee26380054794de..071e83a894ad9c02081f24b9ba243c77f7ea8d7c 100644 (file)
@@ -497,7 +497,6 @@ static inline void tcp_mark_urg(struct tcp_sock *tp, int flags,
        if (flags & MSG_OOB) {
                tp->urg_mode = 1;
                tp->snd_up = tp->write_seq;
-               TCP_SKB_CB(skb)->sacked |= TCPCB_URG;
        }
 }
 
@@ -1653,6 +1652,41 @@ recv_urg:
        goto out;
 }
 
+void tcp_set_state(struct sock *sk, int state)
+{
+       int oldstate = sk->sk_state;
+
+       switch (state) {
+       case TCP_ESTABLISHED:
+               if (oldstate != TCP_ESTABLISHED)
+                       TCP_INC_STATS(TCP_MIB_CURRESTAB);
+               break;
+
+       case TCP_CLOSE:
+               if (oldstate == TCP_CLOSE_WAIT || oldstate == TCP_ESTABLISHED)
+                       TCP_INC_STATS(TCP_MIB_ESTABRESETS);
+
+               sk->sk_prot->unhash(sk);
+               if (inet_csk(sk)->icsk_bind_hash &&
+                   !(sk->sk_userlocks & SOCK_BINDPORT_LOCK))
+                       inet_put_port(sk);
+               /* fall through */
+       default:
+               if (oldstate==TCP_ESTABLISHED)
+                       TCP_DEC_STATS(TCP_MIB_CURRESTAB);
+       }
+
+       /* Change state AFTER socket is unhashed to avoid closed
+        * socket sitting in hash tables.
+        */
+       sk->sk_state = state;
+
+#ifdef STATE_TRACE
+       SOCK_DEBUG(sk, "TCP sk=%p, State %s -> %s\n",sk, statename[oldstate],statename[state]);
+#endif
+}
+EXPORT_SYMBOL_GPL(tcp_set_state);
+
 /*
  *     State processing on a close. This implements the state shift for
  *     sending our FIN frame. Note that we only send a FIN for some