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

📄 tcpxmit.c

📁 用于嵌入式系统的TCP/IP协议栈及若干服务
💻 C
📖 第 1 页 / 共 2 页
字号:
				tcp_rslf(nsvp, nsvp->sv_err);                break;			 }#endif /* TCP_TRANSACTION_TCP */			 /* Make sure the previous connection still an  "active" one before 			    rejecting the new one */			 if (nsvp->sv_state != CLOSED) {				 normal;				 return(FNS_EADDRINUSE);			 }			} /* for */          normal;		} /* if ACK_OFF */		/****************************************************************************/		/* Obtain the MTU of the interface to which the SYN has been routed */        if_mtu = ndp->nd_ipmtu;#ifdef IP_RFC_1191        /* Obtain the path MTU to the destination to which the SYN is being sent.		   If path MTU not available, use the MTU of the interface to which this 		   SYN has been routed. Compute the largest TCP segment this implies (P/MTU 		   minus the maximum size of all of the protocol headers) */		  send_mss = ip_get_path_mtu(svp->sv_dest.ip_nethost);		  if (send_mss == -1) {#endif /* IP_RFC_1191 */			  send_mss = if_mtu;			  mss_source = TCP_MSS_SOURCE_IF_MTU;#ifdef IP_RFC_1191		  } else {			  mss_source = TCP_MSS_SOURCE_PATH_MTU;		  }#endif /* IP_RFC_1191 */		  send_mss -= (SIZEOF_TCPH_T+IP_MHL);        /* The value we advertise as our receive MSS will be based on the interface MTU,		   unless it has been specified from some other source (presumably the 		   TCP_SET_RCV_MSS socket option (this is what will be sent in the MSS option 		   field of this SYN) */        if (svp->sv_rcv_mss == 0) {           svp->sv_rcv_mss = (if_mtu - (SIZEOF_TCPH_T+IP_MHL));		}        critical;        /* Tell our "wizard" for setting the send MSS this interface-MTU-derived		   value. This "wizard" will decide whether to use it or not. */        tcp_set_send_mss(svp, (u16)send_mss,mss_source );        /* also, do any adjustments on the initial round-trip-time         * and ack delay values */        /*  Initialize the values used for the smooth round trip time algorithm		    and retransmission delay timer */        if (svp->sv_srtt == (u32)0L) {#ifdef TCP_TRANSACTION_TCP		   /* For transaction TCP, if we have cached a round trip time measurment		      from a previous connection, remember that here and use it for the 		      initial value of this connection */		   if  (svp->sv_t_tcp_flags & SV_TRANSACTION) {		       t_tcp_cache_entry_ *ce;               /* Must be critical here */		       ce = t_tcp_find_cache_entry(svp->sv_dest.ip_nethost);			   if (ce) {			     svp->sv_srtt = ce->ce_srtt;			     /* os_printf("\ntxp_xmit: setting srtt to cached value %u\n",svp->sv_srtt); */			   }		   }           if (svp->sv_srtt == (u32)0L) { /* in case we didn't find cache entry */#endif /* TCP_TRANSACTION_TCP */			   /* Initial value for smoothed round-trip-time measurement algorithm */               svp->sv_srtt = SRTT_INITIAL_VALUE;#ifdef TCP_TRANSACTION_TCP		   }#endif /* TCP_TRANSACTION_TCP */			/* Initial value for the retransmit timer, until we obtain a round-trip			   time measurement */			svp->sv_retrtim = svp->sv_initretrim;			/* Note from MBM: The following line puzzles me -- it looks like its			   saying "If the retransmission timer is already running, stop it			   and start it with the initial value of the retransmit timer.". 			   What about the case where the timer is not presently running? */            if (!t_stopped(svp->sv_rextcb)) {                t_start(svp->sv_rextcb, svp->sv_retrtim);			}        }        normal;        /* set option values into the segment */        tcp_dink_syn_options(tcphp,svp);        if ( ACK_ON(flags) )                    /* This is a SYN|ACK.  Time to open up the receive             * queue based on the final MSS negotiated. */            tcp_rmax_set(svp);    } /* if SYN_ON */    sop = sv_valid_sop(svp, sop);    if ( svp  &&  ACK_ON(flags) ) {        /* Time to compute the receive window.  For outbound packets,         * this is the only place that this is done.  This insures         * that at the start of a connection, the sv_mss has already         * been completely negotiated. */        if ( svp->sv_flags & SV_RFINFLG )            /* FIN seen -- nothing more expected */            u1 = 0;        else if ( sop  &&  sop->so_rq.gq_inuse )            /* socket has buffer capacity, but silly window avoidance may dictate               that we not presently advertise it */            u1 = tcp_rwind_to_advertise(svp);        else            /* leave room for the FIN */            u1 = 1;        HostToNet16(&tcphp[TCPH_WINDOW], u1);        /* Restart the counter of how many bytes read from the socket since we acked */        svp->sv_rcvsncwupd = 0;#ifdef TCP_TIMESTAMPS		/* RFC 1323 requires us to keep track of last sequence number that has been		   ACKED, which may not be caught up to RCV.NEXT when ACKs are being 		   delayed */		M32U(svp->sv_last_ack_sent, = , NetToHost32(&tcphp[TCPH_ACKNO]));#endif    } else {#ifdef TCP_TRANSACTION_TCP	/* If transaction TCP and we are still sending our request and have not yet	   received the SYN-ACK response to our initial SYN-DATA segment (thus the	   receive queue has not been "opened up" yet), we need to advertise a window	   anyway -- otherwise, their SYN-ACK could not contain any data, defeating	   the purpose of transaction TCP */		if ( svp && (svp->sv_t_tcp_flags & SV_TRANSACTION) ) {            HostToNet16(&tcphp[TCPH_WINDOW],svp->sv_rq_max );		} else #endif        HostToNet16(&tcphp[TCPH_WINDOW], (u16)0);    }/* msd: restore the source address of the message if this isn't an * initial connection; this insures that despite the actual link * layer device chosen by the router, the socket will not appear * to 'move' addresses and thus become disconnected */    if ((SYN_OFF(flags)  ||  ACK_ON(flags))  &&  svp) {        HostToMem32(&(m_ptr(mp,IPH_T)[IPH_SADDR]), svp->sv_src.ip_nethost);        mp->m_src.a_ipa.ip_nethost = svp->sv_src.ip_nethost; /* for ARP, ULP */    }    /* scrutinize the TTL of the IP packet; adjust the socket's current     * TTL value upward (bounding has been done by 'ip_dink') */    if (sop  &&  (u1 = m_ptr(mp, IPH_T)[IPH_TTL]) > ipsu.ipsu_ttl)        ipsu.ipsu_ttl = (u8)u1;/* Compute TCP header checksum. This packet is on its way to the network. * This is the last time TCP will deal with this packet. */    piphp = &m_ptr(mp, IPH_T)[IPH_PIPH];    zbsave = piphp[PIPH_ZERO];      /* don't blast the TTL */    piphp[PIPH_ZERO] = 0;    /* The piph_protocol field is assumed to be correct here. */    u1 = mp->m_tp - mp->m_cp;       /* length of TCP header + data */    HostToNet16(&piphp[PIPH_LENGTH], u1);    HostToNet16(&tcphp[TCPH_CHECKSUM], oc_sum((a16 *)piphp, SIZEOF_PIPH_T));    checksum = ~oc_sum((a16 *)tcphp, u1);    if ( checksum == 0xFFFF)        checksum = 0;    HostToNet16(&tcphp[TCPH_CHECKSUM], checksum);    piphp[PIPH_ZERO] = zbsave;    critical;    smfhist(mp, tcp_dink);#ifdef  TRACE    trace1(tcp_tstate, "tcp_dink: src(%s)[", ipa2str(&mp->m_src.a_ipa, (char *)0));    if (tcp_tstate) {        if (valid_sop(mp))            os_printf("%d", mp->m_soindx);        else            os_printf("*");        os_printf("] => dest(%s) <%s>\n", ipa2str(&mp->m_dest.a_ipa, (char *)0), tcp_pf(flags));    }#endif  /*TRACE*/    normal;   TCP_TRACE_SEGMENT(mp, 0);   return 0;} /* tcp_dink *//* Outbound transmission point. * Final TCP header construction before checksum. */ export  st      tcp_xmit (fast m * mp){    fast    TCPH_T  * tcphp;    use_critical;    critical; trace1(tcp_trace, "tcp_xmit(0x%x):\n", mp); normal;    tcphp = (TCPH_T *)mp->m_cp;    HostToMem16(&tcphp[TCPH_SPORT], mp->m_src.a_ipa.ip_port);    HostToMem16(&tcphp[TCPH_DPORT], mp->m_dest.a_ipa.ip_port);    mp->m_type = tcp_prp->pr_protocol; /* so IP can target 'tcp_dink' */    critical;    if (mp->m_svp != (tcpsv_t *)0)        mp->m_prec = mp->m_svp->sv_prec;    /* pass precedence back down under; if there is no state vector,  */    /* then the precedence will already be set here. */    normal;#ifdef  TCP_STATS    ++tcp_txmit;#endif    INC_MIB_CNTR_TCP_OUT_SEGMENTS#ifndef  AVOID_MSM	return (st)ip_send;#else    return(ip_send(mp));#endif}

⌨️ 快捷键说明

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