aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@cc.helsinki.fi>1994-03-02 17:35:20 +0000
committerNicolas Pitre <nico@cam.org>2007-08-19 14:19:35 -0400
commit61bfd4ff199f5fb360c106073461e550e2ed5f0c (patch)
tree9c87d7e5b63dd26cc3af920929cb656ef82e5523
parent24497521076f7ce46c176d2dad018744e6f8cedd (diff)
downloadarchive-61bfd4ff199f5fb360c106073461e550e2ed5f0c.tar.gz
ALPHA-pl15j
-rw-r--r--Makefile2
-rw-r--r--ipc/shm.c6
-rw-r--r--net/inet/arp.c2
-rw-r--r--net/inet/proc.c2
-rw-r--r--net/inet/sock.c6
-rw-r--r--net/inet/sock.h3
-rw-r--r--net/inet/tcp.c109
-rw-r--r--net/inet/tcp.h5
8 files changed, 68 insertions, 67 deletions
diff --git a/Makefile b/Makefile
index 0fea62b..ff25f83 100644
--- a/Makefile
+++ b/Makefile
@@ -1,6 +1,6 @@
VERSION = 0.99
PATCHLEVEL = 15
-ALPHA = i
+ALPHA = j
all: Version zImage
diff --git a/ipc/shm.c b/ipc/shm.c
index ac249ec..6f8edca 100644
--- a/ipc/shm.c
+++ b/ipc/shm.c
@@ -391,6 +391,12 @@ int sys_shmat (int shmid, char *shmaddr, int shmflg, ulong *raddr)
if (shmid < 0)
return -EINVAL;
+ if (raddr) {
+ err = verify_area(VERIFY_WRITE, raddr, sizeof(long));
+ if (err)
+ return err;
+ }
+
shp = shm_segs[id = shmid % SHMMNI];
if (shp == IPC_UNUSED || shp == IPC_NOID)
return -EINVAL;
diff --git a/net/inet/arp.c b/net/inet/arp.c
index 7b1540f..e3ec49b 100644
--- a/net/inet/arp.c
+++ b/net/inet/arp.c
@@ -17,10 +17,10 @@
*
* Authors: Ross Biro, <bir7@leland.Stanford.Edu>
* Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
- * Stephen A. Wood, <saw@hallc1.cebaf.gov>
* Arnt Gulbrandsen, <agulbra@pvv.unit.no>
*
* Fixes:
+ * Stephen A. Wood : arp problems
* 'Mr Linux' : arp problems.
* Alan Cox : arp_ioctl now checks memory areas with verify_area.
* Alan Cox : Non IP arp message now only appears with debugging on.
diff --git a/net/inet/proc.c b/net/inet/proc.c
index d5bc16e..0775a41 100644
--- a/net/inet/proc.c
+++ b/net/inet/proc.c
@@ -88,7 +88,7 @@ get__netinfo(struct proto *pro, char *buffer, int format)
sp->timer.expires = 0;
pos+=sprintf(pos, "%2d: %08lX:%04X %08lX:%04X %02X %08lX:%08lX %02X:%08lX %08X %d\n",
i, src, srcp, dest, destp, sp->state,
- format==0?sp->send_seq-sp->rcv_ack_seq:sp->rmem_alloc,
+ format==0?sp->write_seq-sp->rcv_ack_seq:sp->rmem_alloc,
format==0?sp->acked_seq-sp->copied_seq:sp->wmem_alloc,
timer_active, sp->timer.expires, (unsigned) sp->retransmits,
SOCK_INODE(sp->socket)->i_uid);
diff --git a/net/inet/sock.c b/net/inet/sock.c
index e45dd7f..356e607 100644
--- a/net/inet/sock.c
+++ b/net/inet/sock.c
@@ -119,8 +119,8 @@ print_sk(struct sock *sk)
printk(" daddr = %lX, saddr = %lX\n", sk->daddr,sk->saddr);
printk(" num = %d", sk->num);
printk(" next = %p\n", sk->next);
- printk(" send_seq = %ld, acked_seq = %ld, copied_seq = %ld\n",
- sk->send_seq, sk->acked_seq, sk->copied_seq);
+ printk(" write_seq = %ld, acked_seq = %ld, copied_seq = %ld\n",
+ sk->write_seq, sk->acked_seq, sk->copied_seq);
printk(" rcv_ack_seq = %ld, window_seq = %ld, fin_seq = %ld\n",
sk->rcv_ack_seq, sk->window_seq, sk->fin_seq);
printk(" prot = %p\n", sk->prot);
@@ -838,7 +838,7 @@ inet_create(struct socket *sock, int protocol)
sk->rcvbuf = SK_RMEM_MAX;
sk->pair = NULL;
sk->opt = NULL;
- sk->send_seq = 0;
+ sk->write_seq = 0;
sk->acked_seq = 0;
sk->copied_seq = 0;
sk->fin_seq = 0;
diff --git a/net/inet/sock.h b/net/inet/sock.h
index d6dbb6a..720bbb5 100644
--- a/net/inet/sock.h
+++ b/net/inet/sock.h
@@ -55,7 +55,8 @@ struct sock {
struct options *opt;
volatile unsigned long wmem_alloc;
volatile unsigned long rmem_alloc;
- unsigned long send_seq;
+ unsigned long write_seq;
+ unsigned long sent_seq;
unsigned long acked_seq;
unsigned long copied_seq;
unsigned long rcv_ack_seq;
diff --git a/net/inet/tcp.c b/net/inet/tcp.c
index 9880c99..faf1903 100644
--- a/net/inet/tcp.c
+++ b/net/inet/tcp.c
@@ -437,10 +437,10 @@ tcp_select(struct sock *sk, int sel_type, select_table *wait)
"tcp_select: sleeping on write sk->wmem_alloc = %d, "
"sk->packets_out = %d\n"
"sk->wback = %X, sk->wfront = %X\n"
- "sk->send_seq = %u, sk->window_seq=%u\n",
+ "sk->write_seq = %u, sk->window_seq=%u\n",
sk->wmem_alloc, sk->packets_out,
sk->wback, sk->wfront,
- sk->send_seq, sk->window_seq));
+ sk->write_seq, sk->window_seq));
release_sock(sk);
return(0);
@@ -617,21 +617,14 @@ static void tcp_send_skb(struct sock *sk, struct sk_buff *skb)
/* We need to complete and send the packet. */
tcp_send_check(skb->h.th, sk->saddr, sk->daddr, size, sk);
- size -= 4*skb->h.th->doff;
- if (skb->h.th->syn)
- size++;
- if (skb->h.th->fin)
- size++;
-
- sk->send_seq += size;
- skb->h.seq = sk->send_seq;
- if (after(sk->send_seq , sk->window_seq) ||
+ skb->h.seq = sk->write_seq;
+ if (after(sk->write_seq , sk->window_seq) ||
(sk->retransmits && sk->timeout == TIME_WRITE) ||
sk->packets_out >= sk->cong_window) {
DPRINTF((DBG_TCP, "sk->cong_window = %d, sk->packets_out = %d\n",
sk->cong_window, sk->packets_out));
- DPRINTF((DBG_TCP, "sk->send_seq = %d, sk->window_seq = %d\n",
- sk->send_seq, sk->window_seq));
+ DPRINTF((DBG_TCP, "sk->write_seq = %d, sk->window_seq = %d\n",
+ sk->write_seq, sk->window_seq));
skb->next = NULL;
skb->magic = TCP_WRITE_QUEUE_MAGIC;
if (sk->wback == NULL) {
@@ -645,6 +638,7 @@ static void tcp_send_skb(struct sock *sk, struct sk_buff *skb)
sk->ack_backlog == 0)
reset_timer(sk, TIME_PROBE0, sk->rto);
} else {
+ sk->sent_seq = sk->write_seq;
sk->prot->queue_xmit(sk, skb->dev, skb, 0);
}
}
@@ -745,10 +739,6 @@ if (inet_debug == DBG_SLIP) printk("\rtcp_ack: build_header failed\n");
/* FIXME: */
memcpy(t1, th, sizeof(*t1)); /* this should probably be removed */
- /* hack-around */
- if (after(sequence, sk->window_seq))
- sequence = sk->window_seq;
-
/* swap the send and the receive. */
t1->dest = th->source;
t1->source = th->dest;
@@ -791,7 +781,7 @@ tcp_build_header(struct tcphdr *th, struct sock *sk, int push)
/* FIXME: want to get rid of this. */
memcpy(th,(void *) &(sk->dummy_th), sizeof(*th));
- th->seq = htonl(sk->send_seq);
+ th->seq = htonl(sk->write_seq);
th->psh =(push == 0) ? 1 : 0;
th->doff = sizeof(*th)/4;
th->ack = 1;
@@ -932,6 +922,7 @@ tcp_write(struct sock *sk, unsigned char *from,
from += copy;
copied += copy;
len -= copy;
+ sk->write_seq += copy;
}
if ((skb->len - hdrlen) >= sk->mss ||
(flags & MSG_OOB) ||
@@ -954,7 +945,7 @@ tcp_write(struct sock *sk, unsigned char *from,
* be queued for later rather than sent.
*/
- copy = sk->window_seq - sk->send_seq;
+ copy = sk->window_seq - sk->write_seq;
if (copy <= 0 || copy < (sk->max_window >> 1) || copy > sk->mss)
copy = sk->mss;
if (copy > len)
@@ -1051,6 +1042,7 @@ tcp_write(struct sock *sk, unsigned char *from,
len -= copy;
skb->len += copy;
skb->free = 0;
+ sk->write_seq += copy;
if (send_tmp != NULL && sk->packets_out) {
tcp_enqueue_partial(send_tmp, sk);
@@ -1071,7 +1063,7 @@ tcp_write(struct sock *sk, unsigned char *from,
if(sk->partial &&
((!sk->packets_out)
/* If not nagling we can send on the before case too.. */
- || (sk->nonagle && before(sk->send_seq , sk->window_seq))
+ || (sk->nonagle && before(sk->write_seq , sk->window_seq))
))
tcp_send_partial(sk);
/* -- */
@@ -1143,10 +1135,7 @@ tcp_read_wakeup(struct sock *sk)
t1 =(struct tcphdr *)(buff->data +tmp);
memcpy(t1,(void *) &sk->dummy_th, sizeof(*t1));
- if (after(sk->send_seq, sk->window_seq))
- t1->seq = ntohl(sk->window_seq);
- else
- t1->seq = ntohl(sk->send_seq);
+ t1->seq = htonl(sk->sent_seq);
t1->ack = 1;
t1->res1 = 0;
t1->res2 = 0;
@@ -1508,9 +1497,9 @@ tcp_shutdown(struct sock *sk, int how)
buff->len += tmp;
buff->dev = dev;
memcpy(t1, th, sizeof(*t1));
- t1->seq = ntohl(sk->send_seq);
- sk->send_seq++;
- buff->h.seq = sk->send_seq;
+ t1->seq = ntohl(sk->write_seq);
+ sk->write_seq++;
+ buff->h.seq = sk->write_seq;
t1->ack = 1;
t1->ack_seq = ntohl(sk->acked_seq);
t1->window = ntohs(sk->window=tcp_select_window(sk)/*sk->prot->rspace(sk)*/);
@@ -1530,6 +1519,7 @@ tcp_shutdown(struct sock *sk, int how)
sk->wback = buff;
buff->magic = TCP_WRITE_QUEUE_MAGIC;
} else {
+ sk->sent_seq = sk->write_seq;
sk->prot->queue_xmit(sk, dev, buff, 0);
}
@@ -1804,9 +1794,9 @@ tcp_conn_request(struct sock *sk, struct sk_buff *skb,
newsk->copied_seq = skb->h.th->seq;
newsk->state = TCP_SYN_RECV;
newsk->timeout = 0;
- newsk->send_seq = jiffies * SEQ_TICK - seq_offset;
- newsk->window_seq = newsk->send_seq;
- newsk->rcv_ack_seq = newsk->send_seq;
+ newsk->write_seq = jiffies * SEQ_TICK - seq_offset;
+ newsk->window_seq = newsk->write_seq;
+ newsk->rcv_ack_seq = newsk->write_seq;
newsk->urg_data = 0;
newsk->retransmits = 0;
newsk->destroy = 0;
@@ -1892,14 +1882,15 @@ tcp_conn_request(struct sock *sk, struct sk_buff *skb,
t1 =(struct tcphdr *)((char *)t1 +tmp);
memcpy(t1, skb->h.th, sizeof(*t1));
- buff->h.seq = newsk->send_seq;
+ buff->h.seq = newsk->write_seq;
/* Swap the send and the receive. */
t1->dest = skb->h.th->source;
t1->source = newsk->dummy_th.source;
- t1->seq = ntohl(newsk->send_seq++);
+ t1->seq = ntohl(newsk->write_seq++);
t1->ack = 1;
newsk->window = tcp_select_window(newsk);/*newsk->prot->rspace(newsk);*/
+ newsk->sent_seq = newsk->write_seq;
t1->window = ntohs(newsk->window);
t1->res1 = 0;
t1->res2 = 0;
@@ -2041,9 +2032,9 @@ tcp_close(struct sock *sk, int timeout)
buff->len += tmp;
buff->dev = dev;
memcpy(t1, th, sizeof(*t1));
- t1->seq = ntohl(sk->send_seq);
- sk->send_seq++;
- buff->h.seq = sk->send_seq;
+ t1->seq = ntohl(sk->write_seq);
+ sk->write_seq++;
+ buff->h.seq = sk->write_seq;
t1->ack = 1;
/* Ack everything immediately from now on. */
@@ -2056,6 +2047,7 @@ tcp_close(struct sock *sk, int timeout)
tcp_send_check(t1, sk->saddr, sk->daddr, sizeof(*t1), sk);
if (sk->wfront == NULL) {
+ sk->sent_seq = sk->write_seq;
prot->queue_xmit(sk, dev, buff, 0);
} else {
reset_timer(sk, TIME_WRITE, sk->rto);
@@ -2122,6 +2114,7 @@ tcp_write_xmit(struct sock *sk)
kfree_skb(skb, FREE_WRITE);
if (!sk->dead) sk->write_space(sk);
} else {
+ sk->sent_seq = skb->h.seq;
sk->prot->queue_xmit(sk, skb->dev, skb, skb->free);
}
}
@@ -2189,8 +2182,9 @@ tcp_ack(struct sock *sk, struct tcphdr *th, unsigned long saddr, int len)
if (sk->retransmits && sk->timeout == TIME_KEEPOPEN)
sk->retransmits = 0;
- if (after(ack, sk->send_seq+1) || before(ack, sk->rcv_ack_seq-1)) {
- if (after(ack, sk->send_seq) ||
+/* not quite clear why the +1 and -1 here, and why not +1 in next line */
+ if (after(ack, sk->sent_seq+1) || before(ack, sk->rcv_ack_seq-1)) {
+ if (after(ack, sk->sent_seq) ||
(sk->state != TCP_ESTABLISHED && sk->state != TCP_CLOSE_WAIT)) {
return(0);
}
@@ -2466,7 +2460,7 @@ tcp_ack(struct sock *sk, struct tcphdr *th, unsigned long saddr, int len)
if (sk->state == TCP_TIME_WAIT) {
if (!sk->dead)
sk->state_change(sk);
- if (sk->rcv_ack_seq == sk->send_seq && sk->acked_seq == sk->fin_seq) {
+ if (sk->rcv_ack_seq == sk->write_seq && sk->acked_seq == sk->fin_seq) {
flag |= 1;
sk->state = TCP_CLOSE;
sk->shutdown = SHUTDOWN_MASK;
@@ -2475,13 +2469,13 @@ tcp_ack(struct sock *sk, struct tcphdr *th, unsigned long saddr, int len)
if (sk->state == TCP_LAST_ACK || sk->state == TCP_FIN_WAIT2) {
if (!sk->dead) sk->state_change(sk);
- if (sk->rcv_ack_seq == sk->send_seq) {
+ if (sk->rcv_ack_seq == sk->write_seq) {
flag |= 1;
if (sk->acked_seq != sk->fin_seq) {
tcp_time_wait(sk);
} else {
DPRINTF((DBG_TCP, "tcp_ack closing socket - %X\n", sk));
- tcp_send_ack(sk->send_seq, sk->acked_seq, sk,
+ tcp_send_ack(sk->sent_seq, sk->acked_seq, sk,
th, sk->daddr);
sk->shutdown = SHUTDOWN_MASK;
sk->state = TCP_CLOSE;
@@ -2552,7 +2546,7 @@ tcp_data(struct sk_buff *skb, struct sock *sk,
sk->bytes_rcv += skb->len;
if (skb->len == 0 && !th->fin && !th->urg && !th->psh) {
/* Don't want to keep passing ack's back and forth. */
- if (!th->ack) tcp_send_ack(sk->send_seq, sk->acked_seq,sk, th, saddr);
+ if (!th->ack) tcp_send_ack(sk->sent_seq, sk->acked_seq,sk, th, saddr);
kfree_skb(skb, FREE_READ);
return(0);
}
@@ -2712,7 +2706,7 @@ tcp_data(struct sk_buff *skb, struct sock *sk,
if (!sk->delay_acks ||
sk->ack_backlog >= sk->max_ack_backlog ||
sk->bytes_rcv > sk->max_unacked || th->fin) {
-/* tcp_send_ack(sk->send_seq, sk->acked_seq,sk,th, saddr); */
+/* tcp_send_ack(sk->sent_seq, sk->acked_seq,sk,th, saddr); */
} else {
sk->ack_backlog++;
if(sk->debug)
@@ -2757,12 +2751,12 @@ tcp_data(struct sk_buff *skb, struct sock *sk,
#endif
kfree_skb(skb1, FREE_READ);
}
- tcp_send_ack(sk->send_seq, sk->acked_seq, sk, th, saddr);
+ tcp_send_ack(sk->sent_seq, sk->acked_seq, sk, th, saddr);
sk->ack_backlog++;
reset_timer(sk, TIME_WRITE, TCP_ACK_TIME);
} else {
/* We missed a packet. Send an ack to try to resync things. */
- tcp_send_ack(sk->send_seq, sk->acked_seq, sk, th, saddr);
+ tcp_send_ack(sk->sent_seq, sk->acked_seq, sk, th, saddr);
}
/* Now tell the user we may have some data. */
@@ -2775,10 +2769,10 @@ tcp_data(struct sk_buff *skb, struct sock *sk,
}
if (sk->state == TCP_FIN_WAIT2 &&
- sk->acked_seq == sk->fin_seq && sk->rcv_ack_seq == sk->send_seq) {
+ sk->acked_seq == sk->fin_seq && sk->rcv_ack_seq == sk->write_seq) {
DPRINTF((DBG_TCP, "tcp_data: entering last_ack state sk = %X\n", sk));
-/* tcp_send_ack(sk->send_seq, sk->acked_seq, sk, th, saddr); */
+/* tcp_send_ack(sk->sent_seq, sk->acked_seq, sk, th, saddr); */
sk->shutdown = SHUTDOWN_MASK;
sk->state = TCP_LAST_ACK;
if (!sk->dead) sk->state_change(sk);
@@ -2976,9 +2970,9 @@ tcp_connect(struct sock *sk, struct sockaddr_in *usin, int addr_len)
sk->inuse = 1;
sk->daddr = sin.sin_addr.s_addr;
- sk->send_seq = jiffies * SEQ_TICK - seq_offset;
- sk->window_seq = sk->send_seq;
- sk->rcv_ack_seq = sk->send_seq -1;
+ sk->write_seq = jiffies * SEQ_TICK - seq_offset;
+ sk->window_seq = sk->write_seq;
+ sk->rcv_ack_seq = sk->write_seq -1;
sk->err = 0;
sk->dummy_th.dest = sin.sin_port;
release_sock(sk);
@@ -3008,8 +3002,9 @@ tcp_connect(struct sock *sk, struct sockaddr_in *usin, int addr_len)
t1 = (struct tcphdr *)((char *)t1 +tmp);
memcpy(t1,(void *)&(sk->dummy_th), sizeof(*t1));
- t1->seq = ntohl(sk->send_seq++);
- buff->h.seq = sk->send_seq;
+ t1->seq = ntohl(sk->write_seq++);
+ sk->sent_seq = sk->write_seq;
+ buff->h.seq = sk->write_seq;
t1->ack = 0;
t1->window = 2;
t1->res1=0;
@@ -3067,12 +3062,12 @@ tcp_sequence(struct sock *sk, struct tcphdr *th, short len,
unsigned long next_seq;
next_seq = len - 4*th->doff;
+ if (th->fin)
+ next_seq++;
/* if we have a zero window, we can't have any data in the packet.. */
if (next_seq && !sk->window)
goto ignore_it;
next_seq += th->seq;
- if (th->syn)
- next_seq++;
/*
* This isn't quite right. sk->acked_seq could be more recent
@@ -3110,7 +3105,7 @@ ignore_it:
return 0;
/* Try to resync things. */
- tcp_send_ack(sk->send_seq, sk->acked_seq, sk, th, saddr);
+ tcp_send_ack(sk->sent_seq, sk->acked_seq, sk, th, saddr);
return 0;
}
@@ -3261,7 +3256,7 @@ if (inet_debug == DBG_SLIP) printk("\rtcp_rcv: not in seq\n");
#ifdef undef
/* nice idea, but tcp_sequence already does this. Maybe it shouldn't?? */
if(!th->rst)
- tcp_send_ack(sk->send_seq, sk->acked_seq,
+ tcp_send_ack(sk->sent_seq, sk->acked_seq,
sk, th, saddr);
#endif
kfree_skb(skb, FREE_READ);
@@ -3458,7 +3453,7 @@ if (inet_debug == DBG_SLIP) printk("\rtcp_rcv: not in seq\n");
/* Ack the syn and fall through. */
sk->acked_seq = th->seq+1;
sk->fin_seq = th->seq;
- tcp_send_ack(sk->send_seq, th->seq+1,
+ tcp_send_ack(sk->sent_seq, th->seq+1,
sk, th, sk->daddr);
case TCP_SYN_RECV:
@@ -3586,7 +3581,7 @@ tcp_write_wakeup(struct sock *sk)
* Use a previous sequence.
* This should cause the other end to send an ack.
*/
- t1->seq = ntohl(sk->send_seq-1);
+ t1->seq = htonl(sk->sent_seq-1);
t1->ack = 1;
t1->res1= 0;
t1->res2= 0;
diff --git a/net/inet/tcp.h b/net/inet/tcp.h
index 1dd91ad..b0b1a3f 100644
--- a/net/inet/tcp.h
+++ b/net/inet/tcp.h
@@ -80,13 +80,12 @@
*/
static inline int before(unsigned long seq1, unsigned long seq2)
{
- seq2 -= seq1+1;
- return (seq2 < 65536);
+ return (long)(seq1-seq2) < 0;
}
static inline int after(unsigned long seq1, unsigned long seq2)
{
- return before(seq2, seq1);
+ return (long)(seq1-seq2) > 0;
}