📄 tcpnetd.c
字号:
/* 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 + -