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

📄 tcpmisc.c

📁 用于嵌入式系统的TCP/IP协议栈及若干服务
💻 C
📖 第 1 页 / 共 5 页
字号:
/* #define DEBUG_IN_SACKS *//**            Copyright (c) 1998-2001 by NETsilicon Inc.**  This software is copyrighted by and is the sole property of*  NETsilicon.  All rights, title, ownership, or other interests*  in the software remain the property of NETsilicon.  This*  software may only be used in accordance with the corresponding*  license agreement.  Any unauthorized use, duplication, transmission,*  distribution, or disclosure of this software is expressly forbidden.**  This Copyright notice may not be removed or modified without prior*  written consent of NETsilicon.**  NETsilicon, reserves the right to modify this software*  without notice.**  NETsilicon*  411 Waverley Oaks Road                  USA 781.647.1234*  Suite 227                               http://www.netsilicon.com*  Waltham, MA 02452                       AmericaSales@netsilicon.com***************************************************************************  $Name: Fusion 6.52 Fusion 6.51 $*  $Date: 2002/01/30 17:15:13 $*  $Source: M:/psisrc/stack/tcp/rcs/tcpmisc.c $*  $Revision: 1.56 $***************************************************************************                         - Revision Log -                              ** Who   When        Why** FND   01/05/01    Rename t_start/t_delete to fns_t_start/fns_t_delete*                   to fix conflict with pSOS.****************************************************************************  File Description:  TCP - Transmission Control Protocol*                     Miscellaneous TCP routines**************************************************************************/#include "std.h"#include "ip.h"#include "icmp.h"#include "m.h"#include "netioc.h"#include "pr.h"#include "q.h"#include "select.h"#include "so.h"#include "timer.h"#include "tcp.h"#include "in.h"#include "fnsmib.h"#include "nerrno.h"#include "debug.h"#include "fns_heap.h"#ifdef TCP_KEEP_ALIVE#include "flags.h"  /* for give_bs macro expansion */#endif#include "fnsproto.h"#define t_start fns_t_start#define t_delete fns_t_delete#ifdef TCP_QUIETpflocal int     tcp_noisy(void * uarg);#endifimport  u32     nc_hsize, tcp_max_mss, tcp_rq_max;export  int     tcp_port;export  q       tcp_q;#ifdef  DEBUGimport  boolean tcp_debug;#endif#ifdef TRACEimport  int tcp_trace, tcp_tstate, tcp_tsqxmit, tcp_trxmit;#endif#ifdef MSD_DEBUGimport  boolean msd_debug;               import  u32     tcptargz;#endifimport  boolean tcp_initialized;import  pr_t    * tcp_prp;#ifdef TCP_QUIETimport  tcb     * tcp_quiet;#endif#ifdef NAT_ROUTERimport u32 m_growmax;#endif/* Global tcp retransmit timer limit variables. Initialized from compiler   constants (defined in tcp.h), and can be changed via SNMP (API is   needed for that). At the time a TCP connection iscreated, the retransmit    timer limits for that connection are initialized from these global limit    variable (whatever values they have at the time). Then, (before the    connection is opened) they can be modified via socket options */export int tcp_initial_rex_delay = INITIAL_REX_DELAY;export int tcp_min_rex_delay = MIN_REX_DELAY;export int tcp_max_rex_delay = MAX_REX_DELAY;/* disconnect the mp from it's state vector. */export  int  sv_m_detach (m * mp){    use_critical;    trace0(tcp_trace, "sv_m_detach:\n");    critical;    assert(mp->m_svp != (tcpsv_t *)0, "sv_m_detach: no state vector\n");    smfhist(mp, sv_m_detach);    sv_detach(mp->m_svp, mp, false);    mp->m_termfn = 0;    mp->m_svp = (tcpsv_t *)0;    normal;    return(1); /* let m_free free the memory, if we're being called from there */} /* sv_m_detach *//***********************************************//* attach a state vector to an m structure */void    sv_m_bind (tcpsv_t * svp, m * mp,int (*termfn)(struct m *)  ){    use_critical;    trace2(tcp_trace, "sv_m_bind: svp == 0x%x, mp == 0x%x\n", svp, mp);    critical;    sv_bind(svp, sv_m_bind, true);    smfhist(mp, sv_m_bind);     /* mark the mp's history */    if (mp->m_svp != (tcpsv_t *)0) {        /* mp is already bound */        /* detach it from the other state vector first */		sv_m_detach(mp);        assert(mp->m_svp == (tcpsv_t *)0, "sv_m_bind: !0 m_svp\n");    }    sv_bind(mp->m_svp = svp, mp, false);    assert(mp->m_svp == svp, "sv_m_bind: incorrectly bound\n");    mp->m_sop = svp->sv_sop;        /* refer to the same socket (if any) */    mp->m_soindx = svp->sv_soindx;    trace1(tcp_trace, "sv_m_bind: m_sop = 0x%x\n", mp->m_sop);    mp->m_termfn = termfn;    sv_detach(svp, sv_m_bind, true);    normal;} /* sv_m_bind *//*************************************************************************                                                                       **  Function :                                                           **                                                                       **  Description :                                                        **                                                                       **                                                                       **  Parameters : None.                                                   **                                                                       **  Return : None.                                                       **                                                                       *************************************************************************/export  void    tcpabort (fast tcpsv_t * svp, int err){    fast    m       * mp;    fast    int     hsize;    so_t    * sop;    use_critical;#ifdef MSD_DEBUG    if (msd_debug)    {        sop = sv_valid_sop(svp, sop);        if (sop)            os_printf("tcpabort[%d] state %d\n", sop->so_index, svp->sv_state);        else            os_printf("tcpabort[*] state %d\n", svp->sv_state);    }#endif    if (svp->sv_state >= SYN_RECVD) {        critical;        hsize = (int)nc_hsize;        sop = sv_valid_sop(svp, sop);        if (sop != (so_t *)0)            hsize += sop->so_hsize;        else            hsize += IP_MHL + SIZEOF_TCPH_T;        normal;        if ((mp = m_new(hsize, (int *)0, (u16)0)) != (m *)0) {            sv_m_bind(svp, mp, sv_m_detach);            mp->m_pflags = RCURRENT;            debug1(tcp_debug, "tcpabort: sending reset, err = %d\n", err);#ifdef MSD_DEBUG        if (msd_debug)            os_printf("tcpabort: sending reset, err %d\n", err);#endif        (void)msm(mp, tcp_reset);        }    }#ifdef MSD_DEBUG    if (msd_debug)        os_printf("tcpabort: calling tcp_rslf, err %d\n", err);#endif    tcp_rslf(svp, err);}/**********************************************************************//* ACKnowledgement timer; emits a time-based acknowledgement, which was * previously requested by 'tcp_schedule_delayed_ack' */export  int     tcp_acktimer (void * uarg){#define lsvp    ((tcpsv_t *)uarg)    fast    so_t    * sop;    use_critical;    critical;    assert((lsvp->sv_q.q_flags & F_Q_ZAPPED) == 0, "tcp_acktimer: called with zapped sv\n");#ifdef MSD_DEBUG    if (msd_debug)      os_printf("<TACK %d> ",(int)lsvp->sv_ackdelay);  #endif    sop = sv_valid_sop(lsvp, sop);    /* UNLESS there is unacknowledged data waiting to be ACKed, or     * the receive window is now fully open, simply bypass the     * generation of this (extraneous) ACK */    if (sop  &&  !(lsvp->sv_flags & SV_DATACK)  &&  sop->so_rq.gq_cnt) {        normal;        return 0;    }    normal;#ifdef TCP_TRANSACTION_TCP	/* If we have delayed a SYN-ACK waiting for application to do a write, this is the	   end of the delay period. But in order to send the SYN, we need to call 	   tcp_sqxmit rather than tcp_sndack. */	if (TRANSACTION_DELAYING_SYNACK(lsvp)) {		tcp_sqxmit(lsvp);	} else {#endif /* TCP_TRANSACTION_TCP */    	tcp_sndack((m *)0, lsvp);#ifdef TCP_TRANSACTION_TCP	}#endif /* TCP_TRANSACTION_TCP */        return 0;#undef lsvp} /* tcp_acktimer */#ifdef NEED_ADJUST_ACK_DELAY/**********************************************************************//* adjust the acknowledgement timer interval based on the given value */export  void    tcp_adjust_ack_delay (fast tcpsv_t * svp, u32 value){    fast    u32     u;    if ((u = svp->sv_ackdelay) != (u32)0) {        /* The following line of code is meant to "smooth" adjustments		   in the ack timer delay. It moves the acktimer  1/8 of distance 		   from the present value toward the passed in new value. This is		   identical to the smoothing algorithm used in "tcp_update" to 		   adjust the round-trip time based on round trip time measurement		   samples. */        u = (((u << 3) - u) + value) >> 3;    } else {        u = value;	}    /* bound the value */    if (u < MS_PER_TICK)        u = MS_PER_TICK;    else if (u > MAX_ACK_DELAY)        u = MAX_ACK_DELAY;#ifdef MSD_DEBUG    if (msd_debug  && svp->sv_ackdelay != u)              os_printf("[ACK %d => %d] ",(int)svp->sv_ackdelay,(int)u);#endif    svp->sv_ackdelay = u;} /* tcp_adjust_ack_delay */#endif/****************************************************************************//* Generate a packet with no data and add it to the receive queue, simulating * an EOF. *//* MUST be called in a critical context! */export  void    tcp_finpkt (m * mp, fast tcpsv_t * svp){    fast    m       * nmp;    so_t    * sop;    assert(svp->sv_refcnt != 0, "tcp_finpkt: sv not bound\n");   /*  compute sop once */    sop = svp->sv_sop;    if (sop == (so_t *)0) { /* no socket to give it too... */        debug0(tcp_debug, "tcp_finpkt: no socket\n");        svp->sv_flags &= ~SV_EOF;       /* fake it anyway */        return;    }    if ((nmp = m_new(0, (int *)0, (u16)0)) != (m *)0) {        /* "receive" an empty packet *//* Start of MSD WSI change */#ifdef WSI1_ONLY#ifdef  MSD_DEBUG    if (msd_debug)      os_printf("tcp_finpkt: rqcnt==%d\n",sop->so_rq.gq_cnt);#endif        /* RSHUTDOWN_NOTIFY when FIN arrives and         *  no data is waiting to be read.         */        if (sop->so_rq.gq_cnt == 0)        {            /* FIN arrived w/ no data ahead of it to be read. */            so_notify(sop, RSHUTDOWN_NOTIFY);        }/* End of MSD WSI change */#endif /* WSI1_ONLY */	    /* MBM -- this was moved here from "tcp_naccept" to fix a race condition --		   see note in tcp_naccespt which explains it. */#ifndef WSI1_ONLY        sop->so_flags |= F_SO_RSHUTDOWN;#endif /* WSI1_ONLY */#ifdef  M_HISTORY        smfhist(mp, (st (*)(m *))tcp_finpkt);#endif        sv_m_bind(svp, nmp, sv_m_detach);        if (mp) {            sm_wqin(mp, nmp, smrqin);        } else {            (void)msm(nmp, smrqin);		}        svp->sv_flags &= ~SV_EOF;    } else {        svp->sv_flags |= SV_EOF;        /* timer will try later */        (void) t_start(svp->sv_rextcb, HALLOC_FIN_DELAY);    }} /* tcp_finpkt */#ifdef IP_RFC_1191/***********************************************************************//* Recieve notification of a path MTU change for a specific foreign    *//* host. Look thru our open connections for connections to the         *//* specified foreigh host, and adjust the send MSS of these connections*//* according to the new path MTU                                       *//***********************************************************************/export int tcp_pmtu_change_notif(u32 hostaddr,u16 new_pmtu){ tcpsv_t *svp; int new_mss = (new_pmtu - (SIZEOF_TCPH_T+IP_MHL) );

⌨️ 快捷键说明

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