OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [rtos/] [ecos-2.0/] [packages/] [net/] [tcpip/] [v2_0/] [src/] [sys/] [netinet/] [tcp_output.c] - Blame information for rev 749

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 27 unneback
//==========================================================================
2
//
3
//      sys/netinet/tcp_output.c
4
//
5
//     
6
//
7
//==========================================================================
8
//####BSDCOPYRIGHTBEGIN####
9
//
10
// -------------------------------------------
11
//
12
// Portions of this software may have been derived from OpenBSD or other sources,
13
// and are covered by the appropriate copyright disclaimers included herein.
14
//
15
// -------------------------------------------
16
//
17
//####BSDCOPYRIGHTEND####
18
//==========================================================================
19
//#####DESCRIPTIONBEGIN####
20
//
21
// Author(s):    gthomas
22
// Contributors: gthomas
23
// Date:         2000-01-10
24
// Purpose:      
25
// Description:  
26
//              
27
//
28
//####DESCRIPTIONEND####
29
//
30
//==========================================================================
31
 
32
 
33
/*      $OpenBSD: tcp_output.c,v 1.27 1999/12/15 16:37:20 provos Exp $  */
34
/*      $NetBSD: tcp_output.c,v 1.16 1997/06/03 16:17:09 kml Exp $      */
35
 
36
/*
37
 * Copyright (c) 1982, 1986, 1988, 1990, 1993
38
 *      The Regents of the University of California.  All rights reserved.
39
 *
40
 * Redistribution and use in source and binary forms, with or without
41
 * modification, are permitted provided that the following conditions
42
 * are met:
43
 * 1. Redistributions of source code must retain the above copyright
44
 *    notice, this list of conditions and the following disclaimer.
45
 * 2. Redistributions in binary form must reproduce the above copyright
46
 *    notice, this list of conditions and the following disclaimer in the
47
 *    documentation and/or other materials provided with the distribution.
48
 * 3. All advertising materials mentioning features or use of this software
49
 *    must display the following acknowledgement:
50
 *      This product includes software developed by the University of
51
 *      California, Berkeley and its contributors.
52
 * 4. Neither the name of the University nor the names of its contributors
53
 *    may be used to endorse or promote products derived from this software
54
 *    without specific prior written permission.
55
 *
56
 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
57
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
58
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
59
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
60
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
61
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
62
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
63
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
64
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
65
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
66
 * SUCH DAMAGE.
67
 *
68
 *      @(#)tcp_output.c        8.3 (Berkeley) 12/30/93
69
 */
70
 
71
/*
72
%%% portions-copyright-nrl-95
73
Portions of this software are Copyright 1995-1998 by Randall Atkinson,
74
Ronald Lee, Daniel McDonald, Bao Phan, and Chris Winters. All Rights
75
Reserved. All rights under this copyright have been assigned to the US
76
Naval Research Laboratory (NRL). The NRL Copyright Notice and License
77
Agreement Version 1.1 (January 17, 1995) applies to these portions of the
78
software.
79
You should have received a copy of the license with this software. If you
80
didn't get a copy, you may request one from <license@ipv6.nrl.navy.mil>.
81
*/
82
 
83
#include <sys/param.h>
84
#ifndef __ECOS
85
#include <sys/systm.h>
86
#endif
87
#include <sys/malloc.h>
88
#include <sys/mbuf.h>
89
#include <sys/protosw.h>
90
#include <sys/socket.h>
91
#include <sys/socketvar.h>
92
#include <sys/errno.h>
93
#include <sys/domain.h>
94
 
95
#include <net/route.h>
96
 
97
#include <netinet/in.h>
98
#include <netinet/in_systm.h>
99
#include <netinet/ip.h>
100
#include <netinet/in_pcb.h>
101
#include <netinet/ip_var.h>
102
#include <netinet/tcp.h>
103
#define TCPOUTFLAGS
104
#include <netinet/tcp_fsm.h>
105
#include <netinet/tcp_seq.h>
106
#include <netinet/tcp_timer.h>
107
#include <netinet/tcp_var.h>
108
#include <netinet/tcpip.h>
109
#include <netinet/tcp_debug.h>
110
 
111
#ifdef TUBA
112
#include <netiso/iso.h>
113
#include <netiso/tuba_table.h>
114
#endif
115
 
116
#ifdef INET6
117
#include <netinet6/tcpipv6.h>
118
#endif /* INET6 */
119
 
120
#ifdef TCP_SIGNATURE
121
#include <sys/md5k.h>
122
#endif /* TCP_SIGNATURE */
123
 
124
#ifdef notyet
125
extern struct mbuf *m_copypack();
126
#endif
127
 
128
#ifdef TCP_SACK
129
extern int tcprexmtthresh;
130
#endif
131
 
132
#ifdef TCP_SACK
133
#ifdef TCP_SACK_DEBUG
134
void
135
tcp_print_holes(tp)
136
struct tcpcb *tp;
137
{
138
        struct sackhole *p = tp->snd_holes;
139
        if (p == 0)
140
                return;
141
        printf("Hole report: start--end dups rxmit\n");
142
        while (p) {
143
                printf("%x--%x d %d r %x\n",  p->start, p->end, p->dups,
144
                    p->rxmit);
145
                p = p->next;
146
        }
147
        printf("\n");
148
}
149
#endif /* TCP_SACK_DEBUG */
150
 
151
/*
152
 * Returns pointer to a sackhole if there are any pending retransmissions;
153
 * NULL otherwise.
154
 */
