patch-2.1.11 linux/net/ipv4/tcp.c
Next file: linux/net/ipv4/tcp_input.c
Previous file: linux/net/ipv4/sysctl_net_ipv4.c
Back to the patch index
Back to the overall index
- Lines: 251
- Date:
Mon Nov 18 11:31:36 1996
- Orig file:
v2.1.10/linux/net/ipv4/tcp.c
- Orig date:
Fri Nov 15 23:49:11 1996
diff -u --recursive --new-file v2.1.10/linux/net/ipv4/tcp.c linux/net/ipv4/tcp.c
@@ -204,8 +204,7 @@
*
* Rewrite output state machine to use a single queue.
* Speed up input assembly algorithm.
- * RFC1323 - PAWS and window scaling. PAWS is required for IPv6 so we
- * could do with it working on IPv4
+ * RFC1323 - PAWS and window scaling.
* User settable/learned rtt/max window/mtu
*
* Change the fundamental structure to a single send queue maintained
@@ -905,19 +904,20 @@
sk->mss - tcp_size > 0 &&
skb->end_seq < tp->snd_una + tp->snd_wnd)
{
+ int tcopy;
- copy = tcp_append_tail(sk, skb, from,
+ tcopy = tcp_append_tail(sk, skb, from,
tcp_size,
seglen);
- if (copy == -1)
+ if (tcopy == -1)
{
return -EFAULT;
}
- from += copy;
- copied += copy;
- len -= copy;
- seglen -= copy;
+ from += tcopy;
+ copied += tcopy;
+ len -= tcopy;
+ seglen -= tcopy;
/*
* FIXME: if we're nagling we
@@ -1092,7 +1092,7 @@
struct msghdr *msg, int len, int flags,
int *addr_len)
{
- int err;
+ int err=0;
struct tcp_opt *tp = &(sk->tp_pinfo.af_tcp);
/*
@@ -1125,7 +1125,12 @@
char c = sk->urg_data;
if (!(flags & MSG_PEEK))
sk->urg_data = URG_READ;
- err = memcpy_toiovec(msg->msg_iov, &c, 1);
+
+ if(len>0)
+ err = memcpy_toiovec(msg->msg_iov, &c, 1);
+ else
+ msg->msg_flags|=MSG_TRUNC;
+
if(msg->msg_name)
{
tp->af_specific->addr2sockaddr(sk, (struct sockaddr *)
@@ -1133,7 +1138,10 @@
}
if(addr_len)
*addr_len= tp->af_specific->sockaddr_len;
-
+ /*
+ * Read urgent data
+ */
+ msg->msg_flags|=MSG_OOB;
release_sock(sk);
return err ? -EFAULT : 1;
}
@@ -1214,10 +1222,7 @@
volatile u32 *seq; /* So gcc doesn't overoptimise */
unsigned long used;
int err = 0;
-
- /*
- * This error should be checked.
- */
+ int target = 1; /* Read at least this may bytes */
if (sk->state == TCP_LISTEN)
return -ENOTCONN;
@@ -1239,6 +1244,13 @@
seq = &sk->copied_seq;
if (flags & MSG_PEEK)
seq = &peek_seq;
+
+ /*
+ * Handle the POSIX bogosity MSG_WAITALL
+ */
+
+ if (flags & MSG_WAITALL)
+ target=len;
add_wait_queue(sk->sleep, &wait);
lock_sock(sk);
@@ -1256,14 +1268,13 @@
/*
* We need to check signals first, to get correct SIGURG
- * handling.
+ * handling. FIXME: Need to check this doesnt impact 1003.1g
+ * and move it down to the bottom of the loop
*/
if (current->signal & ~current->blocked) {
if (copied)
break;
copied = -ERESTARTSYS;
- if (nonblock)
- copied = -EAGAIN;
break;
}
@@ -1300,7 +1311,7 @@
}
while (skb != (struct sk_buff *)&sk->receive_queue);
- if (copied)
+ if (copied >= target)
break;
if (sk->err && !(flags&MSG_PEEK))
@@ -1393,11 +1404,6 @@
* a crash when cleanup_rbuf() gets called.
*/
- /*
- * FIXME: should break out of the loop early when an
- * error occurs
- */
-
err = memcpy_toiovec(msg->msg_iov, ((unsigned char *)skb->h.th) + skb->h.th->doff*4 + offset, used);
if (err)
@@ -1427,7 +1433,8 @@
continue;
/*
- * Process the FIN.
+ * Process the FIN. We may also need to handle PSH
+ * here and make it break out of MSG_WAITALL
*/
if (skb->h.th->fin)
@@ -1847,104 +1854,6 @@
{
tcp_dec_slow_timer(TCP_SLT_KEEPALIVE);
}
-}
-
-
-/*
- * This function returns the amount that we can raise the
- * usable window based on the following constraints
- *
- * 1. The window can never be shrunk once it is offered (RFC 793)
- * 2. We limit memory per socket
- */
-
-
-unsigned short tcp_select_window(struct sock *sk)
-{
- struct tcp_opt *tp = &sk->tp_pinfo.af_tcp;
- long free_space = sock_rspace(sk);
- long window;
- long cur_win;
- long usable;
- int mss = sk->mss;
-
- if (sk->window_clamp)
- {
- free_space = min(sk->window_clamp, free_space);
- mss = min(sk->window_clamp, mss);
- }
-
- /*
- * compute the actual window i.e.
- * old_window - received_bytes_on_that_win
- */
-
- cur_win = tp->rcv_wup - (tp->rcv_nxt - tp->rcv_wnd);
- window = tp->rcv_wnd;
-
- if ( cur_win < 0 )
- {
- cur_win = 0;
- printk(KERN_DEBUG "TSW: win < 0 w=%d 1=%u 2=%u\n",
- tp->rcv_wnd, tp->rcv_nxt, tp->rcv_wup);
- }
-
- /*
- * RFC 1122:
- * "the suggested [SWS] avoidance algoritm for the receiver is to keep
- * RECV.NEXT + RCV.WIN fixed until:
- * RCV.BUFF - RCV.USER - RCV.WINDOW >= min(1/2 RCV.BUFF, MSS)"
- *
- * i.e. don't raise the right edge of the window until you can't raise
- * it MSS bytes
- */
-
- /*
- * It would be a good idea if it didn't break header prediction.
- * and BSD made the header predition standard...
- * It expects the same value in the header i.e. th->window to be
- * constant
- */
-
- usable = free_space - cur_win;
- if (usable < 0)
- {
- usable = 0;
- }
-
- if ( window < usable )
- {
- /*
- * Window is not blocking the sender
- * and we have enought free space for it
- */
-
- if (cur_win > (sk->mss << 1))
- goto out;
- }
-
-
- if (window >= usable)
- {
- /*
- * We are offering too much, cut it down...
- * but don't shrink the window
- */
-
- window = max(usable, cur_win);
- }
- else
- {
- if ((usable - window) >= mss)
- {
- window += mss;
- }
- }
-
- out:
- tp->rcv_wnd = window;
- tp->rcv_wup = tp->rcv_nxt;
- return window;
}
/*
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov