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

Subversion Repositories or1k

[/] [or1k/] [trunk/] [linux/] [linux-2.4/] [net/] [sctp/] [output.c] - Blame information for rev 1765

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1275 phoenix
/* SCTP kernel reference Implementation
2
 * (C) Copyright IBM Corp. 2001, 2004
3
 * Copyright (c) 1999-2000 Cisco, Inc.
4
 * Copyright (c) 1999-2001 Motorola, Inc.
5
 *
6
 * This file is part of the SCTP kernel reference Implementation
7
 *
8
 * These functions handle output processing.
9
 *
10
 * The SCTP reference implementation is free software;
11
 * you can redistribute it and/or modify it under the terms of
12
 * the GNU General Public License as published by
13
 * the Free Software Foundation; either version 2, or (at your option)
14
 * any later version.
15
 *
16
 * The SCTP reference implementation is distributed in the hope that it
17
 * will be useful, but WITHOUT ANY WARRANTY; without even the implied
18
 *                 ************************
19
 * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
20
 * See the GNU General Public License for more details.
21
 *
22
 * You should have received a copy of the GNU General Public License
23
 * along with GNU CC; see the file COPYING.  If not, write to
24
 * the Free Software Foundation, 59 Temple Place - Suite 330,
25
 * Boston, MA 02111-1307, USA.
26
 *
27
 * Please send any bug reports or fixes you make to the
28
 * email address(es):
29
 *    lksctp developers <lksctp-developers@lists.sourceforge.net>
30
 *
31
 * Or submit a bug report through the following website:
32
 *    http://www.sf.net/projects/lksctp
33
 *
34
 * Written or modified by:
35
 *    La Monte H.P. Yarroll <piggy@acm.org>
36
 *    Karl Knutson          <karl@athena.chicago.il.us>
37
 *    Jon Grimm             <jgrimm@austin.ibm.com>
38
 *    Sridhar Samudrala     <sri@us.ibm.com>
39
 *
40
 * Any bugs reported given to us we will try to fix... any fixes shared will
41
 * be incorporated into the next SCTP release.
42
 */
43
 
44
#include <linux/types.h>
45
#include <linux/kernel.h>
46
#include <linux/wait.h>
47
#include <linux/time.h>
48
#include <linux/ip.h>
49
#include <linux/ipv6.h>
50
#include <linux/init.h>
51
#include <net/inet_ecn.h>
52
#include <net/icmp.h>
53
 
54
#ifndef TEST_FRAME
55
#include <net/tcp.h>
56
#endif /* TEST_FRAME (not defined) */
57
 
58
#include <linux/socket.h> /* for sa_family_t */
59
#include <net/sock.h>
60
 
61
#include <net/sctp/sctp.h>
62
#include <net/sctp/sm.h>
63
 
64
/* Forward declarations for private helpers. */
65
static void sctp_packet_reset(struct sctp_packet *packet);
66
static sctp_xmit_t sctp_packet_append_data(struct sctp_packet *packet,
67
                                           struct sctp_chunk *chunk);
68
 
69
/* Config a packet.
70
 * This appears to be a followup set of initializations.)
71
 */
72
struct sctp_packet *sctp_packet_config(struct sctp_packet *packet,
73
                                       __u32 vtag, int ecn_capable,
74
                                       sctp_packet_phandler_t *prepend_handler)
75
{
76
        int packet_empty = (packet->size == SCTP_IP_OVERHEAD);
77
 
78
        packet->vtag = vtag;
79
        packet->ecn_capable = ecn_capable;
80
        packet->get_prepend_chunk = prepend_handler;
81
        packet->has_cookie_echo = 0;
82
        packet->has_sack = 0;
83
        packet->ipfragok = 0;
84
 
85
        /* We might need to call the prepend_handler right away.  */
86
        if (packet_empty)
87
                sctp_packet_reset(packet);
88
        return packet;
89
}
90
 
91
/* Initialize the packet structure. */
92
struct sctp_packet *sctp_packet_init(struct sctp_packet *packet,
93
                                     struct sctp_transport *transport,
94
                                     __u16 sport, __u16 dport)
95
{
96
        packet->transport = transport;
97
        packet->source_port = sport;
98
        packet->destination_port = dport;
99
        skb_queue_head_init(&packet->chunks);
100
        packet->size = SCTP_IP_OVERHEAD;
101
        packet->vtag = 0;
102
        packet->ecn_capable = 0;
103
        packet->get_prepend_chunk = NULL;
104
        packet->has_cookie_echo = 0;
105
        packet->has_sack = 0;
106
        packet->ipfragok = 0;
107
        packet->malloced = 0;
108
        sctp_packet_reset(packet);
109
        return packet;
110
}
111
 
112
/* Free a packet.  */
113
void sctp_packet_free(struct sctp_packet *packet)
114
{
115
        struct sctp_chunk *chunk;
116
 
117
        while ((chunk = (struct sctp_chunk *)__skb_dequeue(&packet->chunks)))
118
                sctp_chunk_free(chunk);
119
 
120
        if (packet->malloced)
121
                kfree(packet);
122
}
123
 
124
/* This routine tries to append the chunk to the offered packet. If adding
125
 * the chunk causes the packet to exceed the path MTU and COOKIE_ECHO chunk
126
 * is not present in the packet, it transmits the input packet.
127
 * Data can be bundled with a packet containing a COOKIE_ECHO chunk as long
128
 * as it can fit in the packet, but any more data that does not fit in this
129
 * packet can be sent only after receiving the COOKIE_ACK.
130
 */
131
sctp_xmit_t sctp_packet_transmit_chunk(struct sctp_packet *packet,
132
                                       struct sctp_chunk *chunk)
133
{
134
        sctp_xmit_t retval;
135
        int error = 0;
136
 
137
        switch ((retval = (sctp_packet_append_chunk(packet, chunk)))) {
138
        case SCTP_XMIT_PMTU_FULL:
139
                if (!packet->has_cookie_echo) {
140
                        error = sctp_packet_transmit(packet);
141
                        if (error < 0)
142
                                chunk->skb->sk->sk_err = -error;
143
 
144
                        /* If we have an empty packet, then we can NOT ever
145
                         * return PMTU_FULL.
146
                         */
147
                        retval = sctp_packet_append_chunk(packet, chunk);
148
                }
149
                break;
150
 
151
        case SCTP_XMIT_MUST_FRAG:
152
        case SCTP_XMIT_RWND_FULL:
153
        case SCTP_XMIT_OK:
154
        case SCTP_XMIT_NAGLE_DELAY:
155
                break;
156
        };
157
 
158
        return retval;
159
}
160
 
161
/* Try to bundle a SACK with the packet. */
162
static sctp_xmit_t sctp_packet_bundle_sack(struct sctp_packet *pkt,
163
                                           struct sctp_chunk *chunk)
164
{
165
        sctp_xmit_t retval = SCTP_XMIT_OK;
166
 
167
        /* If sending DATA and haven't aleady bundled a SACK, try to
168
         * bundle one in to the packet.
169
         */
170
        if (sctp_chunk_is_data(chunk) && !pkt->has_sack &&
171
            !pkt->has_cookie_echo) {
172
                struct sctp_association *asoc;
173
                asoc = pkt->transport->asoc;
174
 
175
                if (asoc->a_rwnd > asoc->rwnd) {
176
                        struct sctp_chunk *sack;
177
                        asoc->a_rwnd = asoc->rwnd;
178
                        sack = sctp_make_sack(asoc);
179
                        if (sack) {
180
                                struct timer_list *timer;
181
                                retval = sctp_packet_append_chunk(pkt, sack);
182
                                asoc->peer.sack_needed = 0;
183
                                timer = &asoc->timers[SCTP_EVENT_TIMEOUT_SACK];
184
                                if (timer_pending(timer) && del_timer(timer))
185
                                        sctp_association_put(asoc);
186
                        }
187
                }
188
        }
189
        return retval;
190
}
191
 
192
/* Append a chunk to the offered packet reporting back any inability to do
193
 * so.
194
 */
195
sctp_xmit_t sctp_packet_append_chunk(struct sctp_packet *packet,
196
                                     struct sctp_chunk *chunk)
197
{
198
        sctp_xmit_t retval = SCTP_XMIT_OK;
199
        __u16 chunk_len = WORD_ROUND(ntohs(chunk->chunk_hdr->length));
200
        size_t psize;
201
        size_t pmtu;
202
        int too_big;
203
 
204
        retval = sctp_packet_bundle_sack(packet, chunk);
205
        psize = packet->size;
206
 
207
        if (retval != SCTP_XMIT_OK)
208
                goto finish;
209
 
210
        pmtu  = ((packet->transport->asoc) ?
211
                 (packet->transport->asoc->pmtu) :
212
                 (packet->transport->pmtu));
213
 
214
        too_big = (psize + chunk_len > pmtu);
215
 
216
        /* Decide if we need to fragment or resubmit later. */
217
        if (too_big) {
218
                int packet_empty = (packet->size == SCTP_IP_OVERHEAD);
219
 
220
                /* Both control chunks and data chunks with TSNs are
221
                 * non-fragmentable.
222
                 */
223
                if (packet_empty || !sctp_chunk_is_data(chunk)) {
224
                        /* We no longer do re-fragmentation.
225
                         * Just fragment at the IP layer, if we
226
                         * actually hit this condition
227
                         */
228
 
229
                        packet->ipfragok = 1;
230
                        goto append;
231
 
232
                } else {
233
                        retval = SCTP_XMIT_PMTU_FULL;
234
                        goto finish;
235
                }
236
        } else {
237
                /* The chunk fits in the packet.  */
238
                goto append;
239
        }
240
 
241
append:
242
        /* We believe that this chunk is OK to add to the packet (as
243
         * long as we have the cwnd for it).
244
         */
245
 
246
        /* DATA is a special case since we must examine both rwnd and cwnd
247
         * before we send DATA.
248
         */
249
        if (sctp_chunk_is_data(chunk)) {
250
                retval = sctp_packet_append_data(packet, chunk);
251
                /* Disallow SACK bundling after DATA. */
252
                packet->has_sack = 1;
253
                if (SCTP_XMIT_OK != retval)
254
                        goto finish;
255
        } else if (SCTP_CID_COOKIE_ECHO == chunk->chunk_hdr->type)
256
                packet->has_cookie_echo = 1;
257
        else if (SCTP_CID_SACK == chunk->chunk_hdr->type)
258
                packet->has_sack = 1;
259
 
260
        /* It is OK to send this chunk.  */
261
        __skb_queue_tail(&packet->chunks, (struct sk_buff *)chunk);
262
        packet->size += chunk_len;
263
finish:
264
        return retval;
265
}
266
 
267
/* All packets are sent to the network through this function from
268
 * sctp_outq_tail().
269
 *
270
 * The return value is a normal kernel error return value.
271
 */
