18b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* 28b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * Copyright (c) 1982, 1986, 1988, 1990, 1993, 1994 38b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * The Regents of the University of California. All rights reserved. 48b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * 58b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * Redistribution and use in source and binary forms, with or without 68b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * modification, are permitted provided that the following conditions 78b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * are met: 88b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * 1. Redistributions of source code must retain the above copyright 98b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * notice, this list of conditions and the following disclaimer. 108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * 2. Redistributions in binary form must reproduce the above copyright 118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * notice, this list of conditions and the following disclaimer in the 128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * documentation and/or other materials provided with the distribution. 135d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner * 3. Neither the name of the University nor the names of its contributors 148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * may be used to endorse or promote products derived from this software 158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * without specific prior written permission. 168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * 178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * SUCH DAMAGE. 288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * 298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * @(#)tcp_input.c 8.5 (Berkeley) 4/10/94 308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * tcp_input.c,v 1.10 1994/10/13 18:36:32 wollman Exp 318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project */ 328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* 348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * Changes and additions relating to SLiRP 358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * Copyright (c) 1995 Danny Gasparovski. 368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * 378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * Please read the file COPYRIGHT for the 388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * terms and conditions of the copyright. 398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project */ 408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include <slirp.h> 428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include "ip_icmp.h" 438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstruct socket tcb; 458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 465d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#define TCPREXMTTHRESH 3 478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstruct socket *tcp_last_so = &tcb; 488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projecttcp_seq tcp_iss; /* tcp initial send seq # */ 508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define TCP_PAWS_IDLE (24 * 24 * 60 * 60 * PR_SLOWHZ) 528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* for modulo comparisons of timestamps */ 548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define TSTMP_LT(a,b) ((int)((a)-(b)) < 0) 558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define TSTMP_GEQ(a,b) ((int)((a)-(b)) >= 0) 568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* 588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * Insert segment ti into reassembly queue of tcp with 598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * control block tp. Return TH_FIN if reassembly now includes 608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * a segment with FIN. The macro form does the common case inline 618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * (segment is the next to be received on an established connection, 628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * and the queue is empty), avoiding linkage into and removal 638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * from the queue and repetition of various conversions. 648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * Set DELACK for segments received in order, but ack immediately 658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * when segments are out of order (so fast retransmit can work). 668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project */ 678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef TCP_ACK_HACK 688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define TCP_REASS(tp, ti, m, so, flags) {\ 698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if ((ti)->ti_seq == (tp)->rcv_nxt && \ 708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tcpfrag_list_empty(tp) && \ 718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project (tp)->t_state == TCPS_ESTABLISHED) {\ 728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (ti->ti_flags & TH_PUSH) \ 738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tp->t_flags |= TF_ACKNOW; \ 748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project else \ 758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tp->t_flags |= TF_DELACK; \ 768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project (tp)->rcv_nxt += (ti)->ti_len; \ 778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project flags = (ti)->ti_flags & TH_FIN; \ 785d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner STAT(tcpstat.tcps_rcvpack++); \ 795d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner STAT(tcpstat.tcps_rcvbyte += (ti)->ti_len); \ 808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (so->so_emu) { \ 815d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner if (tcp_emu((so),(m))) sbappend((so), (m)); \ 828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } else \ 835d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner sbappend((so), (m)); \ 848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* sorwakeup(so); */ \ 858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } else {\ 868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project (flags) = tcp_reass((tp), (ti), (m)); \ 878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tp->t_flags |= TF_ACKNOW; \ 888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } \ 898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#else 918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define TCP_REASS(tp, ti, m, so, flags) { \ 928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if ((ti)->ti_seq == (tp)->rcv_nxt && \ 935d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner tcpfrag_list_empty(tp) && \ 948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project (tp)->t_state == TCPS_ESTABLISHED) { \ 958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tp->t_flags |= TF_DELACK; \ 968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project (tp)->rcv_nxt += (ti)->ti_len; \ 978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project flags = (ti)->ti_flags & TH_FIN; \ 985d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner STAT(tcpstat.tcps_rcvpack++); \ 995d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner STAT(tcpstat.tcps_rcvbyte += (ti)->ti_len); \ 1008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (so->so_emu) { \ 1015d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner if (tcp_emu((so),(m))) sbappend(so, (m)); \ 1028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } else \ 1035d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner sbappend((so), (m)); \ 1048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* sorwakeup(so); */ \ 1058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } else { \ 1068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project (flags) = tcp_reass((tp), (ti), (m)); \ 1078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tp->t_flags |= TF_ACKNOW; \ 1088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } \ 1098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 1108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif 1115d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic void tcp_dooptions(struct tcpcb *tp, u_char *cp, int cnt, 1125d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner struct tcpiphdr *ti); 1135d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic void tcp_xmit_timer(register struct tcpcb *tp, int rtt); 1148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1155d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic int 1165d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnertcp_reass(register struct tcpcb *tp, register struct tcpiphdr *ti, 1175d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner struct mbuf *m) 1188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 1198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project register struct tcpiphdr *q; 1208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project struct socket *so = tp->t_socket; 1218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int flags; 1228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* 1245d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner * Call with ti==NULL after become established to 1258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * force pre-ESTABLISHED data up to user socket. 1268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project */ 1275d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner if (ti == NULL) 1288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project goto present; 1298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* 1318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * Find a segment which begins after this one does. 1328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project */ 1338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project for (q = tcpfrag_list_first(tp); !tcpfrag_list_end(q, tp); 1345d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner q = tcpiphdr_next(q)) 1358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (SEQ_GT(q->ti_seq, ti->ti_seq)) 1368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project break; 1378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* 1398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * If there is a preceding segment, it may provide some of 1408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * our data already. If so, drop the data from the incoming 1418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * segment. If it provides all of our data, drop us. 1428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project */ 1438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (!tcpfrag_list_end(tcpiphdr_prev(q), tp)) { 1448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project register int i; 1458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project q = tcpiphdr_prev(q); 1468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* conversion to int (in i) handles seq wraparound */ 1478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project i = q->ti_seq + q->ti_len - ti->ti_seq; 1488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (i > 0) { 1498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (i >= ti->ti_len) { 1505d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner STAT(tcpstat.tcps_rcvduppack++); 1515d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner STAT(tcpstat.tcps_rcvdupbyte += ti->ti_len); 1525d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner m_freem(m); 1538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* 1548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * Try to present any queued data 1558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * at the left window edge to the user. 1568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * This is needed after the 3-WHS 1578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * completes. 1588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project */ 1598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project goto present; /* ??? */ 1608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 1615d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner m_adj(m, i); 1628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ti->ti_len -= i; 1638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ti->ti_seq += i; 1648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 1658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project q = tcpiphdr_next(q); 1668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 1675d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner STAT(tcpstat.tcps_rcvoopack++); 1685d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner STAT(tcpstat.tcps_rcvoobyte += ti->ti_len); 1698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ti->ti_mbuf = m; 1708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* 1728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * While we overlap succeeding segments trim them or, 1738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * if they are completely covered, dequeue them. 1748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project */ 1758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project while (!tcpfrag_list_end(q, tp)) { 1768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project register int i = (ti->ti_seq + ti->ti_len) - q->ti_seq; 1778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (i <= 0) 1788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project break; 1798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (i < q->ti_len) { 1808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project q->ti_seq += i; 1818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project q->ti_len -= i; 1825d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner m_adj(q->ti_mbuf, i); 1838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project break; 1848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 1858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project q = tcpiphdr_next(q); 1868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project m = tcpiphdr_prev(q)->ti_mbuf; 1878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project remque(tcpiphdr2qlink(tcpiphdr_prev(q))); 1885d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner m_freem(m); 1898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 1908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* 1928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * Stick new segment in its place. 1938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project */ 1948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project insque(tcpiphdr2qlink(ti), tcpiphdr2qlink(tcpiphdr_prev(q))); 1958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectpresent: 1978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* 1988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * Present data to user, advancing rcv_nxt through 1998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * completed sequence space. 2008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project */ 2018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (!TCPS_HAVEESTABLISHED(tp->t_state)) 2028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return (0); 2035d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner ti = tcpfrag_list_first(tp); 2045d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner if (tcpfrag_list_end(ti, tp) || ti->ti_seq != tp->rcv_nxt) 2058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return (0); 2068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (tp->t_state == TCPS_SYN_RECEIVED && ti->ti_len) 2078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return (0); 2088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project do { 2098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tp->rcv_nxt += ti->ti_len; 2108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project flags = ti->ti_flags & TH_FIN; 2118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project remque(tcpiphdr2qlink(ti)); 2128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project m = ti->ti_mbuf; 2138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ti = tcpiphdr_next(ti); 2148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* if (so->so_state & SS_FCANTRCVMORE) */ 2158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (so->so_state & SS_FCANTSENDMORE) 2165d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner m_freem(m); 2178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project else { 2188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (so->so_emu) { 2195d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner if (tcp_emu(so,m)) sbappend(so, m); 2208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } else 2215d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner sbappend(so, m); 2228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 2235d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner } while (ti != (struct tcpiphdr *)tp && ti->ti_seq == tp->rcv_nxt); 2248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* sorwakeup(so); */ 2258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return (flags); 2268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 2278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 2288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* 2298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * TCP input routine, follows pages 65-76 of the 2308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * protocol specification dated September, 1981 very closely. 2318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project */ 2328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid 2335d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnertcp_input(struct mbuf *m, int iphlen, struct socket *inso) 2348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 2358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project struct ip save_ip, *ip; 2368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project register struct tcpiphdr *ti; 2378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project caddr_t optp = NULL; 2388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int optlen = 0; 2398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int len, tlen, off; 2405d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner register struct tcpcb *tp = NULL; 2418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project register int tiflags; 2425d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner struct socket *so = NULL; 2438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int todrop, acked, ourfinisacked, needoutput = 0; 2448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* int dropsocket = 0; */ 2458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int iss = 0; 2468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project u_long tiwin; 2478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int ret; 2488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* int ts_present = 0; */ 2495d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner struct ex_list *ex_ptr; 2508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 2518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project DEBUG_CALL("tcp_input"); 2528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project DEBUG_ARGS((dfd," m = %8lx iphlen = %2d inso = %lx\n", 2538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project (long )m, iphlen, (long )inso )); 2548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 2558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* 2568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * If called with m == 0, then we're continuing the connect 2578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project */ 2588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (m == NULL) { 2598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project so = inso; 2608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 2618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* Re-set a few variables */ 2628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tp = sototcpcb(so); 2638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project m = so->so_m; 2645d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner so->so_m = NULL; 2658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ti = so->so_ti; 2668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tiwin = ti->ti_win; 2678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tiflags = ti->ti_flags; 2688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 2698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project goto cont_conn; 2708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 2718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 2728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 2735d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner STAT(tcpstat.tcps_rcvtotal++); 2748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* 2758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * Get IP and TCP header together in first mbuf. 2768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * Note: IP leaves IP header in first mbuf. 2778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project */ 2785d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner ti = mtod(m, struct tcpiphdr *); 2798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (iphlen > sizeof(struct ip )) { 2805d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner ip_stripoptions(m, (struct mbuf *)0); 2818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project iphlen=sizeof(struct ip ); 2828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 2838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* XXX Check if too short */ 2848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 2858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 2868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* 2878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * Save a copy of the IP header in case we want restore it 2888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * for sending an ICMP error message in response. 2898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project */ 2905d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner ip=mtod(m, struct ip *); 2918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project save_ip = *ip; 2928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project save_ip.ip_len+= iphlen; 2938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 2948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* 2958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * Checksum extended TCP header and data. 2968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project */ 2978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tlen = ((struct ip *)ti)->ip_len; 2985d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner tcpiphdr2qlink(ti)->next = tcpiphdr2qlink(ti)->prev = NULL; 2995d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner memset(&ti->ti_i.ih_mbuf, 0 , sizeof(struct mbuf_ptr)); 3008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ti->ti_x1 = 0; 3018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ti->ti_len = htons((u_int16_t)tlen); 3028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project len = sizeof(struct ip ) + tlen; 3038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* keep checksum for ICMP reply 3048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * ti->ti_sum = cksum(m, len); 3058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * if (ti->ti_sum) { */ 3068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if(cksum(m, len)) { 3075d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner STAT(tcpstat.tcps_rcvbadsum++); 3088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project goto drop; 3098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 3108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 3118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* 3128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * Check that TCP offset makes sense, 3138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * pull out TCP options and adjust length. XXX 3148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project */ 3158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project off = ti->ti_off << 2; 3168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (off < sizeof (struct tcphdr) || off > tlen) { 3175d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner STAT(tcpstat.tcps_rcvbadoff++); 3188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project goto drop; 3198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 3208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tlen -= off; 3218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ti->ti_len = tlen; 3228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (off > sizeof (struct tcphdr)) { 3238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project optlen = off - sizeof (struct tcphdr); 3245d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner optp = mtod(m, caddr_t) + sizeof (struct tcpiphdr); 3258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 3268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* 3278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * Do quick retrieval of timestamp options ("options 3288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * prediction?"). If timestamp is the only option and it's 3298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * formatted as recommended in RFC 1323 appendix A, we 3308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * quickly get the values now and not bother calling 3318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * tcp_dooptions(), etc. 3328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project */ 3338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* if ((optlen == TCPOLEN_TSTAMP_APPA || 3348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * (optlen > TCPOLEN_TSTAMP_APPA && 3358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * optp[TCPOLEN_TSTAMP_APPA] == TCPOPT_EOL)) && 3368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * *(u_int32_t *)optp == htonl(TCPOPT_TSTAMP_HDR) && 3378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * (ti->ti_flags & TH_SYN) == 0) { 3388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * ts_present = 1; 3398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * ts_val = ntohl(*(u_int32_t *)(optp + 4)); 3408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * ts_ecr = ntohl(*(u_int32_t *)(optp + 8)); 3418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * optp = NULL; / * we've parsed the options * / 3428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * } 3438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project */ 3448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 3458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tiflags = ti->ti_flags; 3468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 3478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* 3488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * Convert TCP protocol specific fields to host format. 3498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project */ 3508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project NTOHL(ti->ti_seq); 3518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project NTOHL(ti->ti_ack); 3528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project NTOHS(ti->ti_win); 3538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project NTOHS(ti->ti_urp); 3548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 3558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* 3568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * Drop TCP, IP headers and TCP options. 3578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project */ 3588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project m->m_data += sizeof(struct tcpiphdr)+off-sizeof(struct tcphdr); 3598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project m->m_len -= sizeof(struct tcpiphdr)+off-sizeof(struct tcphdr); 3608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 3615d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner if (slirp_restrict) { 3625d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner for (ex_ptr = exec_list; ex_ptr; ex_ptr = ex_ptr->ex_next) 3635d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner if (ex_ptr->ex_fport == port_geth(ti->ti_dport) && 3645d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner (ip_geth(ti->ti_dst) & 0xff) == ex_ptr->ex_addr) 3655d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner break; 3665d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 3675d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner if (!ex_ptr) 3685d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner goto drop; 3695d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner } 3708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* 3718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * Locate pcb for segment. 3728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project */ 3738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectfindso: 3748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project so = tcp_last_so; 3755d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner { 3765d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner uint32_t srcip = ip_geth(ti->ti_src); 3775d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner uint32_t dstip = ip_geth(ti->ti_dst); 3785d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner uint16_t dstport = port_geth(ti->ti_dport); 3795d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner uint16_t srcport = port_geth(ti->ti_sport); 3805d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 3815d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner if (so->so_faddr_port != dstport || 3825d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner so->so_laddr_port != srcport || 3835d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner so->so_laddr_ip != srcip || 3845d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner so->so_faddr_ip != dstip) { 3855d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner so = solookup(&tcb, srcip, srcport, dstip, dstport); 3865d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner if (so) 3875d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner tcp_last_so = so; 3885d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner STAT(tcpstat.tcps_socachemiss++); 3895d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner } 3905d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner } 3918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* 3928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * If the state is CLOSED (i.e., TCB does not exist) then 3938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * all data in the incoming segment is discarded. 3948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * If the TCB exists but is in CLOSED state, it is embryonic, 3958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * but should either do a listen or a connect soon. 3968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * 3978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * state == CLOSED means we've done socreate() but haven't 3988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * attached it to a protocol yet... 3998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * 4008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * XXX If a TCB does not exist, and the TH_SYN flag is 4018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * the only flag set, then create a session, mark it 4028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * as if it was LISTENING, and continue... 4038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project */ 4045d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner if (so == NULL) { 4058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if ((tiflags & (TH_SYN|TH_FIN|TH_RST|TH_URG|TH_ACK)) != TH_SYN) 4068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project goto dropwithreset; 4078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 4088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if ((so = socreate()) == NULL) 4098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project goto dropwithreset; 4108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (tcp_attach(so) < 0) { 4118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project free(so); /* Not sofree (if it failed, it's not insqued) */ 4128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project goto dropwithreset; 4138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 4148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 4155d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner sbreserve(&so->so_snd, TCP_SNDSPACE); 4165d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner sbreserve(&so->so_rcv, TCP_RCVSPACE); 4178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 4188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* tcp_last_so = so; */ /* XXX ? */ 4198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* tp = sototcpcb(so); */ 4208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 4218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project so->so_laddr_ip = ip_geth(ti->ti_src); 4228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project so->so_laddr_port = port_geth(ti->ti_sport); 4238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project so->so_faddr_ip = ip_geth(ti->ti_dst); 4248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project so->so_faddr_port = port_geth(ti->ti_dport); 4258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 4268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if ((so->so_iptos = tcp_tos(so)) == 0) 4278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project so->so_iptos = ((struct ip *)ti)->ip_tos; 4288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 4298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tp = sototcpcb(so); 4308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tp->t_state = TCPS_LISTEN; 4318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 4328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 4338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* 4348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * If this is a still-connecting socket, this probably 4358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * a retransmit of the SYN. Whether it's a retransmit SYN 4368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * or something else, we nuke it. 4378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project */ 4388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (so->so_state & SS_ISFCONNECTING) 4398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project goto drop; 4408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 4418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tp = sototcpcb(so); 4428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 4438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* XXX Should never fail */ 4445d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner if (tp == NULL) 4458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project goto dropwithreset; 4468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (tp->t_state == TCPS_CLOSED) 4478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project goto drop; 4488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 4498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* Unscale the window into a 32-bit value. */ 4508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* if ((tiflags & TH_SYN) == 0) 4518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * tiwin = ti->ti_win << tp->snd_scale; 4528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * else 4538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project */ 4548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tiwin = ti->ti_win; 4558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 4568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* 4578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * Segment received on connection. 4588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * Reset idle time and keep-alive timer. 4598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project */ 4608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tp->t_idle = 0; 4615d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner if (SO_OPTIONS) 4625d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner tp->t_timer[TCPT_KEEP] = TCPTV_KEEPINTVL; 4638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project else 4645d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner tp->t_timer[TCPT_KEEP] = TCPTV_KEEP_IDLE; 4658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 4668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* 4678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * Process options if not in LISTEN state, 4688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * else do it below (after getting remote address). 4698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project */ 4708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (optp && tp->t_state != TCPS_LISTEN) 4718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tcp_dooptions(tp, (u_char *)optp, optlen, ti); 4728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* , */ 4738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* &ts_present, &ts_val, &ts_ecr); */ 4748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 4758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* 4768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * Header prediction: check for the two common cases 4778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * of a uni-directional data xfer. If the packet has 4788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * no control flags, is in-sequence, the window didn't 4798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * change and we're not retransmitting, it's a 4808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * candidate. If the length is zero and the ack moved 4818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * forward, we're the sender side of the xfer. Just 4828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * free the data acked & wake any higher level process 4838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * that was blocked waiting for space. If the length 4848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * is non-zero and the ack didn't move, we're the 4858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * receiver side. If we're getting packets in-order 4868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * (the reassembly queue is empty), add the data to 4878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * the socket buffer and note that we need a delayed ack. 4888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * 4898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * XXX Some of these tests are not needed 4908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * eg: the tiwin == tp->snd_wnd prevents many more 4918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * predictions.. with no *real* advantage.. 4928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project */ 4938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (tp->t_state == TCPS_ESTABLISHED && 4948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project (tiflags & (TH_SYN|TH_FIN|TH_RST|TH_URG|TH_ACK)) == TH_ACK && 4958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* (!ts_present || TSTMP_GEQ(ts_val, tp->ts_recent)) && */ 4968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ti->ti_seq == tp->rcv_nxt && 4978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tiwin && tiwin == tp->snd_wnd && 4988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tp->snd_nxt == tp->snd_max) { 4998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* 5008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * If last ACK falls within this segment's sequence numbers, 5018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * record the timestamp. 5028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project */ 5038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* if (ts_present && SEQ_LEQ(ti->ti_seq, tp->last_ack_sent) && 5048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * SEQ_LT(tp->last_ack_sent, ti->ti_seq + ti->ti_len)) { 5058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * tp->ts_recent_age = tcp_now; 5068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * tp->ts_recent = ts_val; 5078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * } 5088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project */ 5098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (ti->ti_len == 0) { 5108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (SEQ_GT(ti->ti_ack, tp->snd_una) && 5118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project SEQ_LEQ(ti->ti_ack, tp->snd_max) && 5128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tp->snd_cwnd >= tp->snd_wnd) { 5138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* 5148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * this is a pure ack for outstanding data. 5158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project */ 5165d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner STAT(tcpstat.tcps_predack++); 5178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* if (ts_present) 5188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * tcp_xmit_timer(tp, tcp_now-ts_ecr+1); 5198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * else 5208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project */ if (tp->t_rtt && 5218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project SEQ_GT(ti->ti_ack, tp->t_rtseq)) 5228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tcp_xmit_timer(tp, tp->t_rtt); 5238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project acked = ti->ti_ack - tp->snd_una; 5245d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner STAT(tcpstat.tcps_rcvackpack++); 5255d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner STAT(tcpstat.tcps_rcvackbyte += acked); 5265d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner sbdrop(&so->so_snd, acked); 5278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tp->snd_una = ti->ti_ack; 5285d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner m_freem(m); 5298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 5308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* 5318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * If all outstanding data are acked, stop 5328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * retransmit timer, otherwise restart timer 5338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * using current (possibly backed-off) value. 5348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * If process is waiting for space, 5358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * wakeup/selwakeup/signal. If data 5368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * are ready to send, let tcp_output 5378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * decide between more output or persist. 5388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project */ 5398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (tp->snd_una == tp->snd_max) 5408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tp->t_timer[TCPT_REXMT] = 0; 5418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project else if (tp->t_timer[TCPT_PERSIST] == 0) 5428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tp->t_timer[TCPT_REXMT] = tp->t_rxtcur; 5438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 5448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* 5458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * There's room in so_snd, sowwakup will read() 5468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * from the socket if we can 5478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project */ 5488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* if (so->so_snd.sb_flags & SB_NOTIFY) 5498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * sowwakeup(so); 5508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project */ 5518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* 5528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * This is called because sowwakeup might have 5538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * put data into so_snd. Since we don't so sowwakeup, 5548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * we don't need this.. XXX??? 5558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project */ 5568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (so->so_snd.sb_cc) 5578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project (void) tcp_output(tp); 5588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 5598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return; 5608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 5618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } else if (ti->ti_ack == tp->snd_una && 5628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tcpfrag_list_empty(tp) && 5635d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner ti->ti_len <= sbspace(&so->so_rcv)) { 5648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* 5658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * this is a pure, in-sequence data packet 5668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * with nothing on the reassembly queue and 5678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * we have enough buffer space to take it. 5688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project */ 5695d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner STAT(tcpstat.tcps_preddat++); 5708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tp->rcv_nxt += ti->ti_len; 5715d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner STAT(tcpstat.tcps_rcvpack++); 5725d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner STAT(tcpstat.tcps_rcvbyte += ti->ti_len); 5738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* 5748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * Add data to socket buffer. 5758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project */ 5768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (so->so_emu) { 5775d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner if (tcp_emu(so,m)) sbappend(so, m); 5788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } else 5795d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner sbappend(so, m); 5808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 5818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* 5828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * XXX This is called when data arrives. Later, check 5838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * if we can actually write() to the socket 5848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * XXX Need to check? It's be NON_BLOCKING 5858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project */ 5868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* sorwakeup(so); */ 5878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 5888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* 5898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * If this is a short packet, then ACK now - with Nagel 5908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * congestion avoidance sender won't send more until 5918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * he gets an ACK. 5928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * 5938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * It is better to not delay acks at all to maximize 5948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * TCP throughput. See RFC 2581. 5958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project */ 5968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tp->t_flags |= TF_ACKNOW; 5978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tcp_output(tp); 5988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return; 5998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 6008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } /* header prediction */ 6018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* 6028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * Calculate amount of space in receive window, 6038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * and then do TCP input processing. 6048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * Receive window is amount of space in rcv queue, 6058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * but not less than advertised window. 6068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project */ 6078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project { int win; 6085d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner win = sbspace(&so->so_rcv); 6098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (win < 0) 6108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project win = 0; 6118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tp->rcv_wnd = max(win, (int)(tp->rcv_adv - tp->rcv_nxt)); 6128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 6138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 6148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project switch (tp->t_state) { 6158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 6168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* 6178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * If the state is LISTEN then ignore segment if it contains an RST. 6188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * If the segment contains an ACK then it is bad and send a RST. 6198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * If it does not contain a SYN then it is not interesting; drop it. 6208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * Don't bother responding if the destination was a broadcast. 6218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * Otherwise initialize tp->rcv_nxt, and tp->irs, select an initial 6228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * tp->iss, and send a segment: 6238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * <SEQ=ISS><ACK=RCV_NXT><CTL=SYN,ACK> 6248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * Also initialize tp->snd_nxt to tp->iss+1 and tp->snd_una to tp->iss. 6258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * Fill in remote peer address fields if not previously specified. 6268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * Enter SYN_RECEIVED state, and process any other fields of this 6278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * segment in this state. 6288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project */ 6298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case TCPS_LISTEN: { 6308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 6318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (tiflags & TH_RST) 6328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project goto drop; 6338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (tiflags & TH_ACK) 6348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project goto dropwithreset; 6358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if ((tiflags & TH_SYN) == 0) 6368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project goto drop; 6378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 6388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* 6398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * This has way too many gotos... 6408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * But a bit of spaghetti code never hurt anybody :) 6418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project */ 6428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 6438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* 6448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * If this is destined for the control address, then flag to 6458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * tcp_ctl once connected, otherwise connect 6468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project */ 6478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if ((so->so_faddr_ip & 0xffffff00) == special_addr_ip) { 6485d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner int lastbyte=so->so_faddr_ip & 0xff; 6495d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner if (lastbyte!=CTL_ALIAS && lastbyte!=CTL_DNS) { 6505d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#if 0 6515d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner if(lastbyte==CTL_CMD || lastbyte==CTL_EXEC) { 6525d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner /* Command or exec adress */ 6535d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner so->so_state |= SS_CTL; 6545d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner } else 6555d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif 6565d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner { 6575d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner /* May be an add exec */ 6585d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner for(ex_ptr = exec_list; ex_ptr; ex_ptr = ex_ptr->ex_next) { 6595d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner if(ex_ptr->ex_fport == so->so_faddr_port && 6605d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner lastbyte == ex_ptr->ex_addr) { 6615d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner so->so_state |= SS_CTL; 6625d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner break; 6635d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner } 6645d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner } 6655d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner } 6665d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner if(so->so_state & SS_CTL) goto cont_input; 6675d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner } 6688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* CTL_ALIAS: Do nothing, tcp_fconnect will be called on it */ 6698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 6708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 6718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (so->so_emu & EMU_NOCONNECT) { 6728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project so->so_emu &= ~EMU_NOCONNECT; 6738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project goto cont_input; 6748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 6758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 676ce0f4b02160ee72d7d2428867fe757bc37c68c98David 'Digit' Turner if((tcp_fconnect(so) == -1) && (errno != EINPROGRESS) && 677ce0f4b02160ee72d7d2428867fe757bc37c68c98David 'Digit' Turner (errno != EWOULDBLOCK) && (errno != EAGAIN)) { 6788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project u_char code=ICMP_UNREACH_NET; 6798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project DEBUG_MISC((dfd," tcp fconnect errno = %d-%s\n", 6808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project errno,errno_str)); 6818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if(errno == ECONNREFUSED) { 6828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* ACK the SYN, send RST to refuse the connection */ 6838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tcp_respond(tp, ti, m, ti->ti_seq+1, (tcp_seq)0, 6848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project TH_RST|TH_ACK); 6858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } else { 6868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if(errno == EHOSTUNREACH) code=ICMP_UNREACH_HOST; 6878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project HTONL(ti->ti_seq); /* restore tcp header */ 6888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project HTONL(ti->ti_ack); 6898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project HTONS(ti->ti_win); 6908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project HTONS(ti->ti_urp); 6918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project m->m_data -= sizeof(struct tcpiphdr)+off-sizeof(struct tcphdr); 6928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project m->m_len += sizeof(struct tcpiphdr)+off-sizeof(struct tcphdr); 6938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *ip=save_ip; 6948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project icmp_error(m, ICMP_UNREACH,code, 0,errno_str); 6958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 6968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tp = tcp_close(tp); 6975d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner m_free(m); 6988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } else { 6998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* 7008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * Haven't connected yet, save the current mbuf 7018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * and ti, and return 7028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * XXX Some OS's don't tell us whether the connect() 7038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * succeeded or not. So we must time it out. 7048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project */ 7058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project so->so_m = m; 7068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project so->so_ti = ti; 7078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tp->t_timer[TCPT_KEEP] = TCPTV_KEEP_INIT; 7088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tp->t_state = TCPS_SYN_RECEIVED; 7098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 7108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return; 7118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 7128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project cont_conn: 7138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* m==NULL 7148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * Check if the connect succeeded 7158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project */ 7168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (so->so_state & SS_NOFDREF) { 7178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tp = tcp_close(tp); 7188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project goto dropwithreset; 7198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 7208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project cont_input: 7218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tcp_template(tp); 7228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 7238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (optp) 7248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tcp_dooptions(tp, (u_char *)optp, optlen, ti); 7258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* , */ 7268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* &ts_present, &ts_val, &ts_ecr); */ 7278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 7288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (iss) 7298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tp->iss = iss; 7308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project else 7318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tp->iss = tcp_iss; 7328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tcp_iss += TCP_ISSINCR/2; 7338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tp->irs = ti->ti_seq; 7348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tcp_sendseqinit(tp); 7358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tcp_rcvseqinit(tp); 7368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tp->t_flags |= TF_ACKNOW; 7378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tp->t_state = TCPS_SYN_RECEIVED; 7388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tp->t_timer[TCPT_KEEP] = TCPTV_KEEP_INIT; 7395d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner STAT(tcpstat.tcps_accepts++); 7408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project goto trimthenstep6; 7418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } /* case TCPS_LISTEN */ 7428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 7438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* 7448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * If the state is SYN_SENT: 7458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * if seg contains an ACK, but not for our SYN, drop the input. 7468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * if seg contains a RST, then drop the connection. 7478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * if seg does not contain SYN, then drop it. 7488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * Otherwise this is an acceptable SYN segment 7498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * initialize tp->rcv_nxt and tp->irs 7508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * if seg contains ack then advance tp->snd_una 7518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * if SYN has been acked change to ESTABLISHED else SYN_RCVD state 7528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * arrange for segment to be acked (eventually) 7538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * continue processing rest of data/controls, beginning with URG 7548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project */ 7558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case TCPS_SYN_SENT: 7568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if ((tiflags & TH_ACK) && 7578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project (SEQ_LEQ(ti->ti_ack, tp->iss) || 7588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project SEQ_GT(ti->ti_ack, tp->snd_max))) 7598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project goto dropwithreset; 7608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 7618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (tiflags & TH_RST) { 7628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (tiflags & TH_ACK) 7638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tp = tcp_drop(tp,0); /* XXX Check t_softerror! */ 7648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project goto drop; 7658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 7668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 7678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if ((tiflags & TH_SYN) == 0) 7688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project goto drop; 7698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (tiflags & TH_ACK) { 7708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tp->snd_una = ti->ti_ack; 7718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (SEQ_LT(tp->snd_nxt, tp->snd_una)) 7728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tp->snd_nxt = tp->snd_una; 7738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 7748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 7758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tp->t_timer[TCPT_REXMT] = 0; 7768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tp->irs = ti->ti_seq; 7778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tcp_rcvseqinit(tp); 7788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tp->t_flags |= TF_ACKNOW; 7798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (tiflags & TH_ACK && SEQ_GT(tp->snd_una, tp->iss)) { 7805d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner STAT(tcpstat.tcps_connects++); 7818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project soisfconnected(so); 7828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tp->t_state = TCPS_ESTABLISHED; 7838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 7848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* Do window scaling on this connection? */ 7858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* if ((tp->t_flags & (TF_RCVD_SCALE|TF_REQ_SCALE)) == 7868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * (TF_RCVD_SCALE|TF_REQ_SCALE)) { 7878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * tp->snd_scale = tp->requested_s_scale; 7888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * tp->rcv_scale = tp->request_r_scale; 7898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * } 7908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project */ 7918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project (void) tcp_reass(tp, (struct tcpiphdr *)0, 7925d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner (struct mbuf *)0); 7938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* 7948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * if we didn't have to retransmit the SYN, 7958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * use its rtt as our initial srtt & rtt var. 7968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project */ 7978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (tp->t_rtt) 7988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tcp_xmit_timer(tp, tp->t_rtt); 7998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } else 8008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tp->t_state = TCPS_SYN_RECEIVED; 8018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 8028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projecttrimthenstep6: 8038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* 8048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * Advance ti->ti_seq to correspond to first data byte. 8058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * If data, trim to stay within window, 8068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * dropping FIN if necessary. 8078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project */ 8088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ti->ti_seq++; 8098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (ti->ti_len > tp->rcv_wnd) { 8108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project todrop = ti->ti_len - tp->rcv_wnd; 8115d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner m_adj(m, -todrop); 8128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ti->ti_len = tp->rcv_wnd; 8138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tiflags &= ~TH_FIN; 8145d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner STAT(tcpstat.tcps_rcvpackafterwin++); 8155d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner STAT(tcpstat.tcps_rcvbyteafterwin += todrop); 8168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 8178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tp->snd_wl1 = ti->ti_seq - 1; 8188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tp->rcv_up = ti->ti_seq; 8198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project goto step6; 8208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } /* switch tp->t_state */ 8218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* 8228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * States other than LISTEN or SYN_SENT. 8238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * First check timestamp, if present. 8248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * Then check that at least some bytes of segment are within 8258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * receive window. If segment begins before rcv_nxt, 8268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * drop leading data (and SYN); if nothing left, just ack. 8278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * 8288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * RFC 1323 PAWS: If we have a timestamp reply on this segment 8298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * and it's less than ts_recent, drop it. 8308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project */ 8318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* if (ts_present && (tiflags & TH_RST) == 0 && tp->ts_recent && 8328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * TSTMP_LT(ts_val, tp->ts_recent)) { 8338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * 8348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project */ /* Check to see if ts_recent is over 24 days old. */ 8358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* if ((int)(tcp_now - tp->ts_recent_age) > TCP_PAWS_IDLE) { 8368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project */ /* 8378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * * Invalidate ts_recent. If this segment updates 8388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * * ts_recent, the age will be reset later and ts_recent 8398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * * will get a valid value. If it does not, setting 8408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * * ts_recent to zero will at least satisfy the 8418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * * requirement that zero be placed in the timestamp 8428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * * echo reply when ts_recent isn't valid. The 8438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * * age isn't reset until we get a valid ts_recent 8448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * * because we don't want out-of-order segments to be 8458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * * dropped when ts_recent is old. 8468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * */ 8478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* tp->ts_recent = 0; 8488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * } else { 8498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * tcpstat.tcps_rcvduppack++; 8508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * tcpstat.tcps_rcvdupbyte += ti->ti_len; 8518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * tcpstat.tcps_pawsdrop++; 8528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * goto dropafterack; 8538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * } 8548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * } 8558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project */ 8568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 8578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project todrop = tp->rcv_nxt - ti->ti_seq; 8588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (todrop > 0) { 8598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (tiflags & TH_SYN) { 8608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tiflags &= ~TH_SYN; 8618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ti->ti_seq++; 8628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (ti->ti_urp > 1) 8638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ti->ti_urp--; 8648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project else 8658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tiflags &= ~TH_URG; 8668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project todrop--; 8678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 8688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* 8698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * Following if statement from Stevens, vol. 2, p. 960. 8708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project */ 8718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (todrop > ti->ti_len 8728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project || (todrop == ti->ti_len && (tiflags & TH_FIN) == 0)) { 8738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* 8748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * Any valid FIN must be to the left of the window. 8758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * At this point the FIN must be a duplicate or out 8768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * of sequence; drop it. 8778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project */ 8788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tiflags &= ~TH_FIN; 8798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 8808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* 8818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * Send an ACK to resynchronize and drop any data. 8828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * But keep on processing for RST or ACK. 8838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project */ 8848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tp->t_flags |= TF_ACKNOW; 8858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project todrop = ti->ti_len; 8865d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner STAT(tcpstat.tcps_rcvduppack++); 8875d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner STAT(tcpstat.tcps_rcvdupbyte += todrop); 8888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } else { 8895d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner STAT(tcpstat.tcps_rcvpartduppack++); 8905d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner STAT(tcpstat.tcps_rcvpartdupbyte += todrop); 8918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 8925d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner m_adj(m, todrop); 8938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ti->ti_seq += todrop; 8948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ti->ti_len -= todrop; 8958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (ti->ti_urp > todrop) 8968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ti->ti_urp -= todrop; 8978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project else { 8988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tiflags &= ~TH_URG; 8998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ti->ti_urp = 0; 9008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 9018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 9028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* 9038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * If new data are received on a connection after the 9048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * user processes are gone, then RST the other end. 9058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project */ 9068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if ((so->so_state & SS_NOFDREF) && 9078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tp->t_state > TCPS_CLOSE_WAIT && ti->ti_len) { 9088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tp = tcp_close(tp); 9095d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner STAT(tcpstat.tcps_rcvafterclose++); 9108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project goto dropwithreset; 9118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 9128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 9138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* 9148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * If segment ends after window, drop trailing data 9158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * (and PUSH and FIN); if nothing left, just ACK. 9168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project */ 9178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project todrop = (ti->ti_seq+ti->ti_len) - (tp->rcv_nxt+tp->rcv_wnd); 9188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (todrop > 0) { 9195d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner STAT(tcpstat.tcps_rcvpackafterwin++); 9208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (todrop >= ti->ti_len) { 9215d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner STAT(tcpstat.tcps_rcvbyteafterwin += ti->ti_len); 9228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* 9238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * If a new connection request is received 9248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * while in TIME_WAIT, drop the old connection 9258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * and start over if the sequence numbers 9268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * are above the previous ones. 9278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project */ 9288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (tiflags & TH_SYN && 9298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tp->t_state == TCPS_TIME_WAIT && 9308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project SEQ_GT(ti->ti_seq, tp->rcv_nxt)) { 9318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project iss = tp->rcv_nxt + TCP_ISSINCR; 9328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tp = tcp_close(tp); 9338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project goto findso; 9348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 9358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* 9368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * If window is closed can only take segments at 9378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * window edge, and have to drop data and PUSH from 9388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * incoming segments. Continue processing, but 9398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * remember to ack. Otherwise, drop segment 9408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * and ack. 9418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project */ 9428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (tp->rcv_wnd == 0 && ti->ti_seq == tp->rcv_nxt) { 9438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tp->t_flags |= TF_ACKNOW; 9445d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner STAT(tcpstat.tcps_rcvwinprobe++); 9458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } else 9468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project goto dropafterack; 9478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } else 9485d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner STAT(tcpstat.tcps_rcvbyteafterwin += todrop); 9495d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner m_adj(m, -todrop); 9508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ti->ti_len -= todrop; 9518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tiflags &= ~(TH_PUSH|TH_FIN); 9528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 9538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 9548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* 9558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * If last ACK falls within this segment's sequence numbers, 9568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * record its timestamp. 9578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project */ 9588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* if (ts_present && SEQ_LEQ(ti->ti_seq, tp->last_ack_sent) && 9598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * SEQ_LT(tp->last_ack_sent, ti->ti_seq + ti->ti_len + 9608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * ((tiflags & (TH_SYN|TH_FIN)) != 0))) { 9618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * tp->ts_recent_age = tcp_now; 9628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * tp->ts_recent = ts_val; 9638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * } 9648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project */ 9658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 9668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* 9678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * If the RST bit is set examine the state: 9688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * SYN_RECEIVED STATE: 9698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * If passive open, return to LISTEN state. 9708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * If active open, inform user that connection was refused. 9718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * ESTABLISHED, FIN_WAIT_1, FIN_WAIT2, CLOSE_WAIT STATES: 9728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * Inform user that connection was reset, and close tcb. 9738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * CLOSING, LAST_ACK, TIME_WAIT STATES 9748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * Close the tcb. 9758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project */ 9768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (tiflags&TH_RST) switch (tp->t_state) { 9778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 9788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case TCPS_SYN_RECEIVED: 9798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* so->so_error = ECONNREFUSED; */ 9808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project goto close; 9818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 9828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case TCPS_ESTABLISHED: 9838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case TCPS_FIN_WAIT_1: 9848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case TCPS_FIN_WAIT_2: 9858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case TCPS_CLOSE_WAIT: 9868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* so->so_error = ECONNRESET; */ 9878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project close: 9888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tp->t_state = TCPS_CLOSED; 9895d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner STAT(tcpstat.tcps_drops++); 9908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tp = tcp_close(tp); 9918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project goto drop; 9928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 9938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case TCPS_CLOSING: 9948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case TCPS_LAST_ACK: 9958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case TCPS_TIME_WAIT: 9968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tp = tcp_close(tp); 9978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project goto drop; 9988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 9998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 10008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* 10018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * If a SYN is in the window, then this is an 10028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * error and we send an RST and drop the connection. 10038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project */ 10048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (tiflags & TH_SYN) { 10058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tp = tcp_drop(tp,0); 10068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project goto dropwithreset; 10078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 10088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 10098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* 10108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * If the ACK bit is off we drop the segment and return. 10118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project */ 10128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if ((tiflags & TH_ACK) == 0) goto drop; 10138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 10148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* 10158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * Ack processing. 10168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project */ 10178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project switch (tp->t_state) { 10188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* 10198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * In SYN_RECEIVED state if the ack ACKs our SYN then enter 10208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * ESTABLISHED state and continue processing, otherwise 10218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * send an RST. una<=ack<=max 10228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project */ 10238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case TCPS_SYN_RECEIVED: 10248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 10258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (SEQ_GT(tp->snd_una, ti->ti_ack) || 10268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project SEQ_GT(ti->ti_ack, tp->snd_max)) 10278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project goto dropwithreset; 10285d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner STAT(tcpstat.tcps_connects++); 10298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tp->t_state = TCPS_ESTABLISHED; 10308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* 10318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * The sent SYN is ack'ed with our sequence number +1 10328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * The first data byte already in the buffer will get 10338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * lost if no correction is made. This is only needed for 10348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * SS_CTL since the buffer is empty otherwise. 10358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * tp->snd_una++; or: 10368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project */ 10378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tp->snd_una=ti->ti_ack; 10388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (so->so_state & SS_CTL) { 10398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* So tcp_ctl reports the right state */ 10408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ret = tcp_ctl(so); 10418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (ret == 1) { 10428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project soisfconnected(so); 10438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project so->so_state &= ~SS_CTL; /* success XXX */ 10448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } else if (ret == 2) { 10458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project so->so_state = SS_NOFDREF; /* CTL_CMD */ 10468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } else { 10478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project needoutput = 1; 10488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tp->t_state = TCPS_FIN_WAIT_1; 10498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 10508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } else { 10518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project soisfconnected(so); 10528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 10538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 10548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* Do window scaling? */ 10558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* if ((tp->t_flags & (TF_RCVD_SCALE|TF_REQ_SCALE)) == 10568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * (TF_RCVD_SCALE|TF_REQ_SCALE)) { 10578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * tp->snd_scale = tp->requested_s_scale; 10588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * tp->rcv_scale = tp->request_r_scale; 10598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * } 10608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project */ 10615d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner (void) tcp_reass(tp, (struct tcpiphdr *)0, (struct mbuf *)0); 10628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tp->snd_wl1 = ti->ti_seq - 1; 10638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* Avoid ack processing; snd_una==ti_ack => dup ack */ 10648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project goto synrx_to_est; 10658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* fall into ... */ 10668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 10678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* 10688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * In ESTABLISHED state: drop duplicate ACKs; ACK out of range 10698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * ACKs. If the ack is in the range 10708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * tp->snd_una < ti->ti_ack <= tp->snd_max 10718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * then advance tp->snd_una to ti->ti_ack and drop 10728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * data from the retransmission queue. If this ACK reflects 10738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * more up to date window information we update our window information. 10748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project */ 10758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case TCPS_ESTABLISHED: 10768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case TCPS_FIN_WAIT_1: 10778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case TCPS_FIN_WAIT_2: 10788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case TCPS_CLOSE_WAIT: 10798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case TCPS_CLOSING: 10808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case TCPS_LAST_ACK: 10818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case TCPS_TIME_WAIT: 10828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 10838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (SEQ_LEQ(ti->ti_ack, tp->snd_una)) { 10848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (ti->ti_len == 0 && tiwin == tp->snd_wnd) { 10855d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner STAT(tcpstat.tcps_rcvdupack++); 10868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project DEBUG_MISC((dfd," dup ack m = %lx so = %lx \n", 10878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project (long )m, (long )so)); 10888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* 10898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * If we have outstanding data (other than 10908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * a window probe), this is a completely 10918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * duplicate ack (ie, window info didn't 10928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * change), the ack is the biggest we've 10938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * seen and we've seen exactly our rexmt 10948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * threshold of them, assume a packet 10958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * has been dropped and retransmit it. 10968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * Kludge snd_nxt & the congestion 10978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * window so we send only this one 10988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * packet. 10998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * 11008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * We know we're losing at the current 11018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * window size so do congestion avoidance 11028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * (set ssthresh to half the current window 11038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * and pull our congestion window back to 11048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * the new ssthresh). 11058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * 11068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * Dup acks mean that packets have left the 11078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * network (they're now cached at the receiver) 11088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * so bump cwnd by the amount in the receiver 11098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * to keep a constant cwnd packets in the 11108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * network. 11118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project */ 11128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (tp->t_timer[TCPT_REXMT] == 0 || 11138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ti->ti_ack != tp->snd_una) 11148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tp->t_dupacks = 0; 11155d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner else if (++tp->t_dupacks == TCPREXMTTHRESH) { 11168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tcp_seq onxt = tp->snd_nxt; 11178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project u_int win = 11188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project min(tp->snd_wnd, tp->snd_cwnd) / 2 / 11198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tp->t_maxseg; 11208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 11218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (win < 2) 11228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project win = 2; 11238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tp->snd_ssthresh = win * tp->t_maxseg; 11248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tp->t_timer[TCPT_REXMT] = 0; 11258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tp->t_rtt = 0; 11268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tp->snd_nxt = ti->ti_ack; 11278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tp->snd_cwnd = tp->t_maxseg; 11288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project (void) tcp_output(tp); 11298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tp->snd_cwnd = tp->snd_ssthresh + 11308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tp->t_maxseg * tp->t_dupacks; 11318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (SEQ_GT(onxt, tp->snd_nxt)) 11328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tp->snd_nxt = onxt; 11338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project goto drop; 11345d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner } else if (tp->t_dupacks > TCPREXMTTHRESH) { 11358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tp->snd_cwnd += tp->t_maxseg; 11368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project (void) tcp_output(tp); 11378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project goto drop; 11388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 11398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } else 11408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tp->t_dupacks = 0; 11418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project break; 11428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 11438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project synrx_to_est: 11448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* 11458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * If the congestion window was inflated to account 11468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * for the other side's cached packets, retract it. 11478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project */ 11485d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner if (tp->t_dupacks > TCPREXMTTHRESH && 11498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tp->snd_cwnd > tp->snd_ssthresh) 11508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tp->snd_cwnd = tp->snd_ssthresh; 11518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tp->t_dupacks = 0; 11528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (SEQ_GT(ti->ti_ack, tp->snd_max)) { 11535d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner STAT(tcpstat.tcps_rcvacktoomuch++); 11548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project goto dropafterack; 11558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 11568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project acked = ti->ti_ack - tp->snd_una; 11575d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner STAT(tcpstat.tcps_rcvackpack++); 11585d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner STAT(tcpstat.tcps_rcvackbyte += acked); 11598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 11608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* 11618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * If we have a timestamp reply, update smoothed 11628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * round trip time. If no timestamp is present but 11638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * transmit timer is running and timed sequence 11648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * number was acked, update smoothed round trip time. 11658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * Since we now have an rtt measurement, cancel the 11668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * timer backoff (cf., Phil Karn's retransmit alg.). 11678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * Recompute the initial retransmit timer. 11688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project */ 11698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* if (ts_present) 11708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * tcp_xmit_timer(tp, tcp_now-ts_ecr+1); 11718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * else 11728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project */ 11738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (tp->t_rtt && SEQ_GT(ti->ti_ack, tp->t_rtseq)) 11748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tcp_xmit_timer(tp,tp->t_rtt); 11758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 11768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* 11778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * If all outstanding data is acked, stop retransmit 11788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * timer and remember to restart (more output or persist). 11798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * If there is more data to be acked, restart retransmit 11808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * timer, using current (possibly backed-off) value. 11818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project */ 11828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (ti->ti_ack == tp->snd_max) { 11838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tp->t_timer[TCPT_REXMT] = 0; 11848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project needoutput = 1; 11858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } else if (tp->t_timer[TCPT_PERSIST] == 0) 11868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tp->t_timer[TCPT_REXMT] = tp->t_rxtcur; 11878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* 11888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * When new data is acked, open the congestion window. 11898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * If the window gives us less than ssthresh packets 11908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * in flight, open exponentially (maxseg per packet). 11918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * Otherwise open linearly: maxseg per window 11928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * (maxseg^2 / cwnd per packet). 11938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project */ 11948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project { 11958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project register u_int cw = tp->snd_cwnd; 11968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project register u_int incr = tp->t_maxseg; 11978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 11988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (cw > tp->snd_ssthresh) 11998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project incr = incr * incr / cw; 12008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tp->snd_cwnd = min(cw + incr, TCP_MAXWIN<<tp->snd_scale); 12018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 12028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (acked > so->so_snd.sb_cc) { 12038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tp->snd_wnd -= so->so_snd.sb_cc; 12045d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner sbdrop(&so->so_snd, (int )so->so_snd.sb_cc); 12058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ourfinisacked = 1; 12068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } else { 12075d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner sbdrop(&so->so_snd, acked); 12088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tp->snd_wnd -= acked; 12098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ourfinisacked = 0; 12108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 12118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* 12128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * XXX sowwakup is called when data is acked and there's room for 12138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * for more data... it should read() the socket 12148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project */ 12158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* if (so->so_snd.sb_flags & SB_NOTIFY) 12168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * sowwakeup(so); 12178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project */ 12188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tp->snd_una = ti->ti_ack; 12198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (SEQ_LT(tp->snd_nxt, tp->snd_una)) 12208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tp->snd_nxt = tp->snd_una; 12218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 12228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project switch (tp->t_state) { 12238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 12248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* 12258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * In FIN_WAIT_1 STATE in addition to the processing 12268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * for the ESTABLISHED state if our FIN is now acknowledged 12278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * then enter FIN_WAIT_2. 12288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project */ 12298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case TCPS_FIN_WAIT_1: 12308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (ourfinisacked) { 12318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* 12328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * If we can't receive any more 12338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * data, then closing user can proceed. 12348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * Starting the timer is contrary to the 12358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * specification, but if we don't get a FIN 12368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * we'll hang forever. 12378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project */ 12388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (so->so_state & SS_FCANTRCVMORE) { 12398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project soisfdisconnected(so); 12405d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner tp->t_timer[TCPT_2MSL] = TCP_MAXIDLE; 12418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 12428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tp->t_state = TCPS_FIN_WAIT_2; 12438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 12448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project break; 12458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 12468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* 12478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * In CLOSING STATE in addition to the processing for 12488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * the ESTABLISHED state if the ACK acknowledges our FIN 12498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * then enter the TIME-WAIT state, otherwise ignore 12508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * the segment. 12518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project */ 12528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case TCPS_CLOSING: 12538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (ourfinisacked) { 12548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tp->t_state = TCPS_TIME_WAIT; 12558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tcp_canceltimers(tp); 12568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tp->t_timer[TCPT_2MSL] = 2 * TCPTV_MSL; 12578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project soisfdisconnected(so); 12588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 12598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project break; 12608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 12618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* 12628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * In LAST_ACK, we may still be waiting for data to drain 12638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * and/or to be acked, as well as for the ack of our FIN. 12648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * If our FIN is now acknowledged, delete the TCB, 12658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * enter the closed state and return. 12668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project */ 12678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case TCPS_LAST_ACK: 12688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (ourfinisacked) { 12698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tp = tcp_close(tp); 12708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project goto drop; 12718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 12728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project break; 12738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 12748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* 12758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * In TIME_WAIT state the only thing that should arrive 12768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * is a retransmission of the remote FIN. Acknowledge 12778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * it and restart the finack timer. 12788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project */ 12798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case TCPS_TIME_WAIT: 12808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tp->t_timer[TCPT_2MSL] = 2 * TCPTV_MSL; 12818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project goto dropafterack; 12828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 12838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } /* switch(tp->t_state) */ 12848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 12858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstep6: 12868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* 12878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * Update window information. 12888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * Don't look at window if no ACK: TAC's send garbage on first SYN. 12898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project */ 12908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if ((tiflags & TH_ACK) && 12918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project (SEQ_LT(tp->snd_wl1, ti->ti_seq) || 12928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project (tp->snd_wl1 == ti->ti_seq && (SEQ_LT(tp->snd_wl2, ti->ti_ack) || 12938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project (tp->snd_wl2 == ti->ti_ack && tiwin > tp->snd_wnd))))) { 12948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* keep track of pure window updates */ 12958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (ti->ti_len == 0 && 12968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tp->snd_wl2 == ti->ti_ack && tiwin > tp->snd_wnd) 12975d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner STAT(tcpstat.tcps_rcvwinupd++); 12988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tp->snd_wnd = tiwin; 12998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tp->snd_wl1 = ti->ti_seq; 13008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tp->snd_wl2 = ti->ti_ack; 13018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (tp->snd_wnd > tp->max_sndwnd) 13028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tp->max_sndwnd = tp->snd_wnd; 13038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project needoutput = 1; 13048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 13058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 13068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* 13078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * Process segments with URG. 13088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project */ 13098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if ((tiflags & TH_URG) && ti->ti_urp && 13108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project TCPS_HAVERCVDFIN(tp->t_state) == 0) { 13118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* 13128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * This is a kludge, but if we receive and accept 13138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * random urgent pointers, we'll crash in 13148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * soreceive. It's hard to imagine someone 13158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * actually wanting to send this much urgent data. 13168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project */ 13178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (ti->ti_urp + so->so_rcv.sb_cc > so->so_rcv.sb_datalen) { 13188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ti->ti_urp = 0; 13198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tiflags &= ~TH_URG; 13208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project goto dodata; 13218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 13228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* 13238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * If this segment advances the known urgent pointer, 13248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * then mark the data stream. This should not happen 13258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * in CLOSE_WAIT, CLOSING, LAST_ACK or TIME_WAIT STATES since 13268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * a FIN has been received from the remote side. 13278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * In these states we ignore the URG. 13288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * 13298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * According to RFC961 (Assigned Protocols), 13308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * the urgent pointer points to the last octet 13318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * of urgent data. We continue, however, 13328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * to consider it to indicate the first octet 13338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * of data past the urgent section as the original 13348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * spec states (in one of two places). 13358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project */ 13368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (SEQ_GT(ti->ti_seq+ti->ti_urp, tp->rcv_up)) { 13378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tp->rcv_up = ti->ti_seq + ti->ti_urp; 13388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project so->so_urgc = so->so_rcv.sb_cc + 13398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project (tp->rcv_up - tp->rcv_nxt); /* -1; */ 13408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tp->rcv_up = ti->ti_seq + ti->ti_urp; 13418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 13428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 13438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } else 13448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* 13458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * If no out of band data is expected, 13468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * pull receive urgent pointer along 13478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * with the receive window. 13488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project */ 13498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (SEQ_GT(tp->rcv_nxt, tp->rcv_up)) 13508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tp->rcv_up = tp->rcv_nxt; 13518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectdodata: 13528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 13538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* 13548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * Process the segment text, merging it into the TCP sequencing queue, 13558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * and arranging for acknowledgment of receipt if necessary. 13568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * This process logically involves adjusting tp->rcv_wnd as data 13578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * is presented to the user (this happens in tcp_usrreq.c, 13588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * case PRU_RCVD). If a FIN has already been received on this 13598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * connection then we just ignore the text. 13608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project */ 13618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if ((ti->ti_len || (tiflags&TH_FIN)) && 13628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project TCPS_HAVERCVDFIN(tp->t_state) == 0) { 13638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project TCP_REASS(tp, ti, m, so, tiflags); 13648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* 13658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * Note the amount of data that peer has sent into 13668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * our window, in order to estimate the sender's 13678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * buffer size. 13688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project */ 13698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project len = so->so_rcv.sb_datalen - (tp->rcv_adv - tp->rcv_nxt); 13708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } else { 13715d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner m_free(m); 13728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tiflags &= ~TH_FIN; 13738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 13748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 13758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* 13768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * If FIN is received ACK the FIN and let the user know 13778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * that the connection is closing. 13788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project */ 13798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (tiflags & TH_FIN) { 13808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (TCPS_HAVERCVDFIN(tp->t_state) == 0) { 13818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* 13828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * If we receive a FIN we can't send more data, 13838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * set it SS_FDRAIN 13848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * Shutdown the socket if there is no rx data in the 13858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * buffer. 13868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * soread() is called on completion of shutdown() and 13878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * will got to TCPS_LAST_ACK, and use tcp_output() 13888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * to send the FIN. 13898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project */ 13908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* sofcantrcvmore(so); */ 13918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project sofwdrain(so); 13928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 13938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tp->t_flags |= TF_ACKNOW; 13948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tp->rcv_nxt++; 13958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 13968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project switch (tp->t_state) { 13978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 13988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* 13998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * In SYN_RECEIVED and ESTABLISHED STATES 14008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * enter the CLOSE_WAIT state. 14018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project */ 14028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case TCPS_SYN_RECEIVED: 14038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case TCPS_ESTABLISHED: 14048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if(so->so_emu == EMU_CTL) /* no shutdown on socket */ 14058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tp->t_state = TCPS_LAST_ACK; 14068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project else 14078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tp->t_state = TCPS_CLOSE_WAIT; 14088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project break; 14098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 14108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* 14118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * If still in FIN_WAIT_1 STATE FIN has not been acked so 14128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * enter the CLOSING state. 14138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project */ 14148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case TCPS_FIN_WAIT_1: 14158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tp->t_state = TCPS_CLOSING; 14168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project break; 14178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 14188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* 14198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * In FIN_WAIT_2 state enter the TIME_WAIT state, 14208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * starting the time-wait timer, turning off the other 14218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * standard timers. 14228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project */ 14238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case TCPS_FIN_WAIT_2: 14248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tp->t_state = TCPS_TIME_WAIT; 14258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tcp_canceltimers(tp); 14268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tp->t_timer[TCPT_2MSL] = 2 * TCPTV_MSL; 14278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project soisfdisconnected(so); 14288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project break; 14298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 14308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* 14318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * In TIME_WAIT state restart the 2 MSL time_wait timer. 14328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project */ 14338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case TCPS_TIME_WAIT: 14348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tp->t_timer[TCPT_2MSL] = 2 * TCPTV_MSL; 14358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project break; 14368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 14378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 14388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 14398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* 14408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * If this is a small packet, then ACK now - with Nagel 14418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * congestion avoidance sender won't send more until 14428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * he gets an ACK. 14438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * 14448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * See above. 14458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project */ 14468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* if (ti->ti_len && (unsigned)ti->ti_len < tp->t_maxseg) { 14478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project */ 14488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* if ((ti->ti_len && (unsigned)ti->ti_len < tp->t_maxseg && 14498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * (so->so_iptos & IPTOS_LOWDELAY) == 0) || 14508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * ((so->so_iptos & IPTOS_LOWDELAY) && 14518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * ((struct tcpiphdr_2 *)ti)->first_char == (char)27)) { 14528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project */ 14538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (ti->ti_len && (unsigned)ti->ti_len <= 5 && 14548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ((struct tcpiphdr_2 *)ti)->first_char == (char)27) { 14558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tp->t_flags |= TF_ACKNOW; 14568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 14578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 14588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* 14598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * Return any desired output. 14608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project */ 14618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (needoutput || (tp->t_flags & TF_ACKNOW)) { 14628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project (void) tcp_output(tp); 14638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 14648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return; 14658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 14668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectdropafterack: 14678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* 14688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * Generate an ACK dropping incoming segment if it occupies 14698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * sequence space, where the ACK reflects our state. 14708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project */ 14718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (tiflags & TH_RST) 14728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project goto drop; 14735d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner m_freem(m); 14748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tp->t_flags |= TF_ACKNOW; 14758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project (void) tcp_output(tp); 14768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return; 14778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 14788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectdropwithreset: 14795d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner /* reuses m if m!=NULL, m_free() unnecessary */ 14808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (tiflags & TH_ACK) 14818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tcp_respond(tp, ti, m, (tcp_seq)0, ti->ti_ack, TH_RST); 14828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project else { 14838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (tiflags & TH_SYN) ti->ti_len++; 14848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tcp_respond(tp, ti, m, ti->ti_seq+ti->ti_len, (tcp_seq)0, 14858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project TH_RST|TH_ACK); 14868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 14878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 14888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return; 14898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 14908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectdrop: 14918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* 14928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * Drop space held by incoming segment and return. 14938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project */ 14945d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner m_free(m); 14958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 14968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return; 14978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 14988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 14998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* , ts_present, ts_val, ts_ecr) */ 15008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* int *ts_present; 15018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * u_int32_t *ts_val, *ts_ecr; 15028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project */ 15035d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic void 15045d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnertcp_dooptions(struct tcpcb *tp, u_char *cp, int cnt, struct tcpiphdr *ti) 15058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 15068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project u_int16_t mss; 15078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int opt, optlen; 15088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 15098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project DEBUG_CALL("tcp_dooptions"); 15108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project DEBUG_ARGS((dfd," tp = %lx cnt=%i \n", (long )tp, cnt)); 15118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 15128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project for (; cnt > 0; cnt -= optlen, cp += optlen) { 15138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project opt = cp[0]; 15148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (opt == TCPOPT_EOL) 15158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project break; 15168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (opt == TCPOPT_NOP) 15178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project optlen = 1; 15188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project else { 15198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project optlen = cp[1]; 15208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (optlen <= 0) 15218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project break; 15228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 15238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project switch (opt) { 15248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 15258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project default: 15268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project continue; 15278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 15288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case TCPOPT_MAXSEG: 15298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (optlen != TCPOLEN_MAXSEG) 15308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project continue; 15318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (!(ti->ti_flags & TH_SYN)) 15328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project continue; 15338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project memcpy((char *) &mss, (char *) cp + 2, sizeof(mss)); 15348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project NTOHS(mss); 15358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project (void) tcp_mss(tp, mss); /* sets t_maxseg */ 15368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project break; 15378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 15388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* case TCPOPT_WINDOW: 15398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * if (optlen != TCPOLEN_WINDOW) 15408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * continue; 15418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * if (!(ti->ti_flags & TH_SYN)) 15428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * continue; 15438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * tp->t_flags |= TF_RCVD_SCALE; 15448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * tp->requested_s_scale = min(cp[2], TCP_MAX_WINSHIFT); 15458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * break; 15468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project */ 15478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* case TCPOPT_TIMESTAMP: 15488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * if (optlen != TCPOLEN_TIMESTAMP) 15498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * continue; 15508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * *ts_present = 1; 15518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * memcpy((char *) ts_val, (char *)cp + 2, sizeof(*ts_val)); 15528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * NTOHL(*ts_val); 15538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * memcpy((char *) ts_ecr, (char *)cp + 6, sizeof(*ts_ecr)); 15548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * NTOHL(*ts_ecr); 15558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * 15568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project */ /* 15578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * * A timestamp received in a SYN makes 15588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * * it ok to send timestamp requests and replies. 15598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * */ 15608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* if (ti->ti_flags & TH_SYN) { 15618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * tp->t_flags |= TF_RCVD_TSTMP; 15628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * tp->ts_recent = *ts_val; 15638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * tp->ts_recent_age = tcp_now; 15648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * } 15658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project */ break; 15668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 15678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 15688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 15698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 15708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 15718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* 15728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * Pull out of band byte out of a segment so 15738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * it doesn't appear in the user's data queue. 15748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * It is still reflected in the segment length for 15758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * sequencing purposes. 15768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project */ 15778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 15788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef notdef 15798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 15808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid 15818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projecttcp_pulloutofband(so, ti, m) 15828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project struct socket *so; 15838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project struct tcpiphdr *ti; 15845d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner register struct mbuf *m; 15858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 15868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int cnt = ti->ti_urp - 1; 15878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 15888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project while (cnt >= 0) { 15898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (m->m_len > cnt) { 15905d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner char *cp = mtod(m, caddr_t) + cnt; 15918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project struct tcpcb *tp = sototcpcb(so); 15928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 15938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tp->t_iobc = *cp; 15948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tp->t_oobflags |= TCPOOB_HAVEDATA; 15958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project memcpy(sp, cp+1, (unsigned)(m->m_len - cnt - 1)); 15968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project m->m_len--; 15978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return; 15988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 15998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project cnt -= m->m_len; 16008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project m = m->m_next; /* XXX WRONG! Fix it! */ 16018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (m == 0) 16028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project break; 16038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 16048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project panic("tcp_pulloutofband"); 16058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 16068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 16078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif /* notdef */ 16088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 16098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* 16108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * Collect new round-trip time estimate 16118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * and update averages and current timeout. 16128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project */ 16138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 16145d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic void 16155d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnertcp_xmit_timer(register struct tcpcb *tp, int rtt) 16168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 16178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project register short delta; 16188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 16198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project DEBUG_CALL("tcp_xmit_timer"); 16208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project DEBUG_ARG("tp = %lx", (long)tp); 16218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project DEBUG_ARG("rtt = %d", rtt); 16228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 16235d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner STAT(tcpstat.tcps_rttupdated++); 16248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (tp->t_srtt != 0) { 16258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* 16268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * srtt is stored as fixed point with 3 bits after the 16278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * binary point (i.e., scaled by 8). The following magic 16288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * is equivalent to the smoothing algorithm in rfc793 with 16298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * an alpha of .875 (srtt = rtt/8 + srtt*7/8 in fixed 16308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * point). Adjust rtt to origin 0. 16318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project */ 16328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project delta = rtt - 1 - (tp->t_srtt >> TCP_RTT_SHIFT); 16338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if ((tp->t_srtt += delta) <= 0) 16348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tp->t_srtt = 1; 16358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* 16368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * We accumulate a smoothed rtt variance (actually, a 16378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * smoothed mean difference), then set the retransmit 16388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * timer to smoothed rtt + 4 times the smoothed variance. 16398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * rttvar is stored as fixed point with 2 bits after the 16408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * binary point (scaled by 4). The following is 16418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * equivalent to rfc793 smoothing with an alpha of .75 16428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * (rttvar = rttvar*3/4 + |delta| / 4). This replaces 16438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * rfc793's wired-in beta. 16448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project */ 16458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (delta < 0) 16468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project delta = -delta; 16478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project delta -= (tp->t_rttvar >> TCP_RTTVAR_SHIFT); 16488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if ((tp->t_rttvar += delta) <= 0) 16498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tp->t_rttvar = 1; 16508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } else { 16518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* 16528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * No rtt measurement yet - use the unsmoothed rtt. 16538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * Set the variance to half the rtt (so our first 16548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * retransmit happens at 3*rtt). 16558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project */ 16568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tp->t_srtt = rtt << TCP_RTT_SHIFT; 16578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tp->t_rttvar = rtt << (TCP_RTTVAR_SHIFT - 1); 16588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 16598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tp->t_rtt = 0; 16608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tp->t_rxtshift = 0; 16618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 16628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* 16638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * the retransmit should happen at rtt + 4 * rttvar. 16648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * Because of the way we do the smoothing, srtt and rttvar 16658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * will each average +1/2 tick of bias. When we compute 16668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * the retransmit timer, we want 1/2 tick of rounding and 16678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * 1 extra tick because of +-1/2 tick uncertainty in the 16688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * firing of the timer. The bias will give us exactly the 16698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * 1.5 tick we need. But, because the bias is 16708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * statistical, we have to test that we don't drop below 16718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * the minimum feasible timer (which is 2 ticks). 16728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project */ 16738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project TCPT_RANGESET(tp->t_rxtcur, TCP_REXMTVAL(tp), 16748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project (short)tp->t_rttmin, TCPTV_REXMTMAX); /* XXX */ 16758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 16768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* 16778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * We received an ack for a packet that wasn't retransmitted; 16788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * it is probably safe to discard any error indications we've 16798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * received recently. This isn't quite right, but close enough 16808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * for now (a route might have failed after we sent a segment, 16818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * and the return path might not be symmetrical). 16828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project */ 16838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tp->t_softerror = 0; 16848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 16858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 16868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* 16878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * Determine a reasonable value for maxseg size. 16888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * If the route is known, check route for mtu. 16898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * If none, use an mss that can be handled on the outgoing 16908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * interface without forcing IP to fragment; if bigger than 16918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * an mbuf cluster (MCLBYTES), round down to nearest multiple of MCLBYTES 16928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * to utilize large mbufs. If no route is found, route has no mtu, 16938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * or the destination isn't local, use a default, hopefully conservative 16948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * size (usually 512 or the default IP max size, but no more than the mtu 16958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * of the interface), as we can't discover anything about intervening 16968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * gateways or networks. We also initialize the congestion/slow start 16978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * window to be a single segment if the destination isn't local. 16988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * While looking at the routing entry, we also initialize other path-dependent 16998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * parameters from pre-set or cached values in the routing entry. 17008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project */ 17018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 17028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint 17035d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnertcp_mss(struct tcpcb *tp, u_int offer) 17048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 17058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project struct socket *so = tp->t_socket; 17068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int mss; 17078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 17088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project DEBUG_CALL("tcp_mss"); 17098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project DEBUG_ARG("tp = %lx", (long)tp); 17108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project DEBUG_ARG("offer = %d", offer); 17118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 17125d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner mss = min(IF_MTU, IF_MRU) - sizeof(struct tcpiphdr); 17138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (offer) 17148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project mss = min(mss, offer); 17158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project mss = max(mss, 32); 17168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (mss < tp->t_maxseg || offer != 0) 17178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tp->t_maxseg = mss; 17188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 17198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tp->snd_cwnd = mss; 17208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 17215d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner sbreserve(&so->so_snd, TCP_SNDSPACE + ((TCP_SNDSPACE % mss) ? 17225d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner (mss - (TCP_SNDSPACE % mss)) : 17235d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 0)); 17245d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner sbreserve(&so->so_rcv, TCP_RCVSPACE + ((TCP_RCVSPACE % mss) ? 17255d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner (mss - (TCP_RCVSPACE % mss)) : 17265d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 0)); 17278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 17288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project DEBUG_MISC((dfd, " returning mss = %d\n", mss)); 17298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 17308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return mss; 17318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 1732