⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 tcp_output.pc

📁 无线自组织网络的一个协议仿真软件
💻 PC
📖 第 1 页 / 共 2 页
字号:
/* * GloMoSim is COPYRIGHTED software.  Release 2.02 of GloMoSim is available  * at no cost to educational users only. * * Commercial use of this software requires a separate license.  No cost, * evaluation licenses are available for such purposes; please contact * info@scalable-networks.com * * By obtaining copies of this and any other files that comprise GloMoSim2.02, * you, the Licensee, agree to abide by the following conditions and * understandings with respect to the copyrighted software: * * 1.Permission to use, copy, and modify this software and its documentation *   for education and non-commercial research purposes only is hereby granted *   to Licensee, provided that the copyright notice, the original author's *   names and unit identification, and this permission notice appear on all *   such copies, and that no charge be made for such copies. Any entity *   desiring permission to use this software for any commercial or *   non-educational research purposes should contact:  * *   Professor Rajive Bagrodia  *   University of California, Los Angeles  *   Department of Computer Science  *   Box 951596  *   3532 Boelter Hall  *   Los Angeles, CA 90095-1596  *   rajive@cs.ucla.edu * * 2.NO REPRESENTATIONS ARE MADE ABOUT THE SUITABILITY OF THE SOFTWARE FOR ANY *   PURPOSE. IT IS PROVIDED "AS IS" WITHOUT EXPRESS OR IMPLIED WARRANTY. * * 3.Neither the software developers, the Parallel Computing Lab, UCLA, or any *   affiliate of the UC system shall be liable for any damages suffered by *   Licensee from the use of this software. */// Use the latest version of Parsec if this line causes a compiler error./* * $Id: tcp_output.pc,v 1.11 1999/09/28 05:26:33 ktang Exp $ * * Ported from FreeBSD 2.2.2. * This file contains TCP output routine and ancillary functions. *//* * Copyright (c) 1982, 1986, 1988, 1990, 1993, 1995 *  The Regents of the University of California.  All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright *    notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright *    notice, this list of conditions and the following disclaimer in the *    documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software *    must display the following acknowledgement: *  This product includes software developed by the University of *  California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors *    may be used to endorse or promote products derived from this software *    without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * *  @(#)tcp_output.c    8.4 (Berkeley) 5/24/95 *  $Id: tcp_output.pc,v 1.11 1999/09/28 05:26:33 ktang Exp $ */#include <stdio.h>#include <stdlib.h>#include <string.h>#include <assert.h>#include "api.h"#include "structmsg.h"#include "transport.h"#include "in_pcb.h"#include "ip.h"#include "tcpip.h"#include "tcp_fsm.h"#include "tcp_hdr.h"#include "tcp_proto.h"#include "tcp_seq.h"#include "tcp_timer.h"#include "tcp_var.h"#include "network.h"/* * Tcp output routine: figure out what should be sent and send it. */voidtcp_output(node, tp, tcp_now, tcp_stat)    GlomoNode *node;    struct tcpcb *tp;    unsigned long tcp_now;    struct tcpstat *tcp_stat;{    long len, win;    int off, flags;    struct tcpiphdr *ti;    unsigned char opt[TCP_MAXOLEN];    unsigned int optlen, hdrlen;    int idle, sendalot;    struct inpcb *inp = tp->t_inpcb;    Message *msg;    unsigned char *tcpseg;    int priority = inp->priority;    /*     * Determine length of data that should be transmitted,     * and flags that will be used.     * If there is some data or critical controls (SYN, RST)     * to send, then transmit; otherwise, investigate further.     */    idle = (tp->snd_max == tp->snd_una);    if (idle && tp->t_idle >= tp->t_rxtcur){        /*         * We have been idle for "a while" and no acks are         * expected to clock out any data we send --         * slow start to get ack "clock" running again.         */        tp->snd_cwnd = tp->t_maxseg;    }again:    sendalot = 0;    off = tp->snd_nxt - tp->snd_una;    win = MIN(tp->snd_wnd, tp->snd_cwnd);    flags = tcp_outflags[tp->t_state];    /*     * Get standard flags, and add SYN or FIN if requested by 'hidden'     * state flags.     */    if (tp->t_flags & TF_NEEDFIN)        flags |= TH_FIN;    if (tp->t_flags & TF_NEEDSYN)        flags |= TH_SYN;    /*     * If in persist timeout with window of 0, send 1 byte.     * Otherwise, if window is small but nonzero     * and timer expired, we will send what we can     * and go to transmit state.     */    if (tp->t_force) {        if (win == 0) {            /*             * If we still have some data to send, then             * clear the FIN bit.  Usually this would             * happen below when it realizes that we             * aren't sending all the data.  However,             * if we have exactly 1 byte of unset data,             * then it won't clear the FIN bit below,             * and if we are in persist state, we wind             * up sending the packet without recording             * that we sent the FIN bit.             *             * We can't just blindly clear the FIN bit,             * because if we don't have any more data             * to send then the probe will be the FIN             * itself.             */            if (off < inp->inp_snd.cc)                flags &= ~TH_FIN;            win = 1;        } else {            tp->t_timer[TCPT_PERSIST] = 0;            tp->t_rxtshift = 0;        }    }    len = MIN( inp->inp_snd.cc, win) - off;    /*     * Lop off SYN bit if it has already been sent.  However, if this     * is SYN-SENT state and if segment contains data, suppress sending     * segment.     */    if ((flags & TH_SYN) && SEQ_GT(tp->snd_nxt, tp->snd_una)) {         flags &= ~TH_SYN;        off--, len++;        if (len > 0 && tp->t_state == TCPS_SYN_SENT)             return;    }    /*     * Be careful not to send data and/or FIN on SYN segments     * in cases when no CC option will be sent.     * This measure is needed to prevent interoperability problems     * with not fully conformant TCP implementations.     */    if ((flags & TH_SYN) && (tp->t_flags & TF_NOOPT)){        len = 0;        flags &= ~TH_FIN;    }    if (len < 0) {        /*         * If FIN has been sent but not acked,         * but we haven't been called to retransmit,         * len will be -1.  Otherwise, window shrank         * after we sent into it.  If window shrank to 0,         * cancel pending retransmit, pull snd_nxt back         * to (closed) window, and set the persist timer         * if it isn't already going.  If the window didn't         * close completely, just wait for an ACK.         */        len = 0;        if (win == 0) {            tp->t_timer[TCPT_REXMT] = 0;            tp->t_rxtshift = 0;            tp->snd_nxt = tp->snd_una;            if (tp->t_timer[TCPT_PERSIST] == 0)                tcp_setpersist(tp);        }    }    if (len > tp->t_maxseg) {        len = tp->t_maxseg;        sendalot = 1;    }    if (SEQ_LT(tp->snd_nxt + len, tp->snd_una + inp->inp_snd.cc))        flags &= ~TH_FIN;    win = sbspace(inp);      /*     * Sender silly window avoidance.  If connection is idle     * and can send all data, a maximum segment,     * at least a maximum default-size segment do it,     * or are forced, do it; otherwise don't bother.     * If peer's buffer is tiny, then send     * when window is at least half open.     * If retransmitting (possibly after persist timer forced us     * to send into a small window), then must resend.     */    if (len) {        if (len == tp->t_maxseg)            goto send0;        if ((idle || tp->t_flags & TF_NODELAY) &&            (tp->t_flags & TF_NOPUSH) == 0 &&            len + off >= inp->inp_snd.cc)            goto send0;        if (tp->t_force)            goto send0;        if (len >= tp->max_sndwnd / 2 && tp->max_sndwnd > 0)            goto send0;        if (SEQ_LT(tp->snd_nxt, tp->snd_max))            goto send0;    }    /*     * Compare available window to amount of window     * known to peer (as advertised window less     * next expected input).  If the difference is at least two     * max size segments, or at least 50% of the maximum possible     * window, then want to send a window update to peer.     */    if (win > 0) {        /*         * "adv" is the amount we can increase the window,         * taking into account that we are limited by         * TCP_MAXWIN << tp->rcv_scale.         */        long adv = MIN(win, (long)TCP_MAXWIN << tp->rcv_scale) -            (tp->rcv_adv - tp->rcv_nxt);        if (adv >= (long) (2 * tp->t_maxseg))            goto send0;        if (2 * adv >= (long) inp->inp_rcv_hiwat)            goto send0;    }    /*     * Send if we owe peer an ACK.     */    if (tp->t_flags & TF_ACKNOW)        goto send0;    if ((flags & TH_RST) ||        ((flags & TH_SYN) && (tp->t_flags & TF_NEEDSYN) == 0))        goto send0;    if (SEQ_GT(tp->snd_up, tp->snd_una))        goto send0;    /*     * If our state indicates that FIN should be sent     * and we have not yet done so, or we're retransmitting the FIN,     * then we need to send.     */    if (flags & TH_FIN &&        ((tp->t_flags & TF_SENTFIN) == 0 || tp->snd_nxt == tp->snd_una))        goto send0;    /*     * TCP window updates are not reliable, rather a polling protocol     * using ``persist'' packets is used to insure receipt of window     * updates.  The three ``states'' for the output side are:     *  idle            not doing retransmits or persists     *  persisting      to move a small or zero window     *  (re)transmitting    and thereby not persisting     *     * tp->t_timer[TCPT_PERSIST]     *  is set when we are in persist state.     * tp->t_force     *  is set when we are called to send a persist packet.

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -