/** Build the TCP option in synchronized states. @param[in] Tcb Pointer to the TCP_CB of this TCP instance. @param[in] Nbuf Pointer to the buffer to store the options. @return The total length of the TCP option field. **/ UINT16 TcpBuildOption ( IN TCP_CB *Tcb, IN NET_BUF *Nbuf ) { UINT8 *Data; UINT16 Len; ASSERT ((Tcb != NULL) && (Nbuf != NULL) && (Nbuf->Tcp == NULL)); Len = 0; // // Build the Timestamp option. // if (TCP_FLG_ON (Tcb->CtrlFlag, TCP_CTRL_SND_TS) && !TCP_FLG_ON (TCPSEG_NETBUF (Nbuf)->Flag, TCP_FLG_RST) ) { Data = NetbufAllocSpace ( Nbuf, TCP_OPTION_TS_ALIGNED_LEN, NET_BUF_HEAD ); ASSERT (Data != NULL); Len += TCP_OPTION_TS_ALIGNED_LEN; TcpPutUint32 (Data, TCP_OPTION_TS_FAST); TcpPutUint32 (Data + 4, mTcpTick); TcpPutUint32 (Data + 8, Tcb->TsRecent); } return Len; }
/** Enable the keepalive timer and set the timeout value. @param Tcb Pointer to the TCP_CB of this TCP instance. **/ VOID TcpSetKeepaliveTimer ( IN OUT TCP_CB *Tcb ) { if (TCP_FLG_ON (Tcb->CtrlFlag, TCP_CTRL_NO_KEEPALIVE)) { return ; } // // Set the timer to KeepAliveIdle if either // 1. the keepalive timer is off // 2. The keepalive timer is on, but the idle // is less than KeepAliveIdle, that means the // connection is alive since our last probe. // if (!TCP_TIMER_ON (Tcb->EnabledTimer, TCP_TIMER_KEEPALIVE) || (Tcb->Idle < Tcb->KeepAliveIdle)) { TcpSetTimer (Tcb, TCP_TIMER_KEEPALIVE, Tcb->KeepAliveIdle); Tcb->KeepAliveProbes = 0; } else { TcpSetTimer (Tcb, TCP_TIMER_KEEPALIVE, Tcb->KeepAlivePeriod); } }
/** Build the TCP option in three-way handshake. @param[in] Tcb Pointer to the TCP_CB of this TCP instance. @param[in] Nbuf Pointer to the buffer to store the options. @return The total length of the TCP option field. **/ UINT16 TcpSynBuildOption ( IN TCP_CB *Tcb, IN NET_BUF *Nbuf ) { UINT8 *Data; UINT16 Len; ASSERT ((Tcb != NULL) && (Nbuf != NULL) && (Nbuf->Tcp == NULL)); Len = 0; // // Add a timestamp option if not disabled by the application // and it is the first SYN segment, or the peer has sent // us its timestamp. // if (!TCP_FLG_ON (Tcb->CtrlFlag, TCP_CTRL_NO_TS) && (!TCP_FLG_ON (TCPSEG_NETBUF (Nbuf)->Flag, TCP_FLG_ACK) || TCP_FLG_ON (Tcb->CtrlFlag, TCP_CTRL_RCVD_TS)) ) { Data = NetbufAllocSpace ( Nbuf, TCP_OPTION_TS_ALIGNED_LEN, NET_BUF_HEAD ); ASSERT (Data != NULL); Len += TCP_OPTION_TS_ALIGNED_LEN; TcpPutUint32 (Data, TCP_OPTION_TS_FAST); TcpPutUint32 (Data + 4, mTcpTick); TcpPutUint32 (Data + 8, 0); } // // Build window scale option, only when configured // to send WS option, and either we are doing active // open or we have received WS option from peer. // if (!TCP_FLG_ON (Tcb->CtrlFlag, TCP_CTRL_NO_WS) && (!TCP_FLG_ON (TCPSEG_NETBUF (Nbuf)->Flag, TCP_FLG_ACK) || TCP_FLG_ON (Tcb->CtrlFlag, TCP_CTRL_RCVD_WS)) ) { Data = NetbufAllocSpace ( Nbuf, TCP_OPTION_WS_ALIGNED_LEN, NET_BUF_HEAD ); ASSERT (Data != NULL); Len += TCP_OPTION_WS_ALIGNED_LEN; TcpPutUint32 (Data, TCP_OPTION_WS_FAST | TcpComputeScale (Tcb)); } // // Build the MSS option. // Data = NetbufAllocSpace (Nbuf, TCP_OPTION_MSS_LEN, 1); ASSERT (Data != NULL); Len += TCP_OPTION_MSS_LEN; TcpPutUint32 (Data, TCP_OPTION_MSS_FAST | Tcb->RcvMss); return Len; }
/** Get the operational settings of this TCP instance. @param Tcb Pointer to the TCP_CB of this TCP instance. @param Mode Pointer to the buffer to store the operational settings. @retval EFI_SUCCESS The mode data is read. @retval EFI_NOT_STARTED No configuration data is available because this instance hasn't been started. **/ EFI_STATUS Tcp4GetMode ( IN TCP_CB *Tcb, IN OUT TCP4_MODE_DATA *Mode ) { SOCKET *Sock; EFI_TCP4_CONFIG_DATA *ConfigData; EFI_TCP4_ACCESS_POINT *AccessPoint; EFI_TCP4_OPTION *Option; EFI_IP4_PROTOCOL *Ip; Sock = Tcb->Sk; if (!SOCK_IS_CONFIGURED (Sock) && (Mode->Tcp4ConfigData != NULL)) { return EFI_NOT_STARTED; } if (Mode->Tcp4State != NULL) { *(Mode->Tcp4State) = (EFI_TCP4_CONNECTION_STATE) Tcb->State; } if (Mode->Tcp4ConfigData != NULL) { ConfigData = Mode->Tcp4ConfigData; AccessPoint = &(ConfigData->AccessPoint); Option = ConfigData->ControlOption; ConfigData->TypeOfService = Tcb->Tos; ConfigData->TimeToLive = Tcb->Ttl; AccessPoint->UseDefaultAddress = Tcb->UseDefaultAddr; IP4_COPY_ADDRESS (&AccessPoint->StationAddress, &Tcb->LocalEnd.Ip); IP4_COPY_ADDRESS (&AccessPoint->SubnetMask, &Tcb->SubnetMask); AccessPoint->StationPort = NTOHS (Tcb->LocalEnd.Port); IP4_COPY_ADDRESS (&AccessPoint->RemoteAddress, &Tcb->RemoteEnd.Ip); AccessPoint->RemotePort = NTOHS (Tcb->RemoteEnd.Port); AccessPoint->ActiveFlag = (BOOLEAN) (Tcb->State != TCP_LISTEN); if (Option != NULL) { Option->ReceiveBufferSize = GET_RCV_BUFFSIZE (Tcb->Sk); Option->SendBufferSize = GET_SND_BUFFSIZE (Tcb->Sk); Option->MaxSynBackLog = GET_BACKLOG (Tcb->Sk); Option->ConnectionTimeout = Tcb->ConnectTimeout / TCP_TICK_HZ; Option->DataRetries = Tcb->MaxRexmit; Option->FinTimeout = Tcb->FinWait2Timeout / TCP_TICK_HZ; Option->TimeWaitTimeout = Tcb->TimeWaitTimeout / TCP_TICK_HZ; Option->KeepAliveProbes = Tcb->MaxKeepAlive; Option->KeepAliveTime = Tcb->KeepAliveIdle / TCP_TICK_HZ; Option->KeepAliveInterval = Tcb->KeepAlivePeriod / TCP_TICK_HZ; Option->EnableNagle = (BOOLEAN) (!TCP_FLG_ON (Tcb->CtrlFlag, TCP_CTRL_NO_NAGLE)); Option->EnableTimeStamp = (BOOLEAN) (!TCP_FLG_ON (Tcb->CtrlFlag, TCP_CTRL_NO_TS)); Option->EnableWindowScaling = (BOOLEAN) (!TCP_FLG_ON (Tcb->CtrlFlag, TCP_CTRL_NO_WS)); Option->EnableSelectiveAck = FALSE; Option->EnablePathMtuDiscovery = FALSE; } } Ip = Tcb->IpInfo->Ip.Ip4; ASSERT (Ip != NULL); return Ip->GetModeData (Ip, Mode->Ip4ModeData, Mode->MnpConfigData, Mode->SnpModeData); }