diff options
author | Linus Torvalds <torvalds@cc.helsinki.fi> | 1994-03-02 17:35:20 +0000 |
---|---|---|
committer | Nicolas Pitre <nico@cam.org> | 2007-08-19 14:19:35 -0400 |
commit | 61bfd4ff199f5fb360c106073461e550e2ed5f0c (patch) | |
tree | 9c87d7e5b63dd26cc3af920929cb656ef82e5523 | |
parent | 24497521076f7ce46c176d2dad018744e6f8cedd (diff) | |
download | archive-61bfd4ff199f5fb360c106073461e550e2ed5f0c.tar.gz |
ALPHA-pl15j
-rw-r--r-- | Makefile | 2 | ||||
-rw-r--r-- | ipc/shm.c | 6 | ||||
-rw-r--r-- | net/inet/arp.c | 2 | ||||
-rw-r--r-- | net/inet/proc.c | 2 | ||||
-rw-r--r-- | net/inet/sock.c | 6 | ||||
-rw-r--r-- | net/inet/sock.h | 3 | ||||
-rw-r--r-- | net/inet/tcp.c | 109 | ||||
-rw-r--r-- | net/inet/tcp.h | 5 |
8 files changed, 68 insertions, 67 deletions
@@ -1,6 +1,6 @@ VERSION = 0.99 PATCHLEVEL = 15 -ALPHA = i +ALPHA = j all: Version zImage @@ -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; } |