This source file includes following definitions.
- tcp_print_holes
- tcp_sack_output
- tcp_sack_adjust
- tcp_output
- tcp_setpersist
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71 #include <sys/param.h>
72 #include <sys/systm.h>
73 #include <sys/mbuf.h>
74 #include <sys/protosw.h>
75 #include <sys/socket.h>
76 #include <sys/socketvar.h>
77 #include <sys/kernel.h>
78
79 #include <net/route.h>
80 #include <net/if.h>
81
82 #include <netinet/in.h>
83 #include <netinet/in_systm.h>
84 #include <netinet/ip.h>
85 #include <netinet/in_pcb.h>
86 #include <netinet/ip_var.h>
87 #include <netinet/tcp.h>
88 #define TCPOUTFLAGS
89 #include <netinet/tcp_fsm.h>
90 #include <netinet/tcp_seq.h>
91 #include <netinet/tcp_timer.h>
92 #include <netinet/tcp_var.h>
93 #include <netinet/tcpip.h>
94 #include <netinet/tcp_debug.h>
95
96 #ifdef INET6
97 #include <netinet6/tcpipv6.h>
98 #include <netinet6/in6_var.h>
99 #endif
100
101 #ifdef notyet
102 extern struct mbuf *m_copypack();
103 #endif
104
105 #ifdef TCP_SACK
106 extern int tcprexmtthresh;
107 #endif
108
109 #ifdef TCP_SACK
110 #ifdef TCP_SACK_DEBUG
111 void tcp_print_holes(struct tcpcb *tp);
112
113 void
114 tcp_print_holes(struct tcpcb *tp)
115 {
116 struct sackhole *p = tp->snd_holes;
117 if (p == 0)
118 return;
119 printf("Hole report: start--end dups rxmit\n");
120 while (p) {
121 printf("%x--%x d %d r %x\n", p->start, p->end, p->dups,
122 p->rxmit);
123 p = p->next;
124 }
125 printf("\n");
126 }
127 #endif
128
129
130
131
132
133 struct sackhole *
134 tcp_sack_output(struct tcpcb *tp)
135 {
136 struct sackhole *p;
137
138 if (!tp->sack_enable)
139 return (NULL);
140 p = tp->snd_holes;
141 while (p) {
142 #ifndef TCP_FACK
143 if (p->dups >= tcprexmtthresh && SEQ_LT(p->rxmit, p->end)) {
144 #else
145
146
147
148
149 if ((p->dups >= tcprexmtthresh ||
150 tp->t_dupacks == tcprexmtthresh) &&
151 SEQ_LT(p->rxmit, p->end)) {
152 #endif
153 if (SEQ_LT(p->rxmit, tp->snd_una)) {
154 p = p->next;
155 continue;
156 }
157 #ifdef TCP_SACK_DEBUG
158 if (p)
159 tcp_print_holes(tp);
160 #endif
161 return (p);
162 }
163 p = p->next;
164 }
165 return (NULL);
166 }
167
168
169
170
171
172
173
174 void
175 tcp_sack_adjust(struct tcpcb *tp)
176 {
177 struct sackhole *cur = tp->snd_holes;
178 if (cur == NULL)
179 return;
180 if (SEQ_GEQ(tp->snd_nxt, tp->rcv_lastsack))
181 return;
182
183
184
185
186
187 while (cur->next) {
188 if (SEQ_LT(tp->snd_nxt, cur->end))
189 return;
190 if (SEQ_GEQ(tp->snd_nxt, cur->next->start))
191 cur = cur->next;
192 else {
193 tp->snd_nxt = cur->next->start;
194 return;
195 }
196 }
197 if (SEQ_LT(tp->snd_nxt, cur->end))
198 return;
199 tp->snd_nxt = tp->rcv_lastsack;
200 return;
201 }
202 #endif
203
204
205
206
207 int
208 tcp_output(tp)
209 struct tcpcb *tp;
210 {
211 struct socket *so = tp->t_inpcb->inp_socket;
212 long len, win, txmaxseg;
213 int off, flags, error;
214 struct mbuf *m;
215 struct tcphdr *th;
216 u_char opt[MAX_TCPOPTLEN];
217 unsigned int optlen, hdrlen, packetlen;
218 int idle, sendalot = 0;
219 #ifdef TCP_SACK
220 int i, sack_rxmit = 0;
221 struct sackhole *p;
222 #endif
223 #if defined(TCP_SACK)
224 int maxburst = TCP_MAXBURST;
225 #endif
226 #ifdef TCP_SIGNATURE
227 unsigned int sigoff;
228 #endif
229 #ifdef TCP_ECN
230 int needect;
231 #endif
232
233 #if defined(TCP_SACK) && defined(TCP_SIGNATURE) && defined(DIAGNOSTIC)
234 if (tp->sack_enable && (tp->t_flags & TF_SIGNATURE))
235 return (EINVAL);
236 #endif
237
238
239
240
241
242
243
244 idle = (tp->t_flags & TF_LASTIDLE) || (tp->snd_max == tp->snd_una);
245 if (idle && (tcp_now - tp->t_rcvtime) >= tp->t_rxtcur)
246
247
248
249
250
251 tp->snd_cwnd = 2 * tp->t_maxseg;
252
253
254 if (idle && soissending(so)) {
255 tp->t_flags |= TF_LASTIDLE;
256 idle = 0;
257 } else
258 tp->t_flags &= ~TF_LASTIDLE;
259
260 again:
261 #ifdef TCP_SACK
262
263
264
265
266
267 if (tp->sack_enable && SEQ_LT(tp->snd_nxt, tp->snd_max))
268 tcp_sack_adjust(tp);
269 #endif
270 off = tp->snd_nxt - tp->snd_una;
271 #if defined(TCP_SACK) && defined(TCP_FACK)
272
273
274
275
276 if (tp->sack_enable && (tp->t_dupacks > tcprexmtthresh))
277 win = tp->snd_wnd;
278 else
279 #endif
280 win = ulmin(tp->snd_wnd, tp->snd_cwnd);
281
282 flags = tcp_outflags[tp->t_state];
283
284 #ifdef TCP_SACK
285
286
287
288
289
290
291
292 if (tp->sack_enable && !sendalot) {
293 if (tp->t_dupacks >= tcprexmtthresh &&
294 (p = tcp_sack_output(tp))) {
295 off = p->rxmit - tp->snd_una;
296 sack_rxmit = 1;
297 #if 0
298
299 #endif
300 len = min(tp->t_maxseg, p->end - p->rxmit);
301 #ifndef TCP_FACK
302
303 if (SEQ_LT(tp->snd_una, tp->snd_last))
304 tp->snd_cwnd -= tp->t_maxseg;
305 #endif
306 }
307 }
308 #endif
309
310 sendalot = 0;
311
312
313
314
315
316
317 if (tp->t_force) {
318 if (win == 0) {
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335 if (off < so->so_snd.sb_cc)
336 flags &= ~TH_FIN;
337 win = 1;
338 } else {
339 TCP_TIMER_DISARM(tp, TCPT_PERSIST);
340 tp->t_rxtshift = 0;
341 }
342 }
343
344 #ifdef TCP_SACK
345 if (!sack_rxmit) {
346 #endif
347 len = ulmin(so->so_snd.sb_cc, win) - off;
348
349 #if defined(TCP_SACK) && defined(TCP_FACK)
350
351
352
353
354
355 if (tp->sack_enable && len && SEQ_GT(tp->snd_last, tp->snd_una) &&
356 (tp->snd_awnd >= tp->snd_cwnd))
357 len = 0;
358 #endif
359 #ifdef TCP_SACK
360 }
361 #endif
362
363 if (len < 0) {
364
365
366
367
368
369
370
371
372
373
374 len = 0;
375 if (win == 0) {
376 TCP_TIMER_DISARM(tp, TCPT_REXMT);
377 tp->t_rxtshift = 0;
378 tp->snd_nxt = tp->snd_una;
379 if (TCP_TIMER_ISARMED(tp, TCPT_PERSIST) == 0)
380 tcp_setpersist(tp);
381 }
382 }
383
384
385
386
387
388
389
390 txmaxseg = ulmin(so->so_snd.sb_hiwat / 2, tp->t_maxseg);
391
392 if (len > txmaxseg) {
393 len = txmaxseg;
394 sendalot = 1;
395 }
396 if (off + len < so->so_snd.sb_cc)
397 flags &= ~TH_FIN;
398
399 win = sbspace(&so->so_rcv);
400
401
402
403
404
405
406
407
408
409
410
411 if (len) {
412 if (len == txmaxseg)
413 goto send;
414 if ((idle || tp->t_flags & TF_NODELAY) &&
415 len + off >= so->so_snd.sb_cc && !soissending(so))
416 goto send;
417 if (tp->t_force)
418 goto send;
419 if (len >= tp->max_sndwnd / 2 && tp->max_sndwnd > 0)
420 goto send;
421 if (SEQ_LT(tp->snd_nxt, tp->snd_max))
422 goto send;
423 #ifdef TCP_SACK
424 if (sack_rxmit)
425 goto send;
426 #endif
427 }
428
429
430
431
432
433
434
435
436 if (win > 0) {
437
438
439
440
441
442 long adv = lmin(win, (long)TCP_MAXWIN << tp->rcv_scale) -
443 (tp->rcv_adv - tp->rcv_nxt);
444
445 if (adv >= (long) (2 * tp->t_maxseg))
446 goto send;
447 if (2 * adv >= (long) so->so_rcv.sb_hiwat)
448 goto send;
449 }
450
451
452
453
454 if (tp->t_flags & TF_ACKNOW)
455 goto send;
456 if (flags & (TH_SYN|TH_RST))
457 goto send;
458 if (SEQ_GT(tp->snd_up, tp->snd_una))
459 goto send;
460
461
462
463
464
465 if (flags & TH_FIN &&
466 ((tp->t_flags & TF_SENTFIN) == 0 || tp->snd_nxt == tp->snd_una))
467 goto send;
468 #ifdef TCP_SACK
469
470
471
472
473
474 if (SEQ_GT(tp->snd_max, tp->snd_una) &&
475 TCP_TIMER_ISARMED(tp, TCPT_REXMT) == 0 &&
476 TCP_TIMER_ISARMED(tp, TCPT_PERSIST) == 0) {
477 TCP_TIMER_ARM(tp, TCPT_REXMT, tp->t_rxtcur);
478 return (0);
479 }
480 #endif
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504 if (so->so_snd.sb_cc && TCP_TIMER_ISARMED(tp, TCPT_REXMT) == 0 &&
505 TCP_TIMER_ISARMED(tp, TCPT_PERSIST) == 0) {
506 tp->t_rxtshift = 0;
507 tcp_setpersist(tp);
508 }
509
510
511
512
513 return (0);
514
515 send:
516
517
518
519
520
521
522
523
524
525 optlen = 0;
526
527 switch (tp->pf) {
528 case 0:
529 #ifdef INET
530 case PF_INET:
531 hdrlen = sizeof(struct ip) + sizeof(struct tcphdr);
532 break;
533 #endif
534 #ifdef INET6
535 case PF_INET6:
536 hdrlen = sizeof(struct ip6_hdr) + sizeof(struct tcphdr);
537 break;
538 #endif
539 default:
540 return (EPFNOSUPPORT);
541 }
542
543 if (flags & TH_SYN) {
544 tp->snd_nxt = tp->iss;
545 if ((tp->t_flags & TF_NOOPT) == 0) {
546 u_int16_t mss;
547
548 opt[0] = TCPOPT_MAXSEG;
549 opt[1] = 4;
550 mss = htons((u_int16_t) tcp_mss(tp, 0));
551 bcopy((caddr_t)&mss, (caddr_t)(opt + 2), sizeof(mss));
552 optlen = 4;
553
554 if (flags & TH_ACK)
555 tcp_mss_update(tp);
556 #ifdef TCP_SACK
557
558
559
560
561
562
563 if (tp->sack_enable && ((flags & TH_ACK) == 0 ||
564 (tp->t_flags & TF_SACK_PERMIT))) {
565 *((u_int32_t *) (opt + optlen)) =
566 htonl(TCPOPT_SACK_PERMIT_HDR);
567 optlen += 4;
568 }
569 #endif
570
571 if ((tp->t_flags & TF_REQ_SCALE) &&
572 ((flags & TH_ACK) == 0 ||
573 (tp->t_flags & TF_RCVD_SCALE))) {
574 *((u_int32_t *) (opt + optlen)) = htonl(
575 TCPOPT_NOP << 24 |
576 TCPOPT_WINDOW << 16 |
577 TCPOLEN_WINDOW << 8 |
578 tp->request_r_scale);
579 optlen += 4;
580 }
581 }
582 }
583
584
585
586
587
588
589 if ((tp->t_flags & (TF_REQ_TSTMP|TF_NOOPT)) == TF_REQ_TSTMP &&
590 (flags & TH_RST) == 0 &&
591 ((flags & (TH_SYN|TH_ACK)) == TH_SYN ||
592 (tp->t_flags & TF_RCVD_TSTMP))) {
593 u_int32_t *lp = (u_int32_t *)(opt + optlen);
594
595
596 *lp++ = htonl(TCPOPT_TSTAMP_HDR);
597 *lp++ = htonl(tcp_now + tp->ts_modulate);
598 *lp = htonl(tp->ts_recent);
599 optlen += TCPOLEN_TSTAMP_APPA;
600 }
601
602 #ifdef TCP_SIGNATURE
603 if (tp->t_flags & TF_SIGNATURE) {
604 u_int8_t *bp = (u_int8_t *)(opt + optlen);
605
606
607 *(bp++) = TCPOPT_SIGNATURE;
608 *(bp++) = TCPOLEN_SIGNATURE;
609 sigoff = optlen + 2;
610
611 {
612 unsigned int i;
613
614 for (i = 0; i < 16; i++)
615 *(bp++) = 0;
616 }
617
618
619
620
621
622 *bp++ = TCPOPT_NOP;
623 *bp++ = TCPOPT_EOL;
624
625 optlen += TCPOLEN_SIGLEN;
626 }
627 #endif
628
629 #ifdef TCP_SACK
630
631
632
633
634
635 if (tp->sack_enable && tp->t_state == TCPS_ESTABLISHED &&
636 (tp->t_flags & (TF_SACK_PERMIT|TF_NOOPT)) == TF_SACK_PERMIT &&
637 tp->rcv_numsacks) {
638 u_int32_t *lp = (u_int32_t *)(opt + optlen);
639 u_int32_t *olp = lp++;
640 int count = 0;
641 int maxsack = (MAX_TCPOPTLEN - (optlen + 4))/TCPOLEN_SACK;
642
643 tcpstat.tcps_sack_snd_opts++;
644 maxsack = min(maxsack, TCP_MAX_SACK);
645 for (i = 0; (i < tp->rcv_numsacks && count < maxsack); i++) {
646 struct sackblk sack = tp->sackblks[i];
647 if (sack.start == 0 && sack.end == 0)
648 continue;
649 *lp++ = htonl(sack.start);
650 *lp++ = htonl(sack.end);
651 count++;
652 }
653 *olp = htonl(TCPOPT_SACK_HDR|(TCPOLEN_SACK*count+2));
654 optlen += TCPOLEN_SACK*count + 4;
655 }
656 #endif
657
658 #ifdef DIAGNOSTIC
659 if (optlen > MAX_TCPOPTLEN)
660 panic("tcp_output: options too long");
661 #endif
662
663 hdrlen += optlen;
664
665
666
667
668
669 if (len > tp->t_maxopd - optlen) {
670 len = tp->t_maxopd - optlen;
671 sendalot = 1;
672 flags &= ~TH_FIN;
673 }
674
675 #ifdef DIAGNOSTIC
676 if (max_linkhdr + hdrlen > MCLBYTES)
677 panic("tcphdr too big");
678 #endif
679
680
681
682
683
684
685 if (len) {
686 if (tp->t_force && len == 1)
687 tcpstat.tcps_sndprobe++;
688 else if (SEQ_LT(tp->snd_nxt, tp->snd_max)) {
689 tcpstat.tcps_sndrexmitpack++;
690 tcpstat.tcps_sndrexmitbyte += len;
691 } else {
692 tcpstat.tcps_sndpack++;
693 tcpstat.tcps_sndbyte += len;
694 }
695 #ifdef notyet
696 if ((m = m_copypack(so->so_snd.sb_mb, off,
697 (int)len, max_linkhdr + hdrlen)) == 0) {
698 error = ENOBUFS;
699 goto out;
700 }
701
702
703
704 m->m_len += hdrlen;
705 m->m_data -= hdrlen;
706 #else
707 MGETHDR(m, M_DONTWAIT, MT_HEADER);
708 if (m != NULL && max_linkhdr + hdrlen > MHLEN) {
709 MCLGET(m, M_DONTWAIT);
710 if ((m->m_flags & M_EXT) == 0) {
711 m_freem(m);
712 m = NULL;
713 }
714 }
715 if (m == NULL) {
716 error = ENOBUFS;
717 goto out;
718 }
719 m->m_data += max_linkhdr;
720 m->m_len = hdrlen;
721 if (len <= M_TRAILINGSPACE(m)) {
722 m_copydata(so->so_snd.sb_mb, off, (int) len,
723 mtod(m, caddr_t) + hdrlen);
724 m->m_len += len;
725 } else {
726 m->m_next = m_copy(so->so_snd.sb_mb, off, (int) len);
727 if (m->m_next == 0) {
728 (void) m_free(m);
729 error = ENOBUFS;
730 goto out;
731 }
732 }
733 #endif
734
735
736
737
738
739
740 if (off + len == so->so_snd.sb_cc && !soissending(so))
741 flags |= TH_PUSH;
742 } else {
743 if (tp->t_flags & TF_ACKNOW)
744 tcpstat.tcps_sndacks++;
745 else if (flags & (TH_SYN|TH_FIN|TH_RST))
746 tcpstat.tcps_sndctrl++;
747 else if (SEQ_GT(tp->snd_up, tp->snd_una))
748 tcpstat.tcps_sndurg++;
749 else
750 tcpstat.tcps_sndwinup++;
751
752 MGETHDR(m, M_DONTWAIT, MT_HEADER);
753 if (m != NULL && max_linkhdr + hdrlen > MHLEN) {
754 MCLGET(m, M_DONTWAIT);
755 if ((m->m_flags & M_EXT) == 0) {
756 m_freem(m);
757 m = NULL;
758 }
759 }
760 if (m == NULL) {
761 error = ENOBUFS;
762 goto out;
763 }
764 m->m_data += max_linkhdr;
765 m->m_len = hdrlen;
766 }
767 m->m_pkthdr.rcvif = (struct ifnet *)0;
768 m->m_pkthdr.len = hdrlen + len;
769
770 if (!tp->t_template)
771 panic("tcp_output");
772 #ifdef DIAGNOSTIC
773 if (tp->t_template->m_len != hdrlen - optlen)
774 panic("tcp_output: template len != hdrlen - optlen");
775 #endif
776 bcopy(mtod(tp->t_template, caddr_t), mtod(m, caddr_t),
777 tp->t_template->m_len);
778 th = (struct tcphdr *)(mtod(m, caddr_t) + tp->t_template->m_len -
779 sizeof(struct tcphdr));
780
781
782
783
784
785
786 if ((flags & TH_FIN) && (tp->t_flags & TF_SENTFIN) &&
787 (tp->snd_nxt == tp->snd_max))
788 tp->snd_nxt--;
789
790
791
792
793
794
795
796
797
798
799
800
801
802 if (len || (flags & (TH_SYN|TH_FIN)) || TCP_TIMER_ISARMED(tp, TCPT_PERSIST))
803 th->th_seq = htonl(tp->snd_nxt);
804 else
805 th->th_seq = htonl(tp->snd_max);
806
807 #ifdef TCP_SACK
808 if (sack_rxmit) {
809
810
811
812
813
814 if (sendalot)
815 sendalot = 0;
816 th->th_seq = htonl(p->rxmit);
817 p->rxmit += len;
818 #if defined(TCP_SACK) && defined(TCP_FACK)
819 tp->retran_data += len;
820 #endif
821 tcpstat.tcps_sack_rexmits++;
822 tcpstat.tcps_sack_rexmit_bytes += len;
823 }
824 #endif
825
826 th->th_ack = htonl(tp->rcv_nxt);
827 if (optlen) {
828 bcopy((caddr_t)opt, (caddr_t)(th + 1), optlen);
829 th->th_off = (sizeof (struct tcphdr) + optlen) >> 2;
830 }
831 #ifdef TCP_ECN
832 if (tcp_do_ecn) {
833
834
835
836
837 if (tp->t_flags & TF_RCVD_CE) {
838 flags |= TH_ECE;
839 tcpstat.tcps_ecn_sndece++;
840 }
841 if (!(tp->t_flags & TF_DISABLE_ECN)) {
842
843
844
845
846 if ((flags & (TH_SYN|TH_ACK)) == TH_SYN)
847 flags |= (TH_ECE|TH_CWR);
848 else if ((tp->t_flags & TF_ECN_PERMIT) &&
849 (flags & (TH_SYN|TH_ACK)) == (TH_SYN|TH_ACK))
850 flags |= TH_ECE;
851 }
852
853
854
855
856 if ((tp->t_flags & TF_ECN_PERMIT) &&
857 (tp->t_flags & TF_SEND_CWR)) {
858 flags |= TH_CWR;
859 tp->t_flags &= ~TF_SEND_CWR;
860 tcpstat.tcps_ecn_sndcwr++;
861 }
862 }
863 #endif
864 th->th_flags = flags;
865
866
867
868
869
870 if (win < (long)(so->so_rcv.sb_hiwat / 4) && win < (long)tp->t_maxseg)
871 win = 0;
872 if (win > (long)TCP_MAXWIN << tp->rcv_scale)
873 win = (long)TCP_MAXWIN << tp->rcv_scale;
874 if (win < (long)(int32_t)(tp->rcv_adv - tp->rcv_nxt))
875 win = (long)(int32_t)(tp->rcv_adv - tp->rcv_nxt);
876 if (flags & TH_RST)
877 win = 0;
878 th->th_win = htons((u_int16_t) (win>>tp->rcv_scale));
879 if (SEQ_GT(tp->snd_up, tp->snd_nxt)) {
880 u_int32_t urp = tp->snd_up - tp->snd_nxt;
881 if (urp > IP_MAXPACKET)
882 urp = IP_MAXPACKET;
883 th->th_urp = htons((u_int16_t)urp);
884 th->th_flags |= TH_URG;
885 } else
886
887
888
889
890
891
892 tp->snd_up = tp->snd_una;
893
894 #ifdef TCP_SIGNATURE
895 if (tp->t_flags & TF_SIGNATURE) {
896 int iphlen;
897 union sockaddr_union src, dst;
898 struct tdb *tdb;
899
900 bzero(&src, sizeof(union sockaddr_union));
901 bzero(&dst, sizeof(union sockaddr_union));
902
903 switch (tp->pf) {
904 case 0:
905 #ifdef INET
906 case AF_INET:
907 iphlen = sizeof(struct ip);
908 src.sa.sa_len = sizeof(struct sockaddr_in);
909 src.sa.sa_family = AF_INET;
910 src.sin.sin_addr = mtod(m, struct ip *)->ip_src;
911 dst.sa.sa_len = sizeof(struct sockaddr_in);
912 dst.sa.sa_family = AF_INET;
913 dst.sin.sin_addr = mtod(m, struct ip *)->ip_dst;
914 break;
915 #endif
916 #ifdef INET6
917 case AF_INET6:
918 iphlen = sizeof(struct ip6_hdr);
919 src.sa.sa_len = sizeof(struct sockaddr_in6);
920 src.sa.sa_family = AF_INET6;
921 src.sin6.sin6_addr = mtod(m, struct ip6_hdr *)->ip6_src;
922 dst.sa.sa_len = sizeof(struct sockaddr_in6);
923 dst.sa.sa_family = AF_INET6;
924 dst.sin6.sin6_addr = mtod(m, struct ip6_hdr *)->ip6_dst;
925 break;
926 #endif
927 }
928
929
930
931 tdb = gettdbbysrcdst(0, &src, &dst, IPPROTO_TCP);
932 if (tdb == NULL)
933 return (EPERM);
934
935 if (tcp_signature(tdb, tp->pf, m, th, iphlen, 0,
936 mtod(m, caddr_t) + hdrlen - optlen + sigoff) < 0)
937 return (EINVAL);
938 }
939 #endif
940
941
942
943
944
945 switch (tp->pf) {
946 case 0:
947 #ifdef INET
948 case AF_INET:
949
950 m->m_pkthdr.csum_flags |= M_TCPV4_CSUM_OUT;
951 if (len + optlen)
952 th->th_sum = in_cksum_addword(th->th_sum,
953 htons((u_int16_t)(len + optlen)));
954 break;
955 #endif
956 #ifdef INET6
957 case AF_INET6:
958 th->th_sum = in6_cksum(m, IPPROTO_TCP, sizeof(struct ip6_hdr),
959 hdrlen - sizeof(struct ip6_hdr) + len);
960 break;
961 #endif
962 }
963
964
965
966
967
968 if (tp->t_force == 0 || TCP_TIMER_ISARMED(tp, TCPT_PERSIST) == 0) {
969 tcp_seq startseq = tp->snd_nxt;
970
971
972
973
974 if (flags & (TH_SYN|TH_FIN)) {
975 if (flags & TH_SYN)
976 tp->snd_nxt++;
977 if (flags & TH_FIN) {
978 tp->snd_nxt++;
979 tp->t_flags |= TF_SENTFIN;
980 }
981 }
982 #ifdef TCP_SACK
983 if (tp->sack_enable) {
984 if (sack_rxmit && (p->rxmit != tp->snd_nxt)) {
985 goto timer;
986 }
987 }
988 #endif
989 tp->snd_nxt += len;
990 if (SEQ_GT(tp->snd_nxt, tp->snd_max)) {
991 tp->snd_max = tp->snd_nxt;
992
993
994
995
996 if (tp->t_rtttime == 0) {
997 tp->t_rtttime = tcp_now;
998 tp->t_rtseq = startseq;
999 tcpstat.tcps_segstimed++;
1000 }
1001 }
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011 #ifdef TCP_SACK
1012 timer:
1013 if (tp->sack_enable && sack_rxmit &&
1014 TCP_TIMER_ISARMED(tp, TCPT_REXMT) == 0 &&
1015 tp->snd_nxt != tp->snd_max) {
1016 TCP_TIMER_ARM(tp, TCPT_REXMT, tp->t_rxtcur);
1017 if (TCP_TIMER_ISARMED(tp, TCPT_PERSIST)) {
1018 TCP_TIMER_DISARM(tp, TCPT_PERSIST);
1019 tp->t_rxtshift = 0;
1020 }
1021 }
1022 #endif
1023
1024 if (TCP_TIMER_ISARMED(tp, TCPT_REXMT) == 0 &&
1025 tp->snd_nxt != tp->snd_una) {
1026 TCP_TIMER_ARM(tp, TCPT_REXMT, tp->t_rxtcur);
1027 if (TCP_TIMER_ISARMED(tp, TCPT_PERSIST)) {
1028 TCP_TIMER_DISARM(tp, TCPT_PERSIST);
1029 tp->t_rxtshift = 0;
1030 }
1031 }
1032 } else
1033 if (SEQ_GT(tp->snd_nxt + len, tp->snd_max))
1034 tp->snd_max = tp->snd_nxt + len;
1035
1036
1037
1038
1039 if (so->so_options & SO_DEBUG)
1040 tcp_trace(TA_OUTPUT, tp->t_state, tp, mtod(m, caddr_t), 0,
1041 len);
1042
1043
1044
1045
1046
1047
1048
1049
1050 #ifdef TCP_ECN
1051
1052
1053
1054
1055 needect = 0;
1056 if (tcp_do_ecn && (tp->t_flags & TF_ECN_PERMIT)) {
1057 if (len == 0 || SEQ_LT(tp->snd_nxt, tp->snd_max) ||
1058 (tp->t_force && len == 1)) {
1059
1060 } else {
1061 needect = 1;
1062 tcpstat.tcps_ecn_sndect++;
1063 }
1064 }
1065 #endif
1066
1067 switch (tp->pf) {
1068 case 0:
1069 #ifdef INET
1070 case AF_INET:
1071 {
1072 struct ip *ip;
1073
1074 ip = mtod(m, struct ip *);
1075 ip->ip_len = htons(m->m_pkthdr.len);
1076 packetlen = m->m_pkthdr.len;
1077 ip->ip_ttl = tp->t_inpcb->inp_ip.ip_ttl;
1078 ip->ip_tos = tp->t_inpcb->inp_ip.ip_tos;
1079 #ifdef TCP_ECN
1080 if (needect)
1081 ip->ip_tos |= IPTOS_ECN_ECT0;
1082 #endif
1083 }
1084 error = ip_output(m, tp->t_inpcb->inp_options,
1085 &tp->t_inpcb->inp_route,
1086 (ip_mtudisc ? IP_MTUDISC : 0) |
1087 (so->so_options & SO_DONTROUTE),
1088 (void *)NULL, tp->t_inpcb);
1089 break;
1090 #endif
1091 #ifdef INET6
1092 case AF_INET6:
1093 {
1094 struct ip6_hdr *ip6;
1095
1096 ip6 = mtod(m, struct ip6_hdr *);
1097 ip6->ip6_plen = m->m_pkthdr.len -
1098 sizeof(struct ip6_hdr);
1099 packetlen = m->m_pkthdr.len;
1100 ip6->ip6_nxt = IPPROTO_TCP;
1101 ip6->ip6_hlim = in6_selecthlim(tp->t_inpcb, NULL);
1102 #ifdef TCP_ECN
1103 if (needect)
1104 ip6->ip6_flow |= htonl(IPTOS_ECN_ECT0 << 20);
1105 #endif
1106 }
1107 error = ip6_output(m, tp->t_inpcb->inp_outputopts6,
1108 &tp->t_inpcb->inp_route6,
1109 (so->so_options & SO_DONTROUTE), NULL, NULL,
1110 tp->t_inpcb);
1111 break;
1112 #endif
1113 }
1114
1115 #if defined(TCP_SACK) && defined(TCP_FACK)
1116
1117 tp->snd_awnd = tcp_seq_subtract(tp->snd_max, tp->snd_fack) +
1118 tp->retran_data;
1119 #endif
1120
1121 if (error) {
1122 out:
1123 if (error == ENOBUFS) {
1124
1125
1126
1127
1128 tp->snd_cwnd = tp->t_maxseg;
1129 return (0);
1130 }
1131 if (error == EMSGSIZE) {
1132
1133
1134
1135
1136
1137
1138 tcp_mtudisc(tp->t_inpcb, -1);
1139 return (0);
1140 }
1141 if ((error == EHOSTUNREACH || error == ENETDOWN) &&
1142 TCPS_HAVERCVDSYN(tp->t_state)) {
1143 tp->t_softerror = error;
1144 return (0);
1145 }
1146
1147
1148 if (tp->t_flags & TF_DELACK)
1149 TCP_RESTART_DELACK(tp);
1150
1151 return (error);
1152 }
1153
1154 if (packetlen > tp->t_pmtud_mtu_sent)
1155 tp->t_pmtud_mtu_sent = packetlen;
1156
1157 tcpstat.tcps_sndtotal++;
1158 if (tp->t_flags & TF_DELACK)
1159 tcpstat.tcps_delack++;
1160
1161
1162
1163
1164
1165
1166
1167 if (win > 0 && SEQ_GT(tp->rcv_nxt+win, tp->rcv_adv))
1168 tp->rcv_adv = tp->rcv_nxt + win;
1169 tp->last_ack_sent = tp->rcv_nxt;
1170 tp->t_flags &= ~TF_ACKNOW;
1171 TCP_CLEAR_DELACK(tp);
1172 #if defined(TCP_SACK)
1173 if (sendalot && --maxburst)
1174 #else
1175 if (sendalot)
1176 #endif
1177 goto again;
1178 return (0);
1179 }
1180
1181 void
1182 tcp_setpersist(struct tcpcb *tp)
1183 {
1184 int t = ((tp->t_srtt >> 2) + tp->t_rttvar) >> (1 + TCP_RTT_BASE_SHIFT);
1185 int nticks;
1186
1187 if (TCP_TIMER_ISARMED(tp, TCPT_REXMT))
1188 panic("tcp_output REXMT");
1189
1190
1191
1192 if (t < tp->t_rttmin)
1193 t = tp->t_rttmin;
1194 TCPT_RANGESET(nticks, t * tcp_backoff[tp->t_rxtshift],
1195 TCPTV_PERSMIN, TCPTV_PERSMAX);
1196 TCP_TIMER_ARM(tp, TCPT_PERSIST, nticks);
1197 if (tp->t_rxtshift < TCP_MAXRXTSHIFT)
1198 tp->t_rxtshift++;
1199 }