155
struct sackhole *
156
tcp_sack_output(tp)
157
register struct tcpcb *tp;
158
{
159
        struct sackhole *p;
160
        if (tp->sack_disable)
161
                return 0;
162
        p = tp->snd_holes;
163
        while (p) {
164
                if (p->dups >= tcprexmtthresh && SEQ_LT(p->rxmit, p->end)) {
165
                        if (SEQ_LT(p->rxmit, tp->snd_una)) {/* old SACK hole */
166
                                p = p->next;
167
                                continue;
168
                        }
169
#ifdef TCP_SACK_DEBUG
170
                        if (p)
171
                                tcp_print_holes(tp);
172
#endif
173
                        return p;
174
                }
175
                p = p->next;
176
        }
177
        return 0;
178
}
179
 
180
/*
181
 * After a timeout, the SACK list may be rebuilt.  This SACK information
182
 * should be used to avoid retransmitting SACKed data.  This function
183
 * traverses the SACK list to see if snd_nxt should be moved forward.
184
 */
185
void
186
tcp_sack_adjust(tp)
187
        struct tcpcb *tp;
188
{
189
        int i;
190
 
191
        for (i = 0; i < tp->rcv_numsacks; i++) {
192
                if (SEQ_LT(tp->snd_nxt, tp->sackblks[i].start))
193
                        break;
194
                if (SEQ_LEQ(tp->sackblks[i].end, tp->snd_nxt))
195
                        continue;
196
                if (tp->sackblks[i].start == 0 && tp->sackblks[i].end == 0)
197
                        continue;
198
                /* snd_nxt must be in middle of block of SACKed data */
199
                tp->snd_nxt = tp->sackblks[i].end;
200
                break;
201
        }
202
}
203
#endif /* TCP_SACK */
204
 
205
/*
206
 * Tcp output routine: figure out what should be sent and send it.
207
 */
208
int
209
tcp_output(tp)
210
        register struct tcpcb *tp;
