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 + -
显示快捷键?