1 /* tcp_output.c 4.50 83/01/04 */ 2 3 #include "../h/param.h" 4 #include "../h/systm.h" 5 #include "../h/mbuf.h" 6 #include "../h/protosw.h" 7 #include "../h/socket.h" 8 #include "../h/socketvar.h" 9 #include "../netinet/in.h" 10 #include "../net/route.h" 11 #include "../netinet/in_pcb.h" 12 #include "../netinet/in_systm.h" 13 #include "../netinet/ip.h" 14 #include "../netinet/ip_var.h" 15 #include "../netinet/tcp.h" 16 #define TCPOUTFLAGS 17 #include "../netinet/tcp_fsm.h" 18 #include "../netinet/tcp_seq.h" 19 #include "../netinet/tcp_timer.h" 20 #include "../netinet/tcp_var.h" 21 #include "../netinet/tcpip.h" 22 #include "../netinet/tcp_debug.h" 23 #include <errno.h> 24 25 /* 26 * Initial options. 27 */ 28 u_char tcp_initopt[4] = { TCPOPT_MAXSEG, 4, 0x0, 0x0, }; 29 30 /* 31 * Tcp output routine: figure out what should be sent and send it. 32 */ 33 tcp_output(tp) 34 register struct tcpcb *tp; 35 { 36 register struct socket *so = tp->t_inpcb->inp_socket; 37 register int len; 38 struct mbuf *m0; 39 int off, flags, win, error; 40 register struct mbuf *m; 41 register struct tcpiphdr *ti; 42 u_char *opt; 43 unsigned optlen = 0; 44 int sendalot; 45 46 47 /* 48 * Determine length of data that should be transmitted, 49 * and flags that will be used. 50 * If there is some data or critical controls (SYN, RST) 51 * to send, then transmit; otherwise, investigate further. 52 */ 53 again: 54 sendalot = 0; 55 off = tp->snd_nxt - tp->snd_una; 56 len = MIN(so->so_snd.sb_cc, tp->snd_wnd+tp->t_force) - off; 57 if (len < 0) 58 return (0); /* ??? */ /* past FIN */ 59 if (len > tp->t_maxseg) { 60 len = tp->t_maxseg; 61 sendalot = 1; 62 } 63 64 flags = tcp_outflags[tp->t_state]; 65 if (tp->snd_nxt + len < tp->snd_una + so->so_snd.sb_cc) 66 flags &= ~TH_FIN; 67 if (flags & (TH_SYN|TH_RST|TH_FIN)) 68 goto send; 69 if (SEQ_GT(tp->snd_up, tp->snd_una)) 70 goto send; 71 72 /* 73 * Sender silly window avoidance. If can send all data, 74 * a maximum segment, at least 1/4 of window do it, 75 * or are forced, do it; otherwise don't bother. 76 */ 77 if (len) { 78 if (len == tp->t_maxseg || off+len >= so->so_snd.sb_cc) 79 goto send; 80 if (len * 4 >= tp->snd_wnd) /* a lot */ 81 goto send; 82 if (tp->t_force) 83 goto send; 84 } 85 86 /* 87 * Send if we owe peer an ACK. 88 */ 89 if (tp->t_flags&TF_ACKNOW) 90 goto send; 91 92 93 /* 94 * Calculate available window in i, and also amount 95 * of window known to peer (as advertised window less 96 * next expected input.) If this is 35% or more of the 97 * maximum possible window, then want to send a segment to peer. 98 */ 99 win = sbspace(&so->so_rcv); 100 if (win > 0 && 101 ((100*(win-(tp->rcv_adv-tp->rcv_nxt))/so->so_rcv.sb_hiwat) >= 35)) 102 goto send; 103 104 /* 105 * TCP window updates are not reliable, rather a polling protocol 106 * using ``persist'' packets is used to insure receipt of window 107 * updates. The three ``states'' for the output side are: 108 * idle not doing retransmits or persists 109 * persisting to move a zero window 110 * (re)transmitting and thereby not persisting 111 * 112 * tp->t_timer[TCPT_PERSIST] 113 * is set when we are in persist state. 114 * tp->t_force 115 * is set when we are called to send a persist packet. 116 * tp->t_timer[TCPT_REXMT] 117 * is set when we are retransmitting 118 * The output side is idle when both timers are zero. 119 * 120 * If send window is closed, there is data to transmit, and no 121 * retransmit or persist is pending, then go to persist state, 122 * arranging to force out a byte to get more current window information 123 * if nothing happens soon. 124 */ 125 if (tp->snd_wnd == 0 && so->so_snd.sb_cc && 126 tp->t_timer[TCPT_REXMT] == 0 && tp->t_timer[TCPT_PERSIST] == 0) { 127 tp->t_rxtshift = 0; 128 tcp_setpersist(tp); 129 } 130 131 /* 132 * No reason to send a segment, just return. 133 */ 134 return (0); 135 136 send: 137 /* 138 * Grab a header mbuf, attaching a copy of data to 139 * be transmitted, and initialize the header from 140 * the template for sends on this connection. 141 */ 142 MGET(m, M_DONTWAIT, MT_DATA); 143 if (m == INADDR_ANY) 144 return (ENOBUFS); 145 m->m_off = MMAXOFF - sizeof (struct tcpiphdr); 146 m->m_len = sizeof (struct tcpiphdr); 147 if (len) { 148 m->m_next = m_copy(so->so_snd.sb_mb, off, len); 149 if (m->m_next == 0) 150 len = 0; 151 } 152 ti = mtod(m, struct tcpiphdr *); 153 if (tp->t_template == 0) 154 panic("tcp_output"); 155 bcopy((caddr_t)tp->t_template, (caddr_t)ti, sizeof (struct tcpiphdr)); 156 157 /* 158 * Fill in fields, remembering maximum advertised 159 * window for use in delaying messages about window sizes. 160 */ 161 ti->ti_seq = tp->snd_nxt; 162 ti->ti_ack = tp->rcv_nxt; 163 ti->ti_seq = htonl(ti->ti_seq); 164 ti->ti_ack = htonl(ti->ti_ack); 165 /* 166 * Before ESTABLISHED, force sending of initial options 167 * unless TCP set to not do any options. 168 */ 169 if (tp->t_state < TCPS_ESTABLISHED) { 170 if (tp->t_flags&TF_NOOPT) 171 goto noopt; 172 opt = tcp_initopt; 173 optlen = sizeof (tcp_initopt); 174 *(u_short *)(opt + 2) = MIN(so->so_rcv.sb_hiwat / 2, 1024); 175 *(u_short *)(opt + 2) = htons(*(u_short *)(opt + 2)); 176 } else { 177 if (tp->t_tcpopt == 0) 178 goto noopt; 179 opt = mtod(tp->t_tcpopt, u_char *); 180 optlen = tp->t_tcpopt->m_len; 181 } 182 if (opt) { 183 m0 = m->m_next; 184 m->m_next = m_get(M_DONTWAIT, MT_DATA); 185 if (m->m_next == 0) { 186 (void) m_free(m); 187 m_freem(m0); 188 return (ENOBUFS); 189 } 190 m->m_next->m_next = m0; 191 m0 = m->m_next; 192 m0->m_len = optlen; 193 bcopy((caddr_t)opt, mtod(m0, caddr_t), optlen); 194 opt = (u_char *)(mtod(m0, caddr_t) + optlen); 195 while (m0->m_len & 0x3) { 196 *opt++ = TCPOPT_EOL; 197 m0->m_len++; 198 } 199 optlen = m0->m_len; 200 ti->ti_off = (sizeof (struct tcphdr) + optlen) >> 2; 201 } 202 noopt: 203 ti->ti_flags = flags; 204 win = sbspace(&so->so_rcv); 205 if (win < so->so_rcv.sb_hiwat / 4) /* avoid silly window */ 206 win = 0; 207 if (win > 0) 208 ti->ti_win = htons((u_short)win); 209 if (SEQ_GT(tp->snd_up, tp->snd_nxt)) { 210 ti->ti_urp = tp->snd_up - tp->snd_nxt; 211 ti->ti_urp = htons(ti->ti_urp); 212 ti->ti_flags |= TH_URG; 213 } else 214 /* 215 * If no urgent pointer to send, then we pull 216 * the urgent pointer to the left edge of the send window 217 * so that it doesn't drift into the send window on sequence 218 * number wraparound. 219 */ 220 tp->snd_up = tp->snd_una; /* drag it along */ 221 /* 222 * If anything to send and we can send it all, set PUSH. 223 * (This will keep happy those implementations which only 224 * give data to the user when a buffer fills or a PUSH comes in.) 225 */ 226 if (len && off+len == so->so_snd.sb_cc) 227 ti->ti_flags |= TH_PUSH; 228 229 /* 230 * Put TCP length in extended header, and then 231 * checksum extended header and data. 232 */ 233 if (len + optlen) { 234 ti->ti_len = sizeof (struct tcphdr) + optlen + len; 235 ti->ti_len = htons((u_short)ti->ti_len); 236 } 237 ti->ti_sum = in_cksum(m, sizeof (struct tcpiphdr) + (int)optlen + len); 238 239 /* 240 * In transmit state, time the transmission and arrange for 241 * the retransmit. In persist state, reset persist time for 242 * next persist. 243 */ 244 if (tp->t_force == 0) { 245 /* 246 * Advance snd_nxt over sequence space of this segment. 247 */ 248 if (flags & (TH_SYN|TH_FIN)) 249 tp->snd_nxt++; 250 tp->snd_nxt += len; 251 if (SEQ_GT(tp->snd_nxt, tp->snd_max)) 252 tp->snd_max = tp->snd_nxt; 253 254 /* 255 * Time this transmission if not a retransmission and 256 * not currently timing anything. 257 */ 258 if (SEQ_GT(tp->snd_nxt, tp->snd_max) && tp->t_rtt == 0) { 259 tp->t_rtt = 1; 260 tp->t_rtseq = tp->snd_nxt - len; 261 } 262 263 /* 264 * Set retransmit timer if not currently set. 265 * Initial value for retransmit timer to tcp_beta*tp->t_srtt. 266 * Initialize shift counter which is used for exponential 267 * backoff of retransmit time. 268 */ 269 if (tp->t_timer[TCPT_REXMT] == 0 && 270 tp->snd_nxt != tp->snd_una) { 271 TCPT_RANGESET(tp->t_timer[TCPT_REXMT], 272 tcp_beta * tp->t_srtt, TCPTV_MIN, TCPTV_MAX); 273 tp->t_rtt = 0; 274 tp->t_rxtshift = 0; 275 } 276 tp->t_timer[TCPT_PERSIST] = 0; 277 } else { 278 if (SEQ_GT(tp->snd_una+1, tp->snd_max)) 279 tp->snd_max = tp->snd_una+1; 280 } 281 282 /* 283 * Trace. 284 */ 285 if (so->so_options & SO_DEBUG) 286 tcp_trace(TA_OUTPUT, tp->t_state, tp, ti, 0); 287 288 /* 289 * Fill in IP length and desired time to live and 290 * send to IP level. 291 */ 292 ((struct ip *)ti)->ip_len = sizeof (struct tcpiphdr) + optlen + len; 293 ((struct ip *)ti)->ip_ttl = TCP_TTL; 294 if (error = ip_output(m, tp->t_ipopt, (so->so_options & SO_DONTROUTE) ? 295 &routetoif : &tp->t_inpcb->inp_route, 0)) 296 return (error); 297 298 /* 299 * Data sent (as far as we can tell). 300 * If this advertises a larger window than any other segment, 301 * then remember the size of the advertised window. 302 * Drop send for purpose of ACK requirements. 303 */ 304 if (win > 0 && SEQ_GT(tp->rcv_nxt+win, tp->rcv_adv)) 305 tp->rcv_adv = tp->rcv_nxt + win; 306 tp->t_flags &= ~(TF_ACKNOW|TF_DELACK); 307 if (sendalot && tp->t_force == 0) 308 goto again; 309 return (0); 310 } 311 312 tcp_setpersist(tp) 313 register struct tcpcb *tp; 314 { 315 316 if (tp->t_timer[TCPT_REXMT]) 317 panic("tcp_output REXMT"); 318 /* 319 * Start/restart persistance timer. 320 */ 321 TCPT_RANGESET(tp->t_timer[TCPT_PERSIST], 322 ((int)(tcp_beta * tp->t_srtt)) << tp->t_rxtshift, 323 TCPTV_PERSMIN, TCPTV_MAX); 324 tp->t_rxtshift++; 325 if (tp->t_rxtshift >= TCP_MAXRXTSHIFT) 326 tp->t_rxtshift = 0; 327 } 328