Commit a6b61aab authored by Linus Torvalds's avatar Linus Torvalds

Import 0.99.15j

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