123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883 |
- /** @file
- The implementation of a dispatch routine for processing TCP requests.
- (C) Copyright 2014 Hewlett-Packard Development Company, L.P.<BR>
- Copyright (c) 2009 - 2018, Intel Corporation. All rights reserved.<BR>
- SPDX-License-Identifier: BSD-2-Clause-Patent
- **/
- #include "TcpMain.h"
- /**
- Add or remove a route entry in the IP route table associated with this TCP instance.
- @param[in] Tcb Pointer to the TCP_CB of this TCP instance.
- @param[in] RouteInfo Pointer to the route information to be processed.
- @retval EFI_SUCCESS The operation completed successfully.
- @retval EFI_NOT_STARTED The driver instance has not been started.
- @retval EFI_NO_MAPPING When using the default address, configuration(DHCP,
- BOOTP, RARP, etc.) is not finished yet.
- @retval EFI_OUT_OF_RESOURCES Could not add the entry to the routing table.
- @retval EFI_NOT_FOUND This route is not in the routing table
- (when RouteInfo->DeleteRoute is TRUE).
- @retval EFI_ACCESS_DENIED The route is already defined in the routing table
- (when RouteInfo->DeleteRoute is FALSE).
- **/
- EFI_STATUS
- Tcp4Route (
- IN TCP_CB *Tcb,
- IN TCP4_ROUTE_INFO *RouteInfo
- )
- {
- IP_IO_IP_PROTOCOL Ip;
- Ip = Tcb->IpInfo->Ip;
- ASSERT (Ip.Ip4 != NULL);
- return Ip.Ip4->Routes (
- Ip.Ip4,
- RouteInfo->DeleteRoute,
- RouteInfo->SubnetAddress,
- RouteInfo->SubnetMask,
- RouteInfo->GatewayAddress
- );
- }
- /**
- Get the operational settings of this TCPv4 instance.
- @param[in] Tcb Pointer to the TCP_CB of this TCP instance.
- @param[in, out] Mode Pointer to the buffer to store the operational
- settings.
- @retval EFI_SUCCESS The mode data was 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);
- }
- /**
- Get the operational settings of this TCPv6 instance.
- @param[in] Tcb Pointer to the TCP_CB of this TCP instance.
- @param[in, out] Mode Pointer to the buffer to store the operational
- settings.
- @retval EFI_SUCCESS The mode data was read.
- @retval EFI_NOT_STARTED No configuration data is available because this
- instance hasn't been started.
- **/
- EFI_STATUS
- Tcp6GetMode (
- IN TCP_CB *Tcb,
- IN OUT TCP6_MODE_DATA *Mode
- )
- {
- SOCKET *Sock;
- EFI_TCP6_CONFIG_DATA *ConfigData;
- EFI_TCP6_ACCESS_POINT *AccessPoint;
- EFI_TCP6_OPTION *Option;
- EFI_IP6_PROTOCOL *Ip;
- Sock = Tcb->Sk;
- if (!SOCK_IS_CONFIGURED (Sock) && (Mode->Tcp6ConfigData != NULL)) {
- return EFI_NOT_STARTED;
- }
- if (Mode->Tcp6State != NULL) {
- *(Mode->Tcp6State) = (EFI_TCP6_CONNECTION_STATE)(Tcb->State);
- }
- if (Mode->Tcp6ConfigData != NULL) {
- ConfigData = Mode->Tcp6ConfigData;
- AccessPoint = &(ConfigData->AccessPoint);
- Option = ConfigData->ControlOption;
- ConfigData->TrafficClass = Tcb->Tos;
- ConfigData->HopLimit = Tcb->Ttl;
- AccessPoint->StationPort = NTOHS (Tcb->LocalEnd.Port);
- AccessPoint->RemotePort = NTOHS (Tcb->RemoteEnd.Port);
- AccessPoint->ActiveFlag = (BOOLEAN)(Tcb->State != TCP_LISTEN);
- IP6_COPY_ADDRESS (&AccessPoint->StationAddress, &Tcb->LocalEnd.Ip);
- IP6_COPY_ADDRESS (&AccessPoint->RemoteAddress, &Tcb->RemoteEnd.Ip);
- 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.Ip6;
- ASSERT (Ip != NULL);
- return Ip->GetModeData (Ip, Mode->Ip6ModeData, Mode->MnpConfigData, Mode->SnpModeData);
- }
- /**
- If TcpAp->StationPort isn't zero, check whether the access point
- is registered, else generate a random station port for this
- access point.
- @param[in] TcpAp Pointer to the access point.
- @param[in] IpVersion IP_VERSION_4 or IP_VERSION_6
- @retval EFI_SUCCESS The check passed or the port is assigned.
- @retval EFI_INVALID_PARAMETER The non-zero station port is already used.
- @retval EFI_OUT_OF_RESOURCES No port can be allocated.
- **/
- EFI_STATUS
- TcpBind (
- IN TCP_ACCESS_POINT *TcpAp,
- IN UINT8 IpVersion
- )
- {
- BOOLEAN Cycle;
- EFI_IP_ADDRESS Local;
- UINT16 *Port;
- UINT16 *RandomPort;
- if (IpVersion == IP_VERSION_4) {
- IP4_COPY_ADDRESS (&Local, &TcpAp->Tcp4Ap.StationAddress);
- Port = &TcpAp->Tcp4Ap.StationPort;
- RandomPort = &mTcp4RandomPort;
- } else {
- IP6_COPY_ADDRESS (&Local, &TcpAp->Tcp6Ap.StationAddress);
- Port = &TcpAp->Tcp6Ap.StationPort;
- RandomPort = &mTcp6RandomPort;
- }
- if (0 != *Port) {
- //
- // Check if a same endpoing is bound.
- //
- if (TcpFindTcbByPeer (&Local, *Port, IpVersion)) {
- return EFI_INVALID_PARAMETER;
- }
- } else {
- //
- // generate a random port
- //
- Cycle = FALSE;
- if (TCP_PORT_USER_RESERVED == *RandomPort) {
- *RandomPort = TCP_PORT_KNOWN;
- }
- (*RandomPort)++;
- while (TcpFindTcbByPeer (&Local, *RandomPort, IpVersion)) {
- (*RandomPort)++;
- if (*RandomPort <= TCP_PORT_KNOWN) {
- if (Cycle) {
- DEBUG (
- (DEBUG_ERROR,
- "TcpBind: no port can be allocated for this pcb\n")
- );
- return EFI_OUT_OF_RESOURCES;
- }
- *RandomPort = TCP_PORT_KNOWN + 1;
- Cycle = TRUE;
- }
- }
- *Port = *RandomPort;
- }
- return EFI_SUCCESS;
- }
- /**
- Flush the Tcb add its associated protocols.
- @param[in, out] Tcb Pointer to the TCP_CB to be flushed.
- **/
- VOID
- TcpFlushPcb (
- IN OUT TCP_CB *Tcb
- )
- {
- SOCKET *Sock;
- IpIoConfigIp (Tcb->IpInfo, NULL);
- Sock = Tcb->Sk;
- if (SOCK_IS_CONFIGURED (Sock)) {
- RemoveEntryList (&Tcb->List);
- if (Sock->DevicePath != NULL) {
- //
- // Uninstall the device path protocol.
- //
- gBS->UninstallProtocolInterface (
- Sock->SockHandle,
- &gEfiDevicePathProtocolGuid,
- Sock->DevicePath
- );
- FreePool (Sock->DevicePath);
- Sock->DevicePath = NULL;
- }
- }
- NetbufFreeList (&Tcb->SndQue);
- NetbufFreeList (&Tcb->RcvQue);
- Tcb->State = TCP_CLOSED;
- Tcb->RemoteIpZero = FALSE;
- }
- /**
- Attach a Pcb to the socket.
- @param[in] Sk Pointer to the socket of this TCP instance.
- @retval EFI_SUCCESS The operation completed successfully.
- @retval EFI_OUT_OF_RESOURCES Failed due to resource limits.
- **/
- EFI_STATUS
- TcpAttachPcb (
- IN SOCKET *Sk
- )
- {
- TCP_CB *Tcb;
- TCP_PROTO_DATA *ProtoData;
- IP_IO *IpIo;
- EFI_STATUS Status;
- VOID *Ip;
- EFI_GUID *IpProtocolGuid;
- if (Sk->IpVersion == IP_VERSION_4) {
- IpProtocolGuid = &gEfiIp4ProtocolGuid;
- } else {
- IpProtocolGuid = &gEfiIp6ProtocolGuid;
- }
- Tcb = AllocateZeroPool (sizeof (TCP_CB));
- if (Tcb == NULL) {
- DEBUG ((DEBUG_ERROR, "TcpConfigurePcb: failed to allocate a TCB\n"));
- return EFI_OUT_OF_RESOURCES;
- }
- ProtoData = (TCP_PROTO_DATA *)Sk->ProtoReserved;
- IpIo = ProtoData->TcpService->IpIo;
- //
- // Create an IpInfo for this Tcb.
- //
- Tcb->IpInfo = IpIoAddIp (IpIo);
- if (Tcb->IpInfo == NULL) {
- FreePool (Tcb);
- return EFI_OUT_OF_RESOURCES;
- }
- //
- // Open the new created IP instance BY_CHILD.
- //
- Status = gBS->OpenProtocol (
- Tcb->IpInfo->ChildHandle,
- IpProtocolGuid,
- &Ip,
- IpIo->Image,
- Sk->SockHandle,
- EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
- );
- if (EFI_ERROR (Status)) {
- IpIoRemoveIp (IpIo, Tcb->IpInfo);
- FreePool (Tcb);
- return Status;
- }
- InitializeListHead (&Tcb->List);
- InitializeListHead (&Tcb->SndQue);
- InitializeListHead (&Tcb->RcvQue);
- Tcb->State = TCP_CLOSED;
- Tcb->Sk = Sk;
- ProtoData->TcpPcb = Tcb;
- return EFI_SUCCESS;
- }
- /**
- Detach the Pcb of the socket.
- @param[in, out] Sk Pointer to the socket of this TCP instance.
- **/
- VOID
- TcpDetachPcb (
- IN OUT SOCKET *Sk
- )
- {
- TCP_PROTO_DATA *ProtoData;
- TCP_CB *Tcb;
- ProtoData = (TCP_PROTO_DATA *)Sk->ProtoReserved;
- Tcb = ProtoData->TcpPcb;
- ASSERT (Tcb != NULL);
- TcpFlushPcb (Tcb);
- IpIoRemoveIp (ProtoData->TcpService->IpIo, Tcb->IpInfo);
- FreePool (Tcb);
- ProtoData->TcpPcb = NULL;
- }
- /**
- Configure the Pcb using CfgData.
- @param[in] Sk Pointer to the socket of this TCP instance.
- @param[in] CfgData Pointer to the TCP configuration data.
- @retval EFI_SUCCESS The operation completed successfully.
- @retval EFI_INVALID_PARAMETER A same access point has been configured in
- another TCP instance.
- @retval EFI_OUT_OF_RESOURCES Failed due to resource limits.
- **/
- EFI_STATUS
- TcpConfigurePcb (
- IN SOCKET *Sk,
- IN TCP_CONFIG_DATA *CfgData
- )
- {
- IP_IO_IP_CONFIG_DATA IpCfgData;
- EFI_STATUS Status;
- EFI_TCP4_OPTION *Option;
- TCP_PROTO_DATA *TcpProto;
- TCP_CB *Tcb;
- TCP_ACCESS_POINT *TcpAp;
- ASSERT ((CfgData != NULL) && (Sk != NULL) && (Sk->SockHandle != NULL));
- TcpProto = (TCP_PROTO_DATA *)Sk->ProtoReserved;
- Tcb = TcpProto->TcpPcb;
- ASSERT (Tcb != NULL);
- if (Sk->IpVersion == IP_VERSION_4) {
- //
- // Add Ip for send pkt to the peer
- //
- CopyMem (&IpCfgData.Ip4CfgData, &mIp4IoDefaultIpConfigData, sizeof (EFI_IP4_CONFIG_DATA));
- IpCfgData.Ip4CfgData.DefaultProtocol = EFI_IP_PROTO_TCP;
- IpCfgData.Ip4CfgData.TypeOfService = CfgData->Tcp4CfgData.TypeOfService;
- IpCfgData.Ip4CfgData.TimeToLive = CfgData->Tcp4CfgData.TimeToLive;
- IpCfgData.Ip4CfgData.UseDefaultAddress = CfgData->Tcp4CfgData.AccessPoint.UseDefaultAddress;
- IP4_COPY_ADDRESS (
- &IpCfgData.Ip4CfgData.SubnetMask,
- &CfgData->Tcp4CfgData.AccessPoint.SubnetMask
- );
- IpCfgData.Ip4CfgData.ReceiveTimeout = (UINT32)(-1);
- IP4_COPY_ADDRESS (
- &IpCfgData.Ip4CfgData.StationAddress,
- &CfgData->Tcp4CfgData.AccessPoint.StationAddress
- );
- } else {
- ASSERT (Sk->IpVersion == IP_VERSION_6);
- CopyMem (&IpCfgData.Ip6CfgData, &mIp6IoDefaultIpConfigData, sizeof (EFI_IP6_CONFIG_DATA));
- IpCfgData.Ip6CfgData.DefaultProtocol = EFI_IP_PROTO_TCP;
- IpCfgData.Ip6CfgData.TrafficClass = CfgData->Tcp6CfgData.TrafficClass;
- IpCfgData.Ip6CfgData.HopLimit = CfgData->Tcp6CfgData.HopLimit;
- IpCfgData.Ip6CfgData.ReceiveTimeout = (UINT32)(-1);
- IP6_COPY_ADDRESS (
- &IpCfgData.Ip6CfgData.StationAddress,
- &CfgData->Tcp6CfgData.AccessPoint.StationAddress
- );
- IP6_COPY_ADDRESS (
- &IpCfgData.Ip6CfgData.DestinationAddress,
- &CfgData->Tcp6CfgData.AccessPoint.RemoteAddress
- );
- }
- //
- // Configure the IP instance this Tcb consumes.
- //
- Status = IpIoConfigIp (Tcb->IpInfo, &IpCfgData);
- if (EFI_ERROR (Status)) {
- goto OnExit;
- }
- if (Sk->IpVersion == IP_VERSION_4) {
- //
- // Get the default address information if the instance is configured to use default address.
- //
- IP4_COPY_ADDRESS (
- &CfgData->Tcp4CfgData.AccessPoint.StationAddress,
- &IpCfgData.Ip4CfgData.StationAddress
- );
- IP4_COPY_ADDRESS (
- &CfgData->Tcp4CfgData.AccessPoint.SubnetMask,
- &IpCfgData.Ip4CfgData.SubnetMask
- );
- TcpAp = (TCP_ACCESS_POINT *)&CfgData->Tcp4CfgData.AccessPoint;
- } else {
- IP6_COPY_ADDRESS (
- &CfgData->Tcp6CfgData.AccessPoint.StationAddress,
- &IpCfgData.Ip6CfgData.StationAddress
- );
- TcpAp = (TCP_ACCESS_POINT *)&CfgData->Tcp6CfgData.AccessPoint;
- }
- //
- // check if we can bind this endpoint in CfgData
- //
- Status = TcpBind (TcpAp, Sk->IpVersion);
- if (EFI_ERROR (Status)) {
- DEBUG (
- (DEBUG_ERROR,
- "TcpConfigurePcb: Bind endpoint failed with %r\n",
- Status)
- );
- goto OnExit;
- }
- //
- // Initialize the operating information in this Tcb
- //
- ASSERT (
- Tcb->State == TCP_CLOSED &&
- IsListEmpty (&Tcb->SndQue) &&
- IsListEmpty (&Tcb->RcvQue)
- );
- TCP_SET_FLG (Tcb->CtrlFlag, TCP_CTRL_NO_KEEPALIVE);
- Tcb->State = TCP_CLOSED;
- Tcb->SndMss = 536;
- Tcb->RcvMss = TcpGetRcvMss (Sk);
- Tcb->SRtt = 0;
- Tcb->Rto = 3 * TCP_TICK_HZ;
- Tcb->CWnd = Tcb->SndMss;
- Tcb->Ssthresh = 0xffffffff;
- Tcb->CongestState = TCP_CONGEST_OPEN;
- Tcb->KeepAliveIdle = TCP_KEEPALIVE_IDLE_MIN;
- Tcb->KeepAlivePeriod = TCP_KEEPALIVE_PERIOD;
- Tcb->MaxKeepAlive = TCP_MAX_KEEPALIVE;
- Tcb->MaxRexmit = TCP_MAX_LOSS;
- Tcb->FinWait2Timeout = TCP_FIN_WAIT2_TIME;
- Tcb->TimeWaitTimeout = TCP_TIME_WAIT_TIME;
- Tcb->ConnectTimeout = TCP_CONNECT_TIME;
- if (Sk->IpVersion == IP_VERSION_4) {
- //
- // initialize Tcb in the light of CfgData
- //
- Tcb->Ttl = CfgData->Tcp4CfgData.TimeToLive;
- Tcb->Tos = CfgData->Tcp4CfgData.TypeOfService;
- Tcb->UseDefaultAddr = CfgData->Tcp4CfgData.AccessPoint.UseDefaultAddress;
- CopyMem (&Tcb->LocalEnd.Ip, &CfgData->Tcp4CfgData.AccessPoint.StationAddress, sizeof (IP4_ADDR));
- Tcb->LocalEnd.Port = HTONS (CfgData->Tcp4CfgData.AccessPoint.StationPort);
- IP4_COPY_ADDRESS (&Tcb->SubnetMask, &CfgData->Tcp4CfgData.AccessPoint.SubnetMask);
- CopyMem (&Tcb->RemoteEnd.Ip, &CfgData->Tcp4CfgData.AccessPoint.RemoteAddress, sizeof (IP4_ADDR));
- Tcb->RemoteEnd.Port = HTONS (CfgData->Tcp4CfgData.AccessPoint.RemotePort);
- Option = CfgData->Tcp4CfgData.ControlOption;
- } else {
- Tcb->Ttl = CfgData->Tcp6CfgData.HopLimit;
- Tcb->Tos = CfgData->Tcp6CfgData.TrafficClass;
- IP6_COPY_ADDRESS (&Tcb->LocalEnd.Ip, &CfgData->Tcp6CfgData.AccessPoint.StationAddress);
- Tcb->LocalEnd.Port = HTONS (CfgData->Tcp6CfgData.AccessPoint.StationPort);
- IP6_COPY_ADDRESS (&Tcb->RemoteEnd.Ip, &CfgData->Tcp6CfgData.AccessPoint.RemoteAddress);
- Tcb->RemoteEnd.Port = HTONS (CfgData->Tcp6CfgData.AccessPoint.RemotePort);
- //
- // Type EFI_TCP4_OPTION and EFI_TCP6_OPTION are the same.
- //
- Option = (EFI_TCP4_OPTION *)CfgData->Tcp6CfgData.ControlOption;
- }
- if (Option != NULL) {
- SET_RCV_BUFFSIZE (
- Sk,
- (UINT32)(TCP_COMP_VAL (
- TCP_RCV_BUF_SIZE_MIN,
- TCP_RCV_BUF_SIZE,
- TCP_RCV_BUF_SIZE,
- Option->ReceiveBufferSize
- )
- )
- );
- SET_SND_BUFFSIZE (
- Sk,
- (UINT32)(TCP_COMP_VAL (
- TCP_SND_BUF_SIZE_MIN,
- TCP_SND_BUF_SIZE,
- TCP_SND_BUF_SIZE,
- Option->SendBufferSize
- )
- )
- );
- SET_BACKLOG (
- Sk,
- (UINT32)(TCP_COMP_VAL (
- TCP_BACKLOG_MIN,
- TCP_BACKLOG,
- TCP_BACKLOG,
- Option->MaxSynBackLog
- )
- )
- );
- Tcb->MaxRexmit = (UINT16)TCP_COMP_VAL (
- TCP_MAX_LOSS_MIN,
- TCP_MAX_LOSS,
- TCP_MAX_LOSS,
- Option->DataRetries
- );
- Tcb->FinWait2Timeout = TCP_COMP_VAL (
- TCP_FIN_WAIT2_TIME,
- TCP_FIN_WAIT2_TIME_MAX,
- TCP_FIN_WAIT2_TIME,
- (UINT32)(Option->FinTimeout * TCP_TICK_HZ)
- );
- if (Option->TimeWaitTimeout != 0) {
- Tcb->TimeWaitTimeout = TCP_COMP_VAL (
- TCP_TIME_WAIT_TIME,
- TCP_TIME_WAIT_TIME_MAX,
- TCP_TIME_WAIT_TIME,
- (UINT32)(Option->TimeWaitTimeout * TCP_TICK_HZ)
- );
- } else {
- Tcb->TimeWaitTimeout = 0;
- }
- if (Option->KeepAliveProbes != 0) {
- TCP_CLEAR_FLG (Tcb->CtrlFlag, TCP_CTRL_NO_KEEPALIVE);
- Tcb->MaxKeepAlive = (UINT8)TCP_COMP_VAL (
- TCP_MAX_KEEPALIVE_MIN,
- TCP_MAX_KEEPALIVE,
- TCP_MAX_KEEPALIVE,
- Option->KeepAliveProbes
- );
- Tcb->KeepAliveIdle = TCP_COMP_VAL (
- TCP_KEEPALIVE_IDLE_MIN,
- TCP_KEEPALIVE_IDLE_MAX,
- TCP_KEEPALIVE_IDLE_MIN,
- (UINT32)(Option->KeepAliveTime * TCP_TICK_HZ)
- );
- Tcb->KeepAlivePeriod = TCP_COMP_VAL (
- TCP_KEEPALIVE_PERIOD_MIN,
- TCP_KEEPALIVE_PERIOD,
- TCP_KEEPALIVE_PERIOD,
- (UINT32)(Option->KeepAliveInterval * TCP_TICK_HZ)
- );
- }
- Tcb->ConnectTimeout = TCP_COMP_VAL (
- TCP_CONNECT_TIME_MIN,
- TCP_CONNECT_TIME,
- TCP_CONNECT_TIME,
- (UINT32)(Option->ConnectionTimeout * TCP_TICK_HZ)
- );
- if (!Option->EnableNagle) {
- TCP_SET_FLG (Tcb->CtrlFlag, TCP_CTRL_NO_NAGLE);
- }
- if (!Option->EnableTimeStamp) {
- TCP_SET_FLG (Tcb->CtrlFlag, TCP_CTRL_NO_TS);
- }
- if (!Option->EnableWindowScaling) {
- TCP_SET_FLG (Tcb->CtrlFlag, TCP_CTRL_NO_WS);
- }
- }
- //
- // The socket is bound, the <SrcIp, SrcPort, DstIp, DstPort> is
- // determined, construct the IP device path and install it.
- //
- Status = TcpInstallDevicePath (Sk);
- if (EFI_ERROR (Status)) {
- goto OnExit;
- }
- //
- // update state of Tcb and socket
- //
- if (((Sk->IpVersion == IP_VERSION_4) && !CfgData->Tcp4CfgData.AccessPoint.ActiveFlag) ||
- ((Sk->IpVersion == IP_VERSION_6) && !CfgData->Tcp6CfgData.AccessPoint.ActiveFlag)
- )
- {
- TcpSetState (Tcb, TCP_LISTEN);
- SockSetState (Sk, SO_LISTENING);
- Sk->ConfigureState = SO_CONFIGURED_PASSIVE;
- } else {
- Sk->ConfigureState = SO_CONFIGURED_ACTIVE;
- }
- if (Sk->IpVersion == IP_VERSION_6) {
- Tcb->Tick = TCP6_REFRESH_NEIGHBOR_TICK;
- if (NetIp6IsUnspecifiedAddr (&Tcb->RemoteEnd.Ip.v6)) {
- Tcb->RemoteIpZero = TRUE;
- }
- }
- TcpInsertTcb (Tcb);
- OnExit:
- return Status;
- }
- /**
- The protocol handler provided to the socket layer, which is used to
- dispatch the socket level requests by calling the corresponding
- TCP layer functions.
- @param[in] Sock Pointer to the socket of this TCP instance.
- @param[in] Request The code of this operation request.
- @param[in] Data Pointer to the operation specific data passed in
- together with the operation request. This is an
- optional parameter that may be NULL.
- @retval EFI_SUCCESS The socket request completed successfully.
- @retval other The error status returned by the corresponding TCP
- layer function.
- **/
- EFI_STATUS
- TcpDispatcher (
- IN SOCKET *Sock,
- IN UINT8 Request,
- IN VOID *Data OPTIONAL
- )
- {
- TCP_CB *Tcb;
- TCP_PROTO_DATA *ProtoData;
- ProtoData = (TCP_PROTO_DATA *)Sock->ProtoReserved;
- Tcb = ProtoData->TcpPcb;
- switch (Request) {
- case SOCK_POLL:
- if (Tcb->Sk->IpVersion == IP_VERSION_4) {
- ProtoData->TcpService->IpIo->Ip.Ip4->Poll (ProtoData->TcpService->IpIo->Ip.Ip4);
- } else {
- ProtoData->TcpService->IpIo->Ip.Ip6->Poll (ProtoData->TcpService->IpIo->Ip.Ip6);
- }
- break;
- case SOCK_CONSUMED:
- //
- // After user received data from socket buffer, socket will
- // notify TCP using this message to give it a chance to send out
- // window update information
- //
- ASSERT (Tcb != NULL);
- TcpOnAppConsume (Tcb);
- break;
- case SOCK_SND:
- ASSERT (Tcb != NULL);
- TcpOnAppSend (Tcb);
- break;
- case SOCK_CLOSE:
- TcpOnAppClose (Tcb);
- break;
- case SOCK_ABORT:
- TcpOnAppAbort (Tcb);
- break;
- case SOCK_SNDPUSH:
- Tcb->SndPsh = TcpGetMaxSndNxt (Tcb) + GET_SND_DATASIZE (Tcb->Sk);
- TCP_SET_FLG (Tcb->CtrlFlag, TCP_CTRL_SND_PSH);
- break;
- case SOCK_SNDURG:
- Tcb->SndUp = TcpGetMaxSndNxt (Tcb) + GET_SND_DATASIZE (Tcb->Sk) - 1;
- TCP_SET_FLG (Tcb->CtrlFlag, TCP_CTRL_SND_URG);
- break;
- case SOCK_CONNECT:
- TcpOnAppConnect (Tcb);
- break;
- case SOCK_ATTACH:
- return TcpAttachPcb (Sock);
- break;
- case SOCK_FLUSH:
- TcpFlushPcb (Tcb);
- break;
- case SOCK_DETACH:
- TcpDetachPcb (Sock);
- break;
- case SOCK_CONFIGURE:
- return TcpConfigurePcb (
- Sock,
- (TCP_CONFIG_DATA *)Data
- );
- break;
- case SOCK_MODE:
- ASSERT ((Data != NULL) && (Tcb != NULL));
- if (Tcb->Sk->IpVersion == IP_VERSION_4) {
- return Tcp4GetMode (Tcb, (TCP4_MODE_DATA *)Data);
- } else {
- return Tcp6GetMode (Tcb, (TCP6_MODE_DATA *)Data);
- }
- break;
- case SOCK_ROUTE:
- ASSERT ((Data != NULL) && (Tcb != NULL) && (Tcb->Sk->IpVersion == IP_VERSION_4));
- return Tcp4Route (Tcb, (TCP4_ROUTE_INFO *)Data);
- default:
- return EFI_UNSUPPORTED;
- }
- return EFI_SUCCESS;
- }
|