211
{
212
        register struct socket *so = tp->t_inpcb->inp_socket;
213
        register long len, win;
214
        int off, flags, error = 0;
215
        register struct mbuf *m;
216
        register struct tcphdr *th;
217
        u_char opt[MAX_TCPOPTLEN];
218
        unsigned int optlen, hdrlen;
219
        int idle, sendalot;
220
#ifdef TCP_SACK
221
        int i, sack_rxmit = 0;
222
        struct sackhole *p;
223
#endif
224
#if defined(TCP_SACK) || defined(TCP_NEWRENO)
225
        int maxburst = TCP_MAXBURST;
226
#endif
227
#ifdef TCP_SIGNATURE
228
        unsigned int sigoff;
229
#endif /* TCP_SIGNATURE */
230
 
231
#if defined(TCP_SACK) && defined(TCP_SIGNATURE) && defined(DIAGNOSTIC)
232
        if (!tp->sack_disable && (tp->t_flags & TF_SIGNATURE))
233
                return (EINVAL);
234
#endif /* defined(TCP_SACK) && defined(TCP_SIGNATURE) && defined(DIAGNOSTIC) */
235
 
236
        /*
237
         * Determine length of data that should be transmitted,
238
         * and flags that will be used.
239
         * If there is some data or critical controls (SYN, RST)
240
         * to send, then transmit; otherwise, investigate further.
241
         */
242
        idle = (tp->snd_max == tp->snd_una);
243
        if (idle && tp->t_idle >= tp->t_rxtcur)
244
                /*
245
                 * We have been idle for "a while" and no acks are
246
                 * expected to clock out any data we send --
247
                 * slow start to get ack "clock" running again.
248
                 */
249
                tp->snd_cwnd = tp->t_maxseg;
250
again:
251
        sendalot = 0;
252
#ifdef TCP_SACK
253
        /*
254
         * If we've recently taken a timeout, snd_max will be greater than
255
         * snd_nxt.  There may be SACK information that allows us to avoid
256
         * resending already delivered data.  Adjust snd_nxt accordingly.
257
         */
258
        if (!tp->sack_disable && SEQ_LT(tp->snd_nxt, tp->snd_max))
259
                tcp_sack_adjust(tp);
260
#endif
261
        off = tp->snd_nxt - tp->snd_una;
262
        win = ulmin(tp->snd_wnd, tp->snd_cwnd);
263
 
264
        flags = tcp_outflags[tp->t_state];
265
        /*
266
         * If in persist timeout with window of 0, send 1 byte.
267
         * Otherwise, if window is small but nonzero
268
         * and timer expired, we will send what we can
269
         * and go to transmit state.
270
         */
271
 
272
#ifdef TCP_SACK
273
        /*
274
         * Send any SACK-generated retransmissions.  If we're explicitly trying
275
         * to send out new data (when sendalot is 1), bypass this function.
276
         * If we retransmit in fast recovery mode, decrement snd_cwnd, since
277
         * we're replacing a (future) new transmission with a retransmission
278
         * now, and we previously incremented snd_cwnd in tcp_input().
279
         */
280
        if (!tp->sack_disable && !sendalot) {
281
                if ((p = tcp_sack_output(tp))) {
282
                        off = p->rxmit - tp->snd_una;
283
                        sack_rxmit = 1;
284
#if 0
285
                        /* Coalesce holes into a single retransmission */
286
#endif
287
                        len = min(tp->t_maxseg, p->end - p->rxmit);
288
#ifndef TCP_FACK
289
                        /* in FACK, hold snd_cwnd constant during recovery */
290
                        if (SEQ_LT(tp->snd_una, tp->snd_last))
291
                                tp->snd_cwnd -= tp->t_maxseg;
292
#endif
293
                }
294
        }
295
#endif /* TCP_SACK */
296
 
297
        if (tp->t_force) {
298
                if (win == 0) {
299
                        /*
300
                         * If we still have some data to send, then
301
                         * clear the FIN bit.  Usually this would
302
                         * happen below when it realizes that we
303
                         * aren't sending all the data.  However,
304
                         * if we have exactly 1 byte of unset data,
305
                         * then it won't clear the FIN bit below,
306
                         * and if we are in persist state, we wind
307
                         * up sending the packet without recording
308
                         * that we sent the FIN bit.
309
                         *
310
                         * We can't just blindly clear the FIN bit,
311
                         * because if we don't have any more data
312
                         * to send then the probe will be the FIN
313
                         * itself.
314
                         */
315
                        if (off < so->so_snd.sb_cc)
316
                                flags &= ~TH_FIN;
317
                        win = 1;
318
                } else {
319
                        tp->t_timer[TCPT_PERSIST] = 0;
320
                        tp->t_rxtshift = 0;
321
                }
322
        }
323
 
324
#ifdef TCP_SACK
325
        if (!sack_rxmit) {
326
#endif
327
        len = ulmin(so->so_snd.sb_cc, win) - off;
328
 
329
#if defined(TCP_SACK) && defined(TCP_FACK)
330
        /*
331
         * If we're in fast recovery (SEQ_GT(tp->snd_last, tp->snd_una)), and
332
         * amount of outstanding data (snd_awnd) is >= snd_cwnd, then
333
         * do not send data (like zero window conditions)
334
         */
335
        if (!tp->sack_disable && len && SEQ_GT(tp->snd_last, tp->snd_una) &&
336
            (tp->snd_awnd >= tp->snd_cwnd))
337
                len = 0;
338
#endif /* TCP_FACK */
339
#ifdef TCP_SACK
340
        }
341
#endif
342
 
343
        if (len < 0) {
344
                /*
345
                 * If FIN has been sent but not acked,
346
                 * but we haven't been called to retransmit,
347
                 * len will be -1.  Otherwise, window shrank
348
                 * after we sent into it.  If window shrank to 0,
349
                 * cancel pending retransmit and pull snd_nxt
350
                 * back to (closed) window.  We will enter persist
351
                 * state below.  If the window didn't close completely,
352
                 * just wait for an ACK.
353
                 */
354
                len = 0;
355
                if (win == 0) {
356
                        tp->t_timer[TCPT_REXMT] = 0;
357
                        tp->snd_nxt = tp->snd_una;
358
                }
359
        }
360
        if (len > tp->t_maxseg) {
361
                len = tp->t_maxseg;
362
                sendalot = 1;
363
        }
364
        if (SEQ_LT(tp->snd_nxt + len, tp->snd_una + so->so_snd.sb_cc))
365
                flags &= ~TH_FIN;
366
 
367
        win = sbspace(&so->so_rcv);
368
 
369
        /*
370
         * Sender silly window avoidance.  If connection is idle
371
         * and can send all data, a maximum segment,
372
         * at least a maximum default-size segment do it,
373
         * or are forced, do it; otherwise don't bother.
374
         * If peer's buffer is tiny, then send
375
         * when window is at least half open.
376
         * If retransmitting (possibly after persist timer forced us
377
         * to send into a small window), then must resend.
378
         */
379
        if (len) {
380
                if (len == tp->t_maxseg)
381
                        goto send;
382
                if ((idle || tp->t_flags & TF_NODELAY) &&
383
                    len + off >= so->so_snd.sb_cc)
384
                        goto send;
385
                if (tp->t_force)
386
                        goto send;
387
                if (len >= tp->max_sndwnd / 2 && tp->max_sndwnd > 0)
388
                        goto send;
389
                if (SEQ_LT(tp->snd_nxt, tp->snd_max))
390
                        goto send;
391
#ifdef TCP_SACK
392
                if (sack_rxmit)
393
                        goto send;
394
#endif
395
        }
396
 
397
        /*
398
         * Compare available window to amount of window
399
         * known to peer (as advertised window less
400
         * next expected input).  If the difference is at least two
401
         * max size segments, or at least 50% of the maximum possible
402
         * window, then want to send a window update to peer.
403
         */
404
        if (win > 0) {
405
                /*
406
                 * "adv" is the amount we can increase the window,
407
                 * taking into account that we are limited by
408
                 * TCP_MAXWIN << tp->rcv_scale.
409
                 */
410
                long adv = lmin(win, (long)TCP_MAXWIN << tp->rcv_scale) -
411
                        (tp->rcv_adv - tp->rcv_nxt);
412
 
413
                if (adv >= (long) (2 * tp->t_maxseg))
414
                        goto send;
415
                if (2 * adv >= (long) so->so_rcv.sb_hiwat)
416
                        goto send;
417
        }
418
 
419
        /*
420
         * Send if we owe peer an ACK.
421
         */
422
        if (tp->t_flags & TF_ACKNOW)
423
                goto send;
424
        if (flags & (TH_SYN|TH_RST))
425
                goto send;
426
        if (SEQ_GT(tp->snd_up, tp->snd_una))
427
                goto send;
428
        /*
429
         * If our state indicates that FIN should be sent
430
         * and we have not yet done so, or we're retransmitting the FIN,
431
         * then we need to send.
432
         */
433
        if (flags & TH_FIN &&
434
            ((tp->t_flags & TF_SENTFIN) == 0 || tp->snd_nxt == tp->snd_una))
435
                goto send;
436
#ifdef TCP_SACK
437
        /*
438
         * In SACK, it is possible for tcp_output to fail to send a segment
439
         * after the retransmission timer has been turned off.  Make sure
440
         * that the retransmission timer is set.
441
         */
442
        if (SEQ_GT(tp->snd_max, tp->snd_una) &&
443
            tp->t_timer[TCPT_REXMT] == 0 &&
444
            tp->t_timer[TCPT_PERSIST] == 0) {
445
                tp->t_timer[TCPT_REXMT] = tp->t_rxtcur;
446
                return (0);
447
        }
448
#endif /* TCP_SACK */
449
 
450
        /*
451
         * TCP window updates are not reliable, rather a polling protocol
452
         * using ``persist'' packets is used to insure receipt of window
453
         * updates.  The three ``states'' for the output side are:
454
         *      idle                    not doing retransmits or persists
455
         *      persisting              to move a small or zero window
456
         *      (re)transmitting        and thereby not persisting
457
         *
458
         * tp->t_timer[TCPT_PERSIST]
459
         *      is set when we are in persist state.
460
         * tp->t_force
461
         *      is set when we are called to send a persist packet.
462
         * tp->t_timer[TCPT_REXMT]
463
         *      is set when we are retransmitting
464
         * The output side is idle when both timers are zero.
465
         *
466
         * If send window is too small, there is data to transmit, and no
467
         * retransmit or persist is pending, then go to persist state.
468
         * If nothing happens soon, send when timer expires:
469
         * if window is nonzero, transmit what we can,
470
         * otherwise force out a byte.
471
         */
472
        if (so->so_snd.sb_cc && tp->t_timer[TCPT_REXMT] == 0 &&
473
            tp->t_timer[TCPT_PERSIST] == 0) {
474
                tp->t_rxtshift = 0;
475
                tcp_setpersist(tp);
476
        }
477
 
478
        /*
479
         * No reason to send a segment, just return.
480
         */
481
        return (0);
482
 
483
send:
484
        /*
485
         * Before ESTABLISHED, force sending of initial options
486
         * unless TCP set not to do any options.
487
         * NOTE: we assume that the IP/TCP header plus TCP options
488
         * always fit in a single mbuf, leaving room for a maximum
489
         * link header, i.e.
490
         *      max_linkhdr + sizeof(network header) + sizeof(struct tcphdr +
491
         *              optlen <= MHLEN
492
         */
493
        optlen = 0;
494
 
495
        switch (tp->pf) {
496
        case 0:  /*default to PF_INET*/
497
#ifdef INET
498
        case PF_INET:
499
                hdrlen = sizeof(struct ip) + sizeof(struct tcphdr);
500
                break;
501
#endif /* INET */
502
#ifdef INET6
503
        case PF_INET6:
504
                hdrlen = sizeof(struct ip6_hdr) + sizeof(struct tcphdr);
505
                break;
506
#endif /* INET6 */
507
        default:
508
                return (EPFNOSUPPORT);
509
        }
510
 
511
        if (flags & TH_SYN) {
512
                tp->snd_nxt = tp->iss;
513
                if ((tp->t_flags & TF_NOOPT) == 0) {
514
                        u_int16_t mss;
515
 
516
                        opt[0] = TCPOPT_MAXSEG;
517
                        opt[1] = 4;
518
                        mss = htons((u_int16_t) tcp_mss(tp, 0));
519
                        bcopy((caddr_t)&mss, (caddr_t)(opt + 2), sizeof(mss));
520
                        optlen = 4;
521
#ifdef TCP_SACK
522
                        /*
523
                         * If this is the first SYN of connection (not a SYN
524
                         * ACK), include SACK_PERMIT_HDR option.  If this is a
525
                         * SYN ACK, include SACK_PERMIT_HDR option if peer has
526
                         * already done so.
527
                         */
528
                        if (!tp->sack_disable && ((flags & TH_ACK) == 0 ||
529
                            (tp->t_flags & TF_SACK_PERMIT))) {
530
                                *((u_int32_t *) (opt + optlen)) =
531
                                    htonl(TCPOPT_SACK_PERMIT_HDR);
532
                                optlen += 4;
533
                        }
534
#endif
535
 
536
                        if ((tp->t_flags & TF_REQ_SCALE) &&
537
                            ((flags & TH_ACK) == 0 ||
538
                            (tp->t_flags & TF_RCVD_SCALE))) {
539
                                *((u_int32_t *) (opt + optlen)) = htonl(
540
                                        TCPOPT_NOP << 24 |
541
                                        TCPOPT_WINDOW << 16 |
542
                                        TCPOLEN_WINDOW << 8 |
543
                                        tp->request_r_scale);
544
                                optlen += 4;
545
                        }
546
                }
547
        }
548
 
549
        /*
550
         * Send a timestamp and echo-reply if this is a SYN and our side
551
         * wants to use timestamps (TF_REQ_TSTMP is set) or both our side
552
         * and our peer have sent timestamps in our SYN's.
553
         */
554
        if ((tp->t_flags & (TF_REQ_TSTMP|TF_NOOPT)) == TF_REQ_TSTMP &&
555
             (flags & TH_RST) == 0 &&
556
            ((flags & (TH_SYN|TH_ACK)) == TH_SYN ||
557
             (tp->t_flags & TF_RCVD_TSTMP))) {
558
                u_int32_t *lp = (u_int32_t *)(opt + optlen);
559
 
560
                /* Form timestamp option as shown in appendix A of RFC 1323. */
561
                *lp++ = htonl(TCPOPT_TSTAMP_HDR);
562
                *lp++ = htonl(tcp_now);
563
                *lp   = htonl(tp->ts_recent);
564
                optlen += TCPOLEN_TSTAMP_APPA;
565
        }
566
 
567
#ifdef TCP_SIGNATURE
568
        if (tp->t_flags & TF_SIGNATURE) {
569
                u_int8_t *bp = (u_int8_t *)(opt + optlen);
570
 
571
                /* Send signature option */
572
                *(bp++) = TCPOPT_SIGNATURE;
573
                *(bp++) = TCPOLEN_SIGNATURE;
574
                sigoff = optlen + 2;
575
 
576
                {
577
                        unsigned int i;
578
 
579
                        for (i = 0; i < 16; i++)
580
                                *(bp++) = 0;
581
                }
582
 
583
                optlen += TCPOLEN_SIGNATURE;
584
 
585
                /* Pad options list to the next 32 bit boundary and
586
                 * terminate it.
587
                 */
588
                *bp++ = TCPOPT_NOP;
589
                *bp++ = TCPOPT_EOL;
590
                optlen += 2;
591
        }
592
#endif /* TCP_SIGNATURE */
593
 
594
#ifdef TCP_SACK
595
        /*
596
         * Send SACKs if necessary.  This should be the last option processed.
597
         * Only as many SACKs are sent as are permitted by the maximum options
598
         * size.  No more than three SACKs are sent.
599
         */
600
        if (!tp->sack_disable && tp->t_state == TCPS_ESTABLISHED &&
601
            (tp->t_flags & (TF_SACK_PERMIT|TF_NOOPT)) == TF_SACK_PERMIT &&
602
            tp->rcv_numsacks) {
603
                u_int32_t *lp = (u_int32_t *)(opt + optlen);
604
                u_int32_t *olp = lp++;
605
                int count = 0;  /* actual number of SACKs inserted */
606
                int maxsack = (MAX_TCPOPTLEN - (optlen + 4))/TCPOLEN_SACK;
607
 
608
                maxsack = min(maxsack, TCP_MAX_SACK);
609
                for (i = 0; (i < tp->rcv_numsacks && count < maxsack); i++) {
610
                        struct sackblk sack = tp->sackblks[i];
611
                        if (sack.start == 0 && sack.end == 0)
612
                                continue;
613
                        *lp++ = htonl(sack.start);
614
                        *lp++ = htonl(sack.end);
615
                        count++;
616
                }
617
                *olp = htonl(TCPOPT_SACK_HDR|(TCPOLEN_SACK*count+2));
618
                optlen += TCPOLEN_SACK*count + 4; /* including leading NOPs */
619
        }
620
#endif /* TCP_SACK */
621
 
622
#ifdef DIAGNOSTIC
623
        if (optlen > MAX_TCPOPTLEN)
624
                panic("tcp_output: options too long");
625
#endif /* DIAGNOSTIC */
626
 
627
        hdrlen += optlen;
628
 
629
        /*
630
         * Adjust data length if insertion of options will
631
         * bump the packet length beyond the t_maxopd length.
632
         */
633
        if (len > tp->t_maxopd - optlen) {
634
                len = tp->t_maxopd - optlen;
635
                sendalot = 1;
636
                flags &= ~TH_FIN;
637
         }
638
 
639
#ifdef DIAGNOSTIC
640
        if (max_linkhdr + hdrlen > MCLBYTES)
641
                panic("tcphdr too big");
642
#endif
643
 
644
        /*
645
         * Grab a header mbuf, attaching a copy of data to
646
         * be transmitted, and initialize the header from
647
         * the template for sends on this connection.
648
         */
649
        if (len) {
650
                if (tp->t_force && len == 1)
651
                        tcpstat.tcps_sndprobe++;
652
                else if (SEQ_LT(tp->snd_nxt, tp->snd_max)) {
653
                        tcpstat.tcps_sndrexmitpack++;
654
                        tcpstat.tcps_sndrexmitbyte += len;
655
                } else {
656
                        tcpstat.tcps_sndpack++;
657
                        tcpstat.tcps_sndbyte += len;
658
                }
659
#ifdef notyet
660
                if ((m = m_copypack(so->so_snd.sb_mb, off,
661
                    (int)len, max_linkhdr + hdrlen)) == 0) {
662
                        error = ENOBUFS;
663
                        goto out;
664
                }
665
                /*
666
                 * m_copypack left space for our hdr; use it.
667
                 */
668
                m->m_len += hdrlen;
669
                m->m_data -= hdrlen;
670
#else
671
                MGETHDR(m, M_DONTWAIT, MT_HEADER);
672
                if (m != NULL) {
673
                        MCLGET(m, M_DONTWAIT);
674
                        if ((m->m_flags & M_EXT) == 0) {
675
                                m_freem(m);
676
                                m = NULL;
677
                        }
678
                }
679
                if (m == NULL) {
680
                        error = ENOBUFS;
681
                        goto out;
682
                }
683
                m->m_data += max_linkhdr;
684
                m->m_len = hdrlen;
685
                if (len <= MCLBYTES - hdrlen - max_linkhdr) {
686
                        m_copydata(so->so_snd.sb_mb, off, (int) len,
687
                            mtod(m, caddr_t) + hdrlen);
688
                        m->m_len += len;
689
                } else {
690
                        m->m_next = m_copy(so->so_snd.sb_mb, off, (int) len);
691
                        if (m->m_next == 0) {
692
                                (void) m_free(m);
693
                                error = ENOBUFS;
694
                                goto out;
695
                        }
696
                }
697
#endif
698
                /*
699
                 * If we're sending everything we've got, set PUSH.
700
                 * (This will keep happy those implementations which only
701
                 * give data to the user when a buffer fills or
702
                 * a PUSH comes in.)
703
                 */
704
                if (off + len == so->so_snd.sb_cc)
705
                        flags |= TH_PUSH;
706
        } else {
707
                if (tp->t_flags & TF_ACKNOW)
708
                        tcpstat.tcps_sndacks++;
709
                else if (flags & (TH_SYN|TH_FIN|TH_RST))
710
                        tcpstat.tcps_sndctrl++;
711
                else if (SEQ_GT(tp->snd_up, tp->snd_una))
712
                        tcpstat.tcps_sndurg++;
713
                else
714
                        tcpstat.tcps_sndwinup++;
715
 
716
                MGETHDR(m, M_DONTWAIT, MT_HEADER);
717
                if (m != NULL) {
718
                        MCLGET(m, M_DONTWAIT);
719
                        if ((m->m_flags & M_EXT) == 0) {
720
                                m_freem(m);
721
                                m = NULL;
722
                        }
723
                }
724
                if (m == NULL) {
725
                        error = ENOBUFS;
726
                        goto out;
727
                }
728
                m->m_data += max_linkhdr;
729
                m->m_len = hdrlen;
730
        }
731
        m->m_pkthdr.rcvif = (struct ifnet *)0;
732
 
733
        if (!tp->t_template)
734
                panic("tcp_output");
735
#ifdef DIAGNOSTIC
736
        if (tp->t_template->m_len != hdrlen - optlen)
737
                panic("tcp_output: template len != hdrlen - optlen");
738
#endif /* DIAGNOSTIC */
739
        bcopy(mtod(tp->t_template, caddr_t), mtod(m, caddr_t),
740
                tp->t_template->m_len);
741
        th = (struct tcphdr *)(mtod(m, caddr_t) + tp->t_template->m_len -
742
                sizeof(struct tcphdr));
743
 
744
        /*
745
         * Fill in fields, remembering maximum advertised
746
         * window for use in delaying messages about window sizes.
747
         * If resending a FIN, be sure not to use a new sequence number.
748
         */
749
        if ((flags & TH_FIN) && (tp->t_flags & TF_SENTFIN) &&
750
            (tp->snd_nxt == tp->snd_max))
751
                tp->snd_nxt--;
752
        /*
753
         * If we are doing retransmissions, then snd_nxt will
754
         * not reflect the first unsent octet.  For ACK only
755
         * packets, we do not want the sequence number of the
756
         * retransmitted packet, we want the sequence number
757
         * of the next unsent octet.  So, if there is no data
758
         * (and no SYN or FIN), use snd_max instead of snd_nxt
759
         * when filling in ti_seq.  But if we are in persist
760
         * state, snd_max might reflect one byte beyond the
761
         * right edge of the window, so use snd_nxt in that
762
         * case, since we know we aren't doing a retransmission.
763
         * (retransmit and persist are mutually exclusive...)
764
         */
765
        if (len || (flags & (TH_SYN|TH_FIN)) || tp->t_timer[TCPT_PERSIST])
766
                th->th_seq = htonl(tp->snd_nxt);
767
        else
768
                th->th_seq = htonl(tp->snd_max);
769
 
770
#ifdef TCP_SACK
771
        if (sack_rxmit) {
772
                /*
773
                 * If sendalot was turned on (due to option stuffing), turn it
774
                 * off. Properly set th_seq field.  Advance the ret'x pointer
775
                 * by len.
776
                 */
777
                if (sendalot)
778
                        sendalot = 0;
779
                th->th_seq = htonl(p->rxmit);
780
                p->rxmit += len;
781
#if defined(TCP_SACK) && defined(TCP_FACK)
782
                tp->retran_data += len;
783
#endif /* TCP_FACK */
784
        }
785
#endif /* TCP_SACK */
786
 
787
        th->th_ack = htonl(tp->rcv_nxt);
788
        if (optlen) {
789
                bcopy((caddr_t)opt, (caddr_t)(th + 1), optlen);
790
                th->th_off = (sizeof (struct tcphdr) + optlen) >> 2;
791
        }
792
        th->th_flags = flags;
793
 
794
        /*
795
         * Calculate receive window.  Don't shrink window,
796
         * but avoid silly window syndrome.
797
         */
798
        if (win < (long)(so->so_rcv.sb_hiwat / 4) && win < (long)tp->t_maxseg)
799
                win = 0;
800
        if (win > (long)TCP_MAXWIN << tp->rcv_scale)
801
                win = (long)TCP_MAXWIN << tp->rcv_scale;
802
        if (win < (long)(tp->rcv_adv - tp->rcv_nxt))
803
                win = (long)(tp->rcv_adv - tp->rcv_nxt);
804
        if (flags & TH_RST)
805
                win = 0;
806
        th->th_win = htons((u_int16_t) (win>>tp->rcv_scale));
807
        if (SEQ_GT(tp->snd_up, tp->snd_nxt)) {
808
                u_int32_t urp = tp->snd_up - tp->snd_nxt;
809
                if (urp > IP_MAXPACKET)
810
                        urp = IP_MAXPACKET;
811
                th->th_urp = htons((u_int16_t)urp);
812
                th->th_flags |= TH_URG;
813
        } else
814
                /*
815
                 * If no urgent pointer to send, then we pull
816
                 * the urgent pointer to the left edge of the send window
817
                 * so that it doesn't drift into the send window on sequence
818
                 * number wraparound.
819
                 */
820
                tp->snd_up = tp->snd_una;               /* drag it along */
821
 
822
        /* Put TCP length in pseudo-header */
823
        switch (tp->pf) {
824
        case 0:  /*default to PF_INET*/
825
#ifdef INET
826
        case AF_INET:
827
                if (len + optlen)
828
                        mtod(m, struct ipovly *)->ih_len = htons((u_int16_t)(
829
                                sizeof (struct tcphdr) + optlen + len));
830
                break;
831
#endif /* INET */
832
#ifdef INET6
833
        case AF_INET6:
834
                break;
835
#endif /* INET6 */
836
        }
837
 
838
#ifdef TCP_SIGNATURE
839
        if (tp->t_flags & TF_SIGNATURE) {
840
                MD5_CTX ctx;
841
                union sockaddr_union sa;
842
                struct tdb *tdb;
843
 
844
                memset(&sa, 0, sizeof(union sockaddr_union));
845
 
846
                switch (tp->pf) {
847
                case 0:  /*default to PF_INET*/
848
#ifdef INET
849
                case AF_INET:
850
                        sa.sa.sa_len = sizeof(struct sockaddr_in);
851
                        sa.sa.sa_family = AF_INET;
852
                        sa.sin.sin_addr = mtod(m, struct ip *)->ip_dst;
853
                        break;
854
#endif /* INET */
855
#ifdef INET6
856
                case AF_INET6:
857
                        sa.sa.sa_len = sizeof(struct sockaddr_in6);
858
                        sa.sa.sa_family = AF_INET6;
859
                        sa.sin6.sin6_addr = mtod(m, struct ip6_hdr *)->ip6_dst;
860
                        break;
861
#endif /* INET6 */
862
                }
863
 
864
                /* XXX gettdb() should really be called at spltdb().      */
865
                /* XXX this is splsoftnet(), currently they are the same. */
866
                tdb = gettdb(0, &sa, IPPROTO_TCP);
867
                if (tdb == NULL)
868
                        return (EPERM);
869
 
870
                MD5Init(&ctx);
871
 
872
                switch (tp->pf) {
873
                case 0:  /*default to PF_INET*/
874
#ifdef INET
875
                case AF_INET:
876
                        {
877
                                struct ippseudo ippseudo;
878
                                struct ipovly *ipovly;
879
 
880
                                ipovly = mtod(m, struct ipovly *);
881
 
882
                                ippseudo.ippseudo_src = ipovly->ih_src;
883
                                ippseudo.ippseudo_dst = ipovly->ih_dst;
884
                                ippseudo.ippseudo_pad = 0;
885
                                ippseudo.ippseudo_p   = IPPROTO_TCP;
886
                                ippseudo.ippseudo_len = ipovly->ih_len;
887
                                MD5Update(&ctx, (char *)&ippseudo,
888
                                        sizeof(struct ippseudo));
889
                                MD5Update(&ctx, mtod(m, caddr_t) +
890
                                        sizeof(struct ip),
891
                                        sizeof(struct tcphdr));
892
                        }
893
                        break;
894
#endif /* INET */
895
#ifdef INET6
896
                case AF_INET6:
897
                        {
898
                                static int printed = 0;
899
 
900
                                if (!printed) {
901
                                        printf("error: TCP MD5 support for "
902
                                                "IPv6 not yet implemented.\n");
903
                                        printed = 1;
904
                                }
905
                        }
906
                        break;
907
#endif /* INET6 */
908
                }
909
 
910
                if (len && m_apply(m, hdrlen, len, tcp_signature_apply,
911
                                (caddr_t)&ctx))
912
                        return (EINVAL);
913
 
914
                MD5Update(&ctx, tdb->tdb_amxkey, tdb->tdb_amxkeylen);
915
                MD5Final(mtod(m, caddr_t) + hdrlen - optlen + sigoff, &ctx);
916
        }
917
#endif /* TCP_SIGNATURE */
918
 
919
        /*
920
         * Put TCP length in extended header, and then
921
         * checksum extended header and data.
922
         */
923
        switch (tp->pf) {
924
        case 0:  /*default to PF_INET*/
925
#ifdef INET
926
        case AF_INET:
927
                th->th_sum = in_cksum(m, (int)(hdrlen + len));
928
                break;
929
#endif /* INET */
930
#ifdef INET6
931
        case AF_INET6:
932
                m->m_pkthdr.len = hdrlen + len;
933
                th->th_sum = in6_cksum(m, IPPROTO_TCP, sizeof(struct ip6_hdr),
934
                        hdrlen - sizeof(struct ip6_hdr) + len);
935
                break;
936
#endif /* INET6 */
937
        }
938
 
939
        /*
940
         * In transmit state, time the transmission and arrange for
941
         * the retransmit.  In persist state, just set snd_max.
942
         */
943
        if (tp->t_force == 0 || tp->t_timer[TCPT_PERSIST] == 0) {
944
                tcp_seq startseq = tp->snd_nxt;
945
 
946
                /*
947
                 * Advance snd_nxt over sequence space of this segment.
948
                 */
949
                if (flags & (TH_SYN|TH_FIN)) {
950
                        if (flags & TH_SYN)
951
                                tp->snd_nxt++;
952
                        if (flags & TH_FIN) {
953
                                tp->snd_nxt++;
954
                                tp->t_flags |= TF_SENTFIN;
955
                        }
956
                }
957
#ifdef TCP_SACK
958
                if (!tp->sack_disable) {
959
                        if (sack_rxmit && (p->rxmit != tp->snd_nxt)) {
960
                                goto timer;
961
                        }
962
                }
963
#endif
964
                tp->snd_nxt += len;
965
                if (SEQ_GT(tp->snd_nxt, tp->snd_max)) {
966
                        tp->snd_max = tp->snd_nxt;
967
                        /*
968
                         * Time this transmission if not a retransmission and
969
                         * not currently timing anything.
970
                         */
971
                        if (tp->t_rtt == 0) {
972
                                tp->t_rtt = 1;
973
                                tp->t_rtseq = startseq;
974
                                tcpstat.tcps_segstimed++;
975
                        }
976
                }
977
 
978
                /*
979
                 * Set retransmit timer if not currently set,
980
                 * and not doing an ack or a keep-alive probe.
981
                 * Initial value for retransmit timer is smoothed
982
                 * round-trip time + 2 * round-trip time variance.
983
                 * Initialize shift counter which is used for backoff
984
                 * of retransmit time.
985
                 */
986
#ifdef TCP_SACK
987
 timer:
988
                if (!tp->sack_disable && sack_rxmit &&
989
                    tp->t_timer[TCPT_REXMT] == 0 &&
990
                    tp->snd_nxt != tp->snd_max) {
991
                        tp->t_timer[TCPT_REXMT] = tp->t_rxtcur;
992
                        if (tp->t_timer[TCPT_PERSIST]) {
993
                                tp->t_timer[TCPT_PERSIST] = 0;
994
                                tp->t_rxtshift = 0;
995
                        }
996
                }
997
#endif
998
 
999
                if (tp->t_timer[TCPT_REXMT] == 0 &&
1000
                    tp->snd_nxt != tp->snd_una) {
1001
                        tp->t_timer[TCPT_REXMT] = tp->t_rxtcur;
1002
                        if (tp->t_timer[TCPT_PERSIST]) {
1003
                                tp->t_timer[TCPT_PERSIST] = 0;
1004
                                tp->t_rxtshift = 0;
1005
                        }
1006
                }
1007
        } else
1008
                if (SEQ_GT(tp->snd_nxt + len, tp->snd_max))
1009
                        tp->snd_max = tp->snd_nxt + len;
1010
 
1011
        /*
1012
         * Trace.
1013
         */
1014
#ifdef TCPDEBUG
1015
        if (so->so_options & SO_DEBUG)
1016
                tcp_trace(TA_OUTPUT, tp->t_state, tp, mtod(m, caddr_t), 0,
1017
                        len);
1018
#endif /* TCPDEBUG */
1019
 
1020
        /*
1021
         * Fill in IP length and desired time to live and
1022
         * send to IP level.  There should be a better way
1023
         * to handle ttl and tos; we could keep them in
1024
         * the template, but need a way to checksum without them.
1025
         */
1026
        m->m_pkthdr.len = hdrlen + len;
1027
 
1028
        switch (tp->pf) {
1029
        case 0:  /*default to PF_INET*/
1030
#ifdef INET
1031
        case AF_INET:
1032
                {
1033
                        struct ip *ip;
1034
 
1035
                        ip = mtod(m, struct ip *);
1036
                        ip->ip_len = m->m_pkthdr.len;
1037
                        ip->ip_ttl = tp->t_inpcb->inp_ip.ip_ttl;
1038
                        ip->ip_tos = tp->t_inpcb->inp_ip.ip_tos;
1039
                }
1040
                error = ip_output(m, tp->t_inpcb->inp_options,
1041
                        &tp->t_inpcb->inp_route, so->so_options & SO_DONTROUTE,
1042
                        0, tp->t_inpcb);
1043
                break;
1044
#endif /* INET */
1045
#ifdef INET6
1046
        case AF_INET6:
1047
                {
1048
                        struct ip6_hdr *ipv6;
1049
 
1050
                        ipv6 = mtod(m, struct ip6_hdr *);
1051
                        ipv6->ip6_plen = m->m_pkthdr.len -
1052
                                sizeof(struct ip6_hdr);
1053
                        ipv6->ip6_nxt = IPPROTO_TCP;
1054
                        ipv6->ip6_hlim = in6_selecthlim(tp->t_inpcb, NULL);
1055
                }
1056
                error = ip6_output(m, tp->t_inpcb->inp_outputopts6,
1057
                          &tp->t_inpcb->inp_route6,
1058
                          (so->so_options & SO_DONTROUTE), NULL, NULL);
1059
                break;
1060
#endif /* INET6 */
1061
#ifdef TUBA
1062
        case AF_ISO:
1063
                if (tp->t_tuba_pcb)
1064
                        error = tuba_output(m, tp);
1065
                break;
1066
#endif /* TUBA */
1067
        }
1068
 
1069
#if defined(TCP_SACK) && defined(TCP_FACK)
1070
        /* Update snd_awnd to reflect the new data that was sent.  */
1071
        tp->snd_awnd = tcp_seq_subtract(tp->snd_max, tp->snd_fack) +
1072
                tp->retran_data;
1073
#endif /* defined(TCP_SACK) && defined(TCP_FACK) */
1074
 
1075
        if (error) {
1076
out:
1077
                if (error == ENOBUFS) {
1078
                        tcp_quench(tp->t_inpcb, 0);
1079
                        return (0);
1080
                }
1081
                if ((error == EHOSTUNREACH || error == ENETDOWN)
1082
                    && TCPS_HAVERCVDSYN(tp->t_state)) {
1083
                        tp->t_softerror = error;
1084
                        return (0);
1085
                }
1086
                return (error);
1087
        }
1088
        tcpstat.tcps_sndtotal++;
1089
 
1090
        /*
1091
         * Data sent (as far as we can tell).
1092
         * If this advertises a larger window than any other segment,
1093
         * then remember the size of the advertised window.
1094
         * Any pending ACK has now been sent.
1095
         */
1096
        if (win > 0 && SEQ_GT(tp->rcv_nxt+win, tp->rcv_adv))
1097
                tp->rcv_adv = tp->rcv_nxt + win;
1098
        tp->last_ack_sent = tp->rcv_nxt;
1099
        tp->t_flags &= ~(TF_ACKNOW|TF_DELACK);
1100
#if defined(TCP_SACK) || defined(TCP_NEWRENO)
1101
        if (sendalot && --maxburst)
1102
#else
1103
        if (sendalot)
1104
#endif
1105
                goto again;
1106
        return (0);
1107
}
1108
 
1109
void
1110
tcp_setpersist(tp)
1111
        register struct tcpcb *tp;
1112
{
1113
        register int t = ((tp->t_srtt >> 2) + tp->t_rttvar) >> 1;
1114
 
1115
        if (tp->t_timer[TCPT_REXMT])
1116
                panic("tcp_output REXMT");
1117
        /*
1118
         * Start/restart persistance timer.
1119
         */
1120
        if (t < tp->t_rttmin)
1121
                t = tp->t_rttmin;
1122
        TCPT_RANGESET(tp->t_timer[TCPT_PERSIST],
1123
            t * tcp_backoff[tp->t_rxtshift],
1124
            TCPTV_PERSMIN, TCPTV_PERSMAX);
1125
        if (tp->t_rxtshift < TCP_MAXRXTSHIFT)
1126
                tp->t_rxtshift++;
1127
}

powered by: WebSVN 2.1.0

© copyright 1999-2025 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.