272
int sctp_packet_transmit(struct sctp_packet *packet)
273
{
274
        struct sctp_transport *tp = packet->transport;
275
        struct sctp_association *asoc = tp->asoc;
276
        struct sctphdr *sh;
277
        __u32 crc32;
278
        struct sk_buff *nskb;
279
        struct sctp_chunk *chunk;
280
        struct sock *sk;
281
        int err = 0;
282
        int padding;            /* How much padding do we need?  */
283
        __u8 has_data = 0;
284
        struct dst_entry *dst;
285
 
286
        /* Do NOT generate a chunkless packet. */
287
        chunk = (struct sctp_chunk *)skb_peek(&packet->chunks);
288
        if (unlikely(!chunk))
289
                return err;
290
 
291
        /* Set up convenience variables... */
292
        sk = chunk->skb->sk;
293
 
294
        /* Allocate the new skb.  */
295
        nskb = dev_alloc_skb(packet->size);
296
        if (!nskb)
297
                goto nomem;
298
 
299
        /* Make sure the outbound skb has enough header room reserved. */
300
        skb_reserve(nskb, SCTP_IP_OVERHEAD);
301
 
302
        /* Set the owning socket so that we know where to get the
303
         * destination IP address.
304
         */
305
        skb_set_owner_w(nskb, sk);
306
 
307
        /* Build the SCTP header.  */
308
        sh = (struct sctphdr *)skb_push(nskb, sizeof(struct sctphdr));
309
        sh->source = htons(packet->source_port);
310
        sh->dest   = htons(packet->destination_port);
311
 
312
        /* From 6.8 Adler-32 Checksum Calculation:
313
         * After the packet is constructed (containing the SCTP common
314
         * header and one or more control or DATA chunks), the
315
         * transmitter shall:
316
         *
317
         * 1) Fill in the proper Verification Tag in the SCTP common
318
         *    header and initialize the checksum field to 0's.
319
         */
320
        sh->vtag     = htonl(packet->vtag);
321
        sh->checksum = 0;
322
 
323
        /* 2) Calculate the Adler-32 checksum of the whole packet,
324
         *    including the SCTP common header and all the
325
         *    chunks.
326
         *
327
         * Note: Adler-32 is no longer applicable, as has been replaced
328
         * by CRC32-C as described in <draft-ietf-tsvwg-sctpcsum-02.txt>.
329
         */
330
        crc32 = sctp_start_cksum((__u8 *)sh, sizeof(struct sctphdr));
331
 
332
        /**
333
         * 6.10 Bundling
334
         *
335
         *    An endpoint bundles chunks by simply including multiple
336
         *    chunks in one outbound SCTP packet.  ...
337
         */
338
 
339
        /**
340
         * 3.2  Chunk Field Descriptions
341
         *
342
         * The total length of a chunk (including Type, Length and
343
         * Value fields) MUST be a multiple of 4 bytes.  If the length
344
         * of the chunk is not a multiple of 4 bytes, the sender MUST
345
         * pad the chunk with all zero bytes and this padding is not
346
         * included in the chunk length field.  The sender should
347
         * never pad with more than 3 bytes.
348
         *
349
         * [This whole comment explains WORD_ROUND() below.]
350
         */
351
        SCTP_DEBUG_PRINTK("***sctp_transmit_packet***\n");
352
        while ((chunk = (struct sctp_chunk *)__skb_dequeue(&packet->chunks))) {
353
                if (sctp_chunk_is_data(chunk)) {
354
 
355
                        if (!chunk->has_tsn) {
356
                                sctp_chunk_assign_ssn(chunk);
357
                                sctp_chunk_assign_tsn(chunk);
358
 
359
                        /* 6.3.1 C4) When data is in flight and when allowed
360
                         * by rule C5, a new RTT measurement MUST be made each
361
                         * round trip.  Furthermore, new RTT measurements
362
                         * SHOULD be made no more than once per round-trip
363
                         * for a given destination transport address.
364
                         */
365
 
366
                                if (!tp->rto_pending) {
367
                                        chunk->rtt_in_progress = 1;
368
                                        tp->rto_pending = 1;
369
                                }
370
                        } else
371
                                chunk->resent = 1;
372
 
373
                        chunk->sent_at = jiffies;
374
                        has_data = 1;
375
                }
376
 
377
                padding = WORD_ROUND(chunk->skb->len) - chunk->skb->len;
378
                if (padding)
379
                        memset(skb_put(chunk->skb, padding), 0, padding);
380
 
381
                crc32 = sctp_update_copy_cksum(skb_put(nskb, chunk->skb->len),
382
                                               chunk->skb->data,
383
                                               chunk->skb->len, crc32);
384
 
385
                SCTP_DEBUG_PRINTK("%s %p[%s] %s 0x%x, %s %d, %s %d, %s %d\n",
386
                                  "*** Chunk", chunk,
387
                                  sctp_cname(SCTP_ST_CHUNK(
388
                                          chunk->chunk_hdr->type)),
389
                                  chunk->has_tsn ? "TSN" : "No TSN",
390
                                  chunk->has_tsn ?
391
                                  ntohl(chunk->subh.data_hdr->tsn) : 0,
392
                                  "length", ntohs(chunk->chunk_hdr->length),
393
                                  "chunk->skb->len", chunk->skb->len,
394
                                  "rtt_in_progress", chunk->rtt_in_progress);
395
 
396
                /*
397
                 * If this is a control chunk, this is our last
398
                 * reference. Free data chunks after they've been
399
                 * acknowledged or have failed.
400
                 */
401
                if (!sctp_chunk_is_data(chunk))
402
                        sctp_chunk_free(chunk);
403
        }
404
 
405
        /* Perform final transformation on checksum. */
406
        crc32 = sctp_end_cksum(crc32);
407
 
408
        /* 3) Put the resultant value into the checksum field in the
409
         *    common header, and leave the rest of the bits unchanged.
410
         */
411
        sh->checksum = htonl(crc32);
412
 
413
        /* IP layer ECN support
414
         * From RFC 2481
415
         *  "The ECN-Capable Transport (ECT) bit would be set by the
416
         *   data sender to indicate that the end-points of the
417
         *   transport protocol are ECN-capable."
418
         *
419
         * Now setting the ECT bit all the time, as it should not cause
420
         * any problems protocol-wise even if our peer ignores it.
421
         *
422
         * Note: The works for IPv6 layer checks this bit too later
423
         * in transmission.  See IP6_ECN_flow_xmit().
424
         */
425
        INET_ECN_xmit(nskb->sk);
426
 
427
        /* Set up the IP options.  */
428
        /* BUG: not implemented
429
         * For v4 this all lives somewhere in sk->sk_opt...
430
         */
431
 
432
        /* Dump that on IP!  */
433
        if (asoc && asoc->peer.last_sent_to != tp) {
434
                /* Considering the multiple CPU scenario, this is a
435
                 * "correcter" place for last_sent_to.  --xguo
436
                 */
437
                asoc->peer.last_sent_to = tp;
438
        }
439
 
440
        if (has_data) {
441
                struct timer_list *timer;
442
                unsigned long timeout;
443
 
444
                tp->last_time_used = jiffies;
445
 
446
                /* Restart the AUTOCLOSE timer when sending data. */
447
                if (sctp_state(asoc, ESTABLISHED) && asoc->autoclose) {
448
                        timer = &asoc->timers[SCTP_EVENT_TIMEOUT_AUTOCLOSE];
449
                        timeout = asoc->timeouts[SCTP_EVENT_TIMEOUT_AUTOCLOSE];
450
 
451
                        if (!mod_timer(timer, jiffies + timeout))
452
                                sctp_association_hold(asoc);
453
                }
454
        }
455
 
456
        dst = tp->dst;
457
        /* The 'obsolete' field of dst is set to 2 when a dst is freed. */
458
        if (!dst || (dst->obsolete > 1)) {
459
                dst_release(dst);
460
                sctp_transport_route(tp, NULL, sctp_sk(sk));
461
                sctp_assoc_sync_pmtu(asoc);
462
        }
463
 
464
        nskb->dst = dst_clone(tp->dst);
465
        if (!nskb->dst)
466
                goto no_route;
467
 
468
        SCTP_DEBUG_PRINTK("***sctp_transmit_packet*** skb len %d\n",
469
                          nskb->len);
470
 
471
        (*tp->af_specific->sctp_xmit)(nskb, tp, packet->ipfragok);
472
 
473
out:
474
        packet->size = SCTP_IP_OVERHEAD;
475
        return err;
476
no_route:
477
        kfree_skb(nskb);
478
        IP_INC_STATS_BH(IpOutNoRoutes);
479
 
480
        /* FIXME: Returning the 'err' will effect all the associations
481
         * associated with a socket, although only one of the paths of the
482
         * association is unreachable.
483
         * The real failure of a transport or association can be passed on
484
         * to the user via notifications. So setting this error may not be
485
         * required.
486
         */
487
         /* err = -EHOSTUNREACH; */
488
err:
489
        /* Control chunks are unreliable so just drop them.  DATA chunks
490
         * will get resent or dropped later.
491
         */
492
 
493
        while ((chunk = (struct sctp_chunk *)__skb_dequeue(&packet->chunks))) {
494
                if (!sctp_chunk_is_data(chunk))
495
                        sctp_chunk_free(chunk);
496
        }
497
        goto out;
498
nomem:
499
        err = -ENOMEM;
500
        printk("%s alloc_skb failed.\n", __FUNCTION__);
501
        goto err;
502
}
503
 
504
/********************************************************************
505
 * 2nd Level Abstractions
506
 ********************************************************************/
507
 
508
/*
509
 * This private function resets the packet to a fresh state.
510
 */
511
static void sctp_packet_reset(struct sctp_packet *packet)
512
{
513
        struct sctp_chunk *chunk = NULL;
514
 
515
        packet->size = SCTP_IP_OVERHEAD;
516
 
517
        if (packet->get_prepend_chunk)
518
                chunk = packet->get_prepend_chunk(packet->transport->asoc);
519
 
520
        /* If there a is a prepend chunk stick it on the list before
521
         * any other chunks get appended.
522
         */
523
        if (chunk)
524
                sctp_packet_append_chunk(packet, chunk);
525
}
526
 
527
/* This private function handles the specifics of appending DATA chunks.  */
528
static sctp_xmit_t sctp_packet_append_data(struct sctp_packet *packet,
529
                                           struct sctp_chunk *chunk)
530
{
531
        sctp_xmit_t retval = SCTP_XMIT_OK;
532
        size_t datasize, rwnd, inflight;
533
        struct sctp_transport *transport = packet->transport;
534
        __u32 max_burst_bytes;
535
        struct sctp_association *asoc = transport->asoc;
536
        struct sctp_opt *sp = sctp_sk(asoc->base.sk);
537
        struct sctp_outq *q = &asoc->outqueue;
538
 
539
        /* RFC 2960 6.1  Transmission of DATA Chunks
540
         *
541
         * A) At any given time, the data sender MUST NOT transmit new data to
542
         * any destination transport address if its peer's rwnd indicates
543
         * that the peer has no buffer space (i.e. rwnd is 0, see Section
544
         * 6.2.1).  However, regardless of the value of rwnd (including if it
545
         * is 0), the data sender can always have one DATA chunk in flight to
546
         * the receiver if allowed by cwnd (see rule B below).  This rule
547
         * allows the sender to probe for a change in rwnd that the sender
548
         * missed due to the SACK having been lost in transit from the data
549
         * receiver to the data sender.
550
         */
551
 
552
        rwnd = asoc->peer.rwnd;
553
        inflight = asoc->outqueue.outstanding_bytes;
554
 
555
        datasize = sctp_data_size(chunk);
556
 
557
        if (datasize > rwnd) {
558
                if (inflight > 0) {
559
                        /* We have (at least) one data chunk in flight,
560
                         * so we can't fall back to rule 6.1 B).
561
                         */
562
                        retval = SCTP_XMIT_RWND_FULL;
563
                        goto finish;
564
                }
565
        }
566
 
567
        /* sctpimpguide-05 2.14.2
568
         * D) When the time comes for the sender to
569
         * transmit new DATA chunks, the protocol parameter Max.Burst MUST
570
         * first be applied to limit how many new DATA chunks may be sent.
571
         * The limit is applied by adjusting cwnd as follows:
572
         *      if ((flightsize + Max.Burst * MTU) < cwnd)
573
         *              cwnd = flightsize + Max.Burst * MTU
574
         */
575
        max_burst_bytes = asoc->max_burst * asoc->pmtu;
576
        if ((transport->flight_size + max_burst_bytes) < transport->cwnd) {
577
                transport->cwnd = transport->flight_size + max_burst_bytes;
578
                SCTP_DEBUG_PRINTK("%s: cwnd limited by max_burst: "
579
                                  "transport: %p, cwnd: %d, "
580
                                  "ssthresh: %d, flight_size: %d, "
581
                                  "pba: %d\n",
582
                                  __FUNCTION__, transport,
583
                                  transport->cwnd,
584
                                  transport->ssthresh,
585
                                  transport->flight_size,
586
                                  transport->partial_bytes_acked);
587
        }
588
 
589
        /* RFC 2960 6.1  Transmission of DATA Chunks
590
         *
591
         * B) At any given time, the sender MUST NOT transmit new data
592
         * to a given transport address if it has cwnd or more bytes
593
         * of data outstanding to that transport address.
594
         */
595
        /* RFC 7.2.4 & the Implementers Guide 2.8.
596
         *
597
         * 3) ...
598
         *    When a Fast Retransmit is being performed the sender SHOULD
599
         *    ignore the value of cwnd and SHOULD NOT delay retransmission.
600
         */
601
        if (!chunk->fast_retransmit)
602
                if (transport->flight_size >= transport->cwnd) {
603
                        retval = SCTP_XMIT_RWND_FULL;
604
                        goto finish;
605
                }
606
 
607
        /* Nagle's algorithm to solve small-packet problem:
608
         * Inhibit the sending of new chunks when new outgoing data arrives
609
         * if any previously transmitted data on the connection remains
610
         * unacknowledged.
611
         */
612
        if (!sp->nodelay && SCTP_IP_OVERHEAD == packet->size &&
613
            q->outstanding_bytes && sctp_state(asoc, ESTABLISHED)) {
614
                unsigned len = datasize + q->out_qlen;
615
 
616
                /* Check whether this chunk and all the rest of pending
617
                 * data will fit or delay in hopes of bundling a full
618
                 * sized packet.
619
                 */
620
                if (len < asoc->pmtu - SCTP_IP_OVERHEAD) {
621
                        retval = SCTP_XMIT_NAGLE_DELAY;
622
                        goto finish;
623
                }
624
        }
625
 
626
        /* Keep track of how many bytes are in flight over this transport. */
627
        transport->flight_size += datasize;
628
 
629
        /* Keep track of how many bytes are in flight to the receiver. */
630
        asoc->outqueue.outstanding_bytes += datasize;
631
 
632
        /* Update our view of the receiver's rwnd. */
633
        if (datasize < rwnd)
634
                rwnd -= datasize;
635
        else
636
                rwnd = 0;
637
 
638
        asoc->peer.rwnd = rwnd;
639
        /* Has been accepted for transmission. */
640
        chunk->msg->can_expire = 0;
641
 
642
finish:
643
        return retval;
644
}

powered by: WebSVN 2.1.0

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