tcp4dispatcher.c
来自「EFI BIOS是Intel提出的下一代的BIOS标准。这里上传的Edk源代码是」· C语言 代码 · 共 709 行 · 第 1/2 页
C
709 行
Returns:
EFI_SUCCESS - The operation is completed successfully.
EFI_INVALID_PARAMETER - A same access point has been configured in
another TCP instance.
EFI_OUT_OF_RESOURCES - Failed due to resource limit.
--*/
{
IP_IO *IpIo;
EFI_IP4_CONFIG_DATA IpCfgData;
EFI_STATUS Status;
EFI_TCP4_OPTION *Option;
TCP4_PROTO_DATA *TcpProto;
TCP_CB *Tcb;
ASSERT (CfgData && Sk && Sk->SockHandle);
TcpProto = (TCP4_PROTO_DATA *) Sk->ProtoReserved;
Tcb = TcpProto->TcpPcb;
IpIo = TcpProto->TcpService->IpIo;
ASSERT (Tcb != NULL);
//
// Add Ip for send pkt to the peer
//
IpCfgData = mIpIoDefaultIpConfigData;
IpCfgData.DefaultProtocol = EFI_IP_PROTO_TCP;
IpCfgData.UseDefaultAddress = CfgData->AccessPoint.UseDefaultAddress;
IpCfgData.StationAddress = CfgData->AccessPoint.StationAddress;
IpCfgData.SubnetMask = CfgData->AccessPoint.SubnetMask;
IpCfgData.ReceiveTimeout = (UINT32) (-1);
//
// Configure the IP instance this Tcb consumes.
//
Status = IpIoConfigIp (Tcb->IpInfo, &IpCfgData);
if (EFI_ERROR (Status)) {
goto OnExit;
}
//
// Get the default address info if the instance is configured to use default address.
//
if (CfgData->AccessPoint.UseDefaultAddress) {
CfgData->AccessPoint.StationAddress = IpCfgData.StationAddress;
CfgData->AccessPoint.SubnetMask = IpCfgData.SubnetMask;
}
//
// check if we can bind this endpoint in CfgData
//
Status = Tcp4Bind (&(CfgData->AccessPoint));
if (EFI_ERROR (Status)) {
TCP4_DEBUG_ERROR (("Tcp4ConfigurePcb: Bind endpoint failed "
"with %r\n", Status));
goto OnExit;
}
//
// Initalize the operating information in this Tcb
//
ASSERT (Tcb->State == TCP_CLOSED &&
NetListIsEmpty (&Tcb->SndQue) &&
NetListIsEmpty (&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;
//
// initialize Tcb in the light of CfgData
//
Tcb->TTL = CfgData->TimeToLive;
Tcb->TOS = CfgData->TypeOfService;
Tcb->LocalEnd.Ip = EFI_IP4 (CfgData->AccessPoint.StationAddress);
Tcb->LocalEnd.Port = HTONS (CfgData->AccessPoint.StationPort);
Tcb->SubnetMask = CfgData->AccessPoint.SubnetMask;
Tcb->RemoteEnd.Ip = EFI_IP4 (CfgData->AccessPoint.RemoteAddress);
Tcb->RemoteEnd.Port = HTONS (CfgData->AccessPoint.RemotePort);
Option = CfgData->ControlOption;
if (Option != NULL) {
SET_RCV_BUFFSIZE (
Sk,
TCP_COMP_VAL (TCP_RCV_BUF_SIZE_MIN,
TCP_RCV_BUF_SIZE,
TCP_RCV_BUF_SIZE,
Option->ReceiveBufferSize)
);
SET_SND_BUFFSIZE (
Sk,
TCP_COMP_VAL (TCP_SND_BUF_SIZE_MIN,
TCP_SND_BUF_SIZE,
TCP_SND_BUF_SIZE,
Option->SendBufferSize)
);
SET_BACKLOG (
Sk,
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,
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,
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,
Option->KeepAliveTime * TCP_TICK_HZ
);
Tcb->KeepAlivePeriod = TCP_COMP_VAL (
TCP_KEEPALIVE_PERIOD_MIN,
TCP_KEEPALIVE_PERIOD,
TCP_KEEPALIVE_PERIOD,
Option->KeepAliveInterval * TCP_TICK_HZ
);
}
Tcb->ConnectTimeout = TCP_COMP_VAL (
TCP_CONNECT_TIME_MIN,
TCP_CONNECT_TIME,
TCP_CONNECT_TIME,
Option->ConnectionTimeout * TCP_TICK_HZ
);
if (Option->EnableNagle == FALSE) {
TCP_SET_FLG (Tcb->CtrlFlag, TCP_CTRL_NO_NAGLE);
}
if (Option->EnableTimeStamp == FALSE) {
TCP_SET_FLG (Tcb->CtrlFlag, TCP_CTRL_NO_TS);
}
if (Option->EnableWindowScaling == FALSE) {
TCP_SET_FLG (Tcb->CtrlFlag, TCP_CTRL_NO_WS);
}
}
//
// update state of Tcb and socket
//
if (CfgData->AccessPoint.ActiveFlag == FALSE) {
TcpSetState (Tcb, TCP_LISTEN);
SockSetState (Sk, SO_LISTENING);
Sk->ConfigureState = SO_CONFIGURED_PASSIVE;
} else {
Sk->ConfigureState = SO_CONFIGURED_ACTIVE;
}
TcpInsertTcb (Tcb);
OnExit:
return Status;
}
EFI_STATUS
Tcp4Dispatcher (
IN SOCKET *Sock,
IN SOCK_REQUEST Request,
IN VOID *Data OPTIONAL
)
/*++
Routine Description:
The procotol handler provided to the socket layer, used to
dispatch the socket level requests by calling the corresponding
TCP layer functions.
Arguments:
Sock - Pointer to the socket of this TCP instance.
Request - The code of this operation request.
Data - Pointer to the operation specific data passed in
together with the operation request.
Returns:
EFI_SUCCESS - The socket request is completed successfully.
other - The error status returned by the corresponding
TCP layer function.
--*/
{
TCP_CB *Tcb;
TCP4_PROTO_DATA *ProtoData;
EFI_IP4_PROTOCOL *Ip;
ProtoData = (TCP4_PROTO_DATA *) Sock->ProtoReserved;
Tcb = ProtoData->TcpPcb;
switch (Request) {
case SOCK_POLL:
Ip = ProtoData->TcpService->IpIo->Ip;
Ip->Poll (Ip);
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);
TcpOnAppConsume (Tcb);
break;
case SOCK_SND:
ASSERT (Tcb);
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 Tcp4AttachPcb (Sock);
break;
case SOCK_FLUSH:
Tcp4FlushPcb (Tcb);
break;
case SOCK_DETACH:
Tcp4DetachPcb (Sock);
break;
case SOCK_CONFIGURE:
return Tcp4ConfigurePcb (
Sock,
(EFI_TCP4_CONFIG_DATA *) Data
);
break;
case SOCK_MODE:
ASSERT (Data && Tcb);
return Tcp4GetMode (Tcb, (TCP4_MODE_DATA *) Data);
break;
case SOCK_ROUTE:
ASSERT (Data && Tcb);
return Tcp4Route (Tcb, (TCP4_ROUTE_INFO *) Data);
}
return EFI_SUCCESS;
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?