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

📄 tcpnetd.c

📁 用于嵌入式系统的TCP/IP协议栈及若干服务
💻 C
📖 第 1 页 / 共 5 页
字号:
    /* Urgent byte is in this segment. Store it in "urgent buffer", and       slide the data beyond it down over it */    svp->sv_urg_buf = *ubp;#if 0    os_printf("\ntcp_urgdata: got out-of-band urgent byte (%02x)\n",*ubp);#endif    for (mvp = (ubp + 1); mvp <= mp->m_tp; mvp++) {        *(mvp - 1) = *mvp;    } /* for */    --(mp->m_tp);    mp->m_oob = 1;} /* tcp_urgdata *//************************************************************************//* Update the state vector with regard to urgent data. Notify the       *//* application if appropriate                                           *//* NOTE: Out-of-band urgent data will have been extracted earlier by    *//* tcp_urgdata                                                          *//************************************************************************/local void tcp_urgstate (fast m *mp){    fast    tcpsv_t * svp;    fast    TCPH_T  * tcphp;    fast    u32 urgent, seqno;    use_critical;    so_t    * sop;    /* if there is no urgent pointer in this segment, there is nothing to       do here */    tcphp = (TCPH_T *)(mp->m_cp);    if (URG_OFF(NetToHost16(&tcphp[TCPH_FLAGS]))) return;    trace0(tcp_turgent, "tcp_urgstate: urgent pointer is set\n");    critical;    if ((svp = mp->m_svp) == (tcpsv_t *)0) {        debug0(tcp_debug, "tcp_urgstate: no state vector\n");        goto out;    } /* if */    /* If we are not already in an urgent state, enter urgent state now and       notify the application  */    if (svp->sv_urg_state == SV_URGSTATE_NONE) {        sop = sv_valid_sop(svp, sop);        if (sop) so_notify(sop, URGENT_NOTIFY);        svp->sv_urg_state = SV_URGSTATE_NODATA;    } /* if */    /* calculate the urgent sequence, store it in state vector*/    seqno = NetToHost32(&tcphp[TCPH_SEQNO]);    urgent = seqno + NetToHost16(&tcphp[TCPH_URGENT]);    M32U(svp->sv_rurg, =, urgent);    /* If this segment contains the urgent byte, not that in our state vector.       This check assumes that tcp_nstate has already been invoked to update       the sv_rnxt pointer. */    if ( MC32U(svp->sv_rurg, >, seqno) && M32M(svp->sv_rurg, <=, svp->sv_rnxt) ) {        svp->sv_urg_state = SV_URGSTATE_DATA;    } /* if */out:    normal;} /* tcp_urgstate *//*************************************************************************                                                                       **  Function :                                                           **                                                                       **  Description :                                                        **                                                                       **                                                                       **  Parameters : None.                                                   **                                                                       **  Return : None.                                                       **                                                                       *************************************************************************//* clear any delayed acknowledgement */export  void    tcp_clr_ack (fast tcpsv_t * svp){    use_critical;    critical;    svp->sv_flags &= ~SV_DATACK;    if (svp->sv_acktcb)        (void) t_stop(svp->sv_acktcb);    normal;}/*************************************************************************                                                                       **  Function :                                                           **                                                                       **  Description :                                                        **                                                                       **                                                                       **  Parameters : None.                                                   **                                                                       **  Return : None.                                                       **                                                                       *************************************************************************//* 9.4.6.3.9 Connection open. [134] */pflocal st  tcp_copen (fast m * mp){    fast    tcpsv_t * svp;    fast    TCPH_T  * tcphp;    fast    u16 flags;    trace0(tcp_trace, "tcp_copen\n");    if ((svp = mp->m_svp) == (tcpsv_t *)0) {        debug0(tcp_debug, "tcp_copen: no state vector\n");        return (st)mp->m_dispfn;    }    tcphp = (TCPH_T *)mp->m_cp;    flags = NetToHost16(&tcphp[TCPH_FLAGS]);    if (SYN_ON(flags)) {        /* adopt the peer's sequence number */        M32U(svp->sv_rnxt, =, NetToHost32(&tcphp[TCPH_SEQNO]) + 1);        /* prepare to run this packet by 'tcp_net_deliver' once again to         * generate the ack, and in case there is data or a FIN present.         * This may seem cyclical, but clearing the SYN here prevents         * another return to this function, and other problems. */        flags &= ~SYN;        HostToNet16(&tcphp[TCPH_FLAGS], flags);        HostToNet32(&tcphp[TCPH_SEQNO], MU32(svp->sv_rnxt));    }	if (svp->sv_flags & SV_PASSIVE) {#ifdef TCP_TRANSACTION_TCP	   /* According to RFC 1644, section 3.4, R3.2, now is the time (completion	      of 3-way handshake when cache.CC is undefined) to update cache.CC for		  the peer host */		if  (svp->sv_t_tcp_flags & SV_TRANSACTION) { 		    t_tcp_cache_entry_ *ce = t_tcp_find_cache_entry(svp->sv_dest.ip_nethost);			if ( (ce) && (ce->ce_cc == 0) ) {				ce->ce_cc = svp->sv_ccrecv;			} /* if */		} /* if */#endif	   /* If this is the passive side of the connection, we may have received	      data with the initial SYN that was stored temporarily on the holding	      queue (see end of function "tcp_passive") until the 3-way handshake completed.	      Now that it has, schedule that message to be processed now */       tcp_process_hold_queue(mp);	} /* if */    /* Note: if a FIN is present, 'tcp_net_deliver' will change state to     * CLOSE_WAIT. */    tcp_estab(svp); /* Enter ESTAB state */    return (st)tcp_net_deliver;} /* tcp_copen *//*************************************************************************                                                                       **  Function :                                                           **                                                                       **  Description :                                                        **                                                                       **                                                                       **  Parameters : None.                                                   **                                                                       **  Return : None.                                                       **                                                                       *************************************************************************//* return the data size of a TCP packet, including SYN & FIN bits. */export  int tcp_dl (fast m * mp){    fast    int length;    fast    u16 flags;    fast    TCPH_T  * tcphp;    tcphp = (TCPH_T *)mp->m_cp;    length = mp->m_tp - mp->m_cp - tcphl(tcphp);    flags = NetToHost16(&tcphp[TCPH_FLAGS]);    if (length < 0) { /* very strange... */        debug0(tcp_debug, "tcp_dl: negative length!\n");        debug2(tcp_debug, "tcp_dl: length = %d, flags = 0x%x\n", length, flags);        debug3(tcp_debug, "tcp_dl: m_tp = 0x%x, m_hp = 0x%x, m_cp = 0x%x\n", mp->m_tp, mp->m_hp, mp->m_cp);        smhprint(mp);        length = 0; /* return something valid... */    }    if (SYN_ON(flags))        length++;    if (FIN_ON(flags))        length++;    return length;} /* tcp_dl *//*************************************************************************                                                                       **  Function :                                                           **                                                                       **  Description :                                                        **                                                                       **                                                                       **  Parameters : None.                                                   **                                                                       **  Return : None.                                                       **                                                                       *************************************************************************//* Go into the Established state, and notify the ULP *//* 'svp' must be bound by caller */local   void    tcp_estab (fast tcpsv_t * svp){    fast    so_t    * sop, * lsop;    int     err;    use_critical;    critical;    /* This *must* be the only place that changes state to ESTAB */#ifdef TCP_TRANSACTION_TCP	/* With transaction TCP, it is possible to receive the SYN-ACK	   that puts us into the established state when we already sent	   (or scheduled to be sent) a FIN. If thats the case, we want to 	   go into the FIN_WAIT1 state. */	if (svp->sv_flags & SV_TFINFLG)  {        set_state("tcp_estab", svp, FIN1_WAIT);	} else {#endif /* #ifdef TCP_TRANSACTION_TCP */    /* This *must* be the only place that changes state to ESTAB */    set_state("tcp_estab", svp, ESTAB);#ifdef TCP_TRANSACTION_TCP	}	/* For transaction TCP, once we have gotten past the SYN-SENT state,	   we need to recalibrate the user-data size of a full-sized data segment,	   because previously we will have included a CC option in the 	   calibration, and if the other end did not properly echo our	   CC option, we don't want to send them in subsequent segments */	if (svp->sv_t_tcp_flags & SV_TRANSACTION)  {	   svp->sv_mssd = (svp->sv_mss - tcp_seg_optsize(svp,0,&(svp->sv_dseg_options))); 	}#endif /* TCP_TRANSACTION_TCP */    /* initialize sv_read for urgent data processing */    stass(svp->sv_read, svp->sv_rnxt);    sop = sv_valid_sop(svp, sop);    if (sop) {        sop->so_flags |= F_SO_CONNECTED;#ifdef TCP_KEEP_ALIVE        if (tcp_keep_alive && so_keepalive(sop))        {            /* if set, initialize Keep-Alive parameters */            err = tcp_init_ka(svp);            debug1(tcp_debug, "tcp_init_ka failed %d\n", err);        }#endif        if (svp->sv_flags & SV_PASSIVE) {            trace1(tcp_tpassive, "ESTABL on %d\n", sop->so_index);/* notify the listening socket. User does know yet about the new socket */            lsop = (so_t *)sop->so_q.q_next;/* added check for accept socket not in listening socket queue * Could happen when client and server reside on same host (only if server * executes a blocking accept() and if server task has higher priority than * client task). */            while ( !is_header((q *)&lsop->so_q) && lsop != sop)                lsop = (so_t *)lsop->so_q.q_next;/* connection, ok now to accept */            if (lsop != sop)            {                trace1(tcp_tpassive, "NOTIFY listening socket %d\n", lsop->so_index);                so_notify(lsop, ACCEPT_NOTIFY|READ_NOTIFY);                os_wakeup((char *)lsop);            }            else            {              debug1(tcp_debug, "Accept socket [%d] not queued to listening socket!\n", sop->so_index);              ;            }        } else            so_notify(sop, CONNECT_NOTIFY | WRITE_NOTIFY | SENDQEMPTY_NOTIFY); /* connection, ok now to write */    }    normal;} /* tcp_estab *//*************************************************************************                                                                       **  Function :                                                           **                                                                       **  Description :                                                        **                                                                       **                                                                       **  Parameters : None.                                                   **                                                                       **  Return : None.                                                       **                                                                       *************************************************************************//* Net deliver, ALL states. [103..119] */export  st  tcp_net_deliver (fast m * mp){    fast    tcpsv_t * svp;    fast    TCPH_T  * tcphp;        /* TCP header pointer */    fast    u16 flags;    fast    int length;    fast    u32 ackno, seqno;    fast    u32 rwind;    fast    u32 netend;    fast    u32 winend;#ifdef TCP_TIMESTAMPS	fast    u32 peer_tmstmp = 0;	fast    boolean got_peer_tmstmp = false;#endif#ifdef TCP_PAWS	boolean paws_test_passes;

⌨️ 快捷键说明

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