Ejemplo n.º 1
0
/**
  Clone a new socket including its associated protocol control block.

  @param  Sock                  Pointer to the socket to be cloned.

  @return Pointer to the newly cloned socket. If NULL, error condition occurred.

**/
SOCKET *
SockClone (
  IN SOCKET *Sock
  )
{
  SOCKET          *ClonedSock;
  SOCK_INIT_DATA  InitData;

  InitData.BackLog         = Sock->BackLog;
  InitData.Parent          = Sock;
  InitData.State           = Sock->State;
  InitData.ProtoHandler    = Sock->ProtoHandler;
  InitData.Type            = Sock->Type;
  InitData.RcvBufferSize   = Sock->RcvBuffer.HighWater;
  InitData.SndBufferSize   = Sock->SndBuffer.HighWater;
  InitData.DriverBinding   = Sock->DriverBinding;
  InitData.Protocol        = &(Sock->NetProtocol);
  InitData.CreateCallback  = Sock->CreateCallback;
  InitData.DestroyCallback = Sock->DestroyCallback;
  InitData.Context         = Sock->Context;
  InitData.ProtoData       = Sock->ProtoReserved;
  InitData.DataSize        = sizeof (Sock->ProtoReserved);

  ClonedSock               = SockCreate (&InitData);

  if (NULL == ClonedSock) {
    DEBUG ((EFI_D_ERROR, "SockClone: no resource to create a cloned sock\n"));
    return NULL;
  }

  SockSetState (ClonedSock, SO_CONNECTING);
  ClonedSock->ConfigureState = Sock->ConfigureState;

  return ClonedSock;
}
Ejemplo n.º 2
0
/**
  Called by the low layer protocol to indicate the socket a connection is
  established.

  This function just changes the socket's state to SO_CONNECTED
  and signals the token used for connection establishment.

  @param[in, out]  Sock         Pointer to the socket associated with the
                                established connection.

**/
VOID
SockConnEstablished (
  IN OUT SOCKET *Sock
  )
{

  ASSERT (SO_CONNECTING == Sock->State);

  SockSetState (Sock, SO_CONNECTED);

  if (NULL == Sock->Parent) {
    SockWakeConnToken (Sock);
  } else {
    SockWakeListenToken (Sock);
  }

}
Ejemplo n.º 3
0
/**
  Destroy a socket.

  @param  Sock                  Pointer to the socket.

**/
VOID
SockDestroy (
  IN OUT SOCKET *Sock
  )
{
  ASSERT (SockStream == Sock->Type);

  //
  // Flush the completion token buffered
  // by sock and rcv, snd buffer
  //
  if (!SOCK_IS_UNCONFIGURED (Sock)) {

    SockConnFlush (Sock);
    SockSetState (Sock, SO_CLOSED);
    Sock->ConfigureState = SO_UNCONFIGURED;

  }
  //
  // Destroy the RcvBuffer Queue and SendBuffer Queue
  //
  NetbufQueFree (Sock->RcvBuffer.DataQueue);
  NetbufQueFree (Sock->SndBuffer.DataQueue);

  //
  // Remove it from parent connection list if needed
  //
  if (Sock->Parent != NULL) {

    RemoveEntryList (&(Sock->ConnectionList));
    (Sock->Parent->ConnCnt)--;

    DEBUG (
      (EFI_D_NET,
      "SockDestroy: Delete a unaccepted socket from parent"
      "now conncnt is %d\n",
      Sock->Parent->ConnCnt)
      );

    Sock->Parent = NULL;
  }

  FreePool (Sock);
  return ;
}
Ejemplo n.º 4
0
/**
  Called by the low layer protocol to indicate the connection is closed.

  This function flushes the socket, sets the state to SO_CLOSED and signals
  the close token.

  @param  Sock                  Pointer to the socket associated with the closed
                                connection.

**/
VOID
SockConnClosed (
  IN OUT SOCKET *Sock
  )
{
  if (Sock->CloseToken != NULL) {
    SIGNAL_TOKEN (Sock->CloseToken, EFI_SUCCESS);
    Sock->CloseToken = NULL;
  }

  SockConnFlush (Sock);
  SockSetState (Sock, SO_CLOSED);

  if (Sock->Parent != NULL) {
    SockDestroyChild (Sock);
  }

}
Ejemplo n.º 5
0
/**
  Configure the Pcb using CfgData.

  @param  Sk                     Pointer to the socket of this TCP instance.
  @param  CfgData                Pointer to the TCP configuration data.

  @retval EFI_SUCCESS            The operation is 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 limit.

**/
EFI_STATUS
Tcp4ConfigurePcb (
  IN SOCKET               *Sk,
  IN EFI_TCP4_CONFIG_DATA *CfgData
  )
{
  EFI_IP4_CONFIG_DATA IpCfgData;
  EFI_STATUS          Status;
  EFI_TCP4_OPTION     *Option;
  TCP4_PROTO_DATA     *TcpProto;
  TCP_CB              *Tcb;

  ASSERT ((CfgData != NULL) && (Sk != NULL) && (Sk->SockHandle != NULL));

  TcpProto = (TCP4_PROTO_DATA *) Sk->ProtoReserved;
  Tcb      = TcpProto->TcpPcb;

  ASSERT (Tcb != NULL);

  //
  // Add Ip for send pkt to the peer
  //
  CopyMem (&IpCfgData, &mIp4IoDefaultIpConfigData, sizeof (IpCfgData));
  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)) {
    DEBUG ((EFI_D_ERROR, "Tcp4ConfigurePcb: Bind endpoint failed "
      "with %r\n", Status));

    goto OnExit;
  }

  //
  // Initalize 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;

  //
  // initialize Tcb in the light of CfgData
  //
  Tcb->Ttl            = CfgData->TimeToLive;
  Tcb->Tos            = CfgData->TypeOfService;

  Tcb->UseDefaultAddr = CfgData->AccessPoint.UseDefaultAddress;

  CopyMem (&Tcb->LocalEnd.Ip, &CfgData->AccessPoint.StationAddress, sizeof (IP4_ADDR));
  Tcb->LocalEnd.Port  = HTONS (CfgData->AccessPoint.StationPort);
  IP4_COPY_ADDRESS (&Tcb->SubnetMask, &CfgData->AccessPoint.SubnetMask);

  if (CfgData->AccessPoint.ActiveFlag) {
    CopyMem (&Tcb->RemoteEnd.Ip, &CfgData->AccessPoint.RemoteAddress, sizeof (IP4_ADDR));
    Tcb->RemoteEnd.Port = HTONS (CfgData->AccessPoint.RemotePort);
  } else {
    Tcb->RemoteEnd.Ip   = 0;
    Tcb->RemoteEnd.Port = 0;
  }

  Option              = CfgData->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 (!CfgData->AccessPoint.ActiveFlag) {

    TcpSetState (Tcb, TCP_LISTEN);
    SockSetState (Sk, SO_LISTENING);

    Sk->ConfigureState = SO_CONFIGURED_PASSIVE;
  } else {

    Sk->ConfigureState = SO_CONFIGURED_ACTIVE;
  }

  TcpInsertTcb (Tcb);

OnExit:

  return Status;
}
Ejemplo n.º 6
0
/**
  Destroy a socket.

  @param  Sock                  Pointer to the socket.

**/
VOID
SockDestroy (
  IN OUT SOCKET *Sock
  )
{
  VOID        *SockProtocol;
  EFI_GUID    *ProtocolGuid;
  EFI_STATUS  Status;

  ASSERT (SockStream == Sock->Type);

  if (Sock->DestroyCallback != NULL) {
    Sock->DestroyCallback (Sock, Sock->Context);
  }

  //
  // Flush the completion token buffered
  // by sock and rcv, snd buffer
  //
  if (!SOCK_IS_UNCONFIGURED (Sock)) {

    SockConnFlush (Sock);
    SockSetState (Sock, SO_CLOSED);
    Sock->ConfigureState = SO_UNCONFIGURED;

  }
  //
  // Destory the RcvBuffer Queue and SendBuffer Queue
  //
  NetbufQueFree (Sock->RcvBuffer.DataQueue);
  NetbufQueFree (Sock->SndBuffer.DataQueue);

  //
  // Remove it from parent connection list if needed
  //
  if (Sock->Parent != NULL) {

    RemoveEntryList (&(Sock->ConnectionList));
    (Sock->Parent->ConnCnt)--;

    DEBUG (
      (EFI_D_INFO,
      "SockDestory: Delete a unaccepted socket from parent"
      "now conncnt is %d\n",
      Sock->Parent->ConnCnt)
      );

    Sock->Parent = NULL;
  }

  //
  // Set the protocol guid and driver binding handle
  // in the light of Sock->SockType
  //
  ProtocolGuid = &gEfiTcp4ProtocolGuid;

  //
  // Retrieve the protocol installed on this sock
  //
  Status = gBS->OpenProtocol (
                  Sock->SockHandle,
                  ProtocolGuid,
                  &SockProtocol,
                  Sock->DriverBinding,
                  Sock->SockHandle,
                  EFI_OPEN_PROTOCOL_GET_PROTOCOL
                  );

  if (EFI_ERROR (Status)) {

    DEBUG ((EFI_D_ERROR, "SockDestroy: Open protocol installed "
      "on socket failed with %r\n", Status));

    goto FreeSock;
  }

  //
  // Uninstall the protocol installed on this sock
  // in the light of Sock->SockType
  //
  gBS->UninstallMultipleProtocolInterfaces (
        Sock->SockHandle,
        ProtocolGuid,
        SockProtocol,
        NULL
        );

FreeSock:
  FreePool (Sock);
  return ;
}