Exemplo n.º 1
0
/**
  Flush the sndBuffer and rcvBuffer of socket.

  @param  Sock                  Pointer to the socket.

**/
VOID
SockConnFlush (
  IN OUT SOCKET *Sock
  )
{
  SOCKET  *Child;

  ASSERT (Sock != NULL);

  //
  // Clear the flag in this socket
  //
  Sock->Flag = 0;

  //
  // Flush the SndBuffer and RcvBuffer of Sock
  //
  NetbufQueFlush (Sock->SndBuffer.DataQueue);
  NetbufQueFlush (Sock->RcvBuffer.DataQueue);

  //
  // Signal the pending token
  //
  if (Sock->ConnectionToken != NULL) {
    SIGNAL_TOKEN (Sock->ConnectionToken, Sock->SockError);
    Sock->ConnectionToken = NULL;
  }

  if (Sock->CloseToken != NULL) {
    SIGNAL_TOKEN (Sock->CloseToken, Sock->SockError);
    Sock->CloseToken = NULL;
  }

  SockFlushPendingToken (Sock, &(Sock->ListenTokenList));
  SockFlushPendingToken (Sock, &(Sock->RcvTokenList));
  SockFlushPendingToken (Sock, &(Sock->SndTokenList));
  SockFlushPendingToken (Sock, &(Sock->ProcessingSndTokenList));

  //
  // Destroy the pending connection, if it is a listening socket
  //
  if (SOCK_IS_LISTENING (Sock)) {
    while (!IsListEmpty (&Sock->ConnectionList)) {
      Child = NET_LIST_HEAD (
                &Sock->ConnectionList,
                SOCKET,
                ConnectionList
                );

      SockDestroyChild (Child);
    }

    Sock->ConnCnt = 0;
  }

  return ;
}
Exemplo n.º 2
0
/**
  Wake up the listen token while the connection is established successfully.

  @param[in, out]  Sock                  Pointer to the socket.

**/
VOID
SockWakeListenToken (
  IN OUT SOCKET *Sock
  )
{
  SOCKET                *Parent;
  SOCK_TOKEN            *SockToken;
  EFI_TCP4_LISTEN_TOKEN *ListenToken;

  Parent = Sock->Parent;

  ASSERT ((Parent != NULL) && SOCK_IS_LISTENING (Parent) && SOCK_IS_CONNECTED (Sock));

  if (!IsListEmpty (&Parent->ListenTokenList)) {
    SockToken = NET_LIST_HEAD (
                  &Parent->ListenTokenList,
                  SOCK_TOKEN,
                  TokenList
                  );

    ListenToken                 = (EFI_TCP4_LISTEN_TOKEN *) SockToken->Token;
    ListenToken->NewChildHandle = Sock->SockHandle;

    SIGNAL_TOKEN (&(ListenToken->CompletionToken), EFI_SUCCESS);

    RemoveEntryList (&SockToken->TokenList);
    FreePool (SockToken);

    RemoveEntryList (&Sock->ConnectionList);

    Parent->ConnCnt--;
    DEBUG (
      (EFI_D_NET,
      "SockWakeListenToken: accept a socket, now conncnt is %d",
      Parent->ConnCnt)
      );

    Sock->Parent = NULL;
  }
}
Exemplo n.º 3
0
/**
  Create a socket with initial data SockInitData.

  @param  SockInitData          Pointer to the initial data of the socket.

  @return Pointer to the newly created socket, return NULL when exception occured.

**/
SOCKET *
SockCreate (
  IN SOCK_INIT_DATA *SockInitData
  )
{
  SOCKET      *Sock;
  SOCKET      *Parent;
  EFI_STATUS  Status;

  ASSERT ((SockInitData != NULL) && (SockInitData->ProtoHandler != NULL));
  ASSERT (SockInitData->Type == SockStream);
  ASSERT ((SockInitData->ProtoData != NULL) && (SockInitData->DataSize <= PROTO_RESERVED_LEN));

  Parent = SockInitData->Parent;

  if ((Parent != NULL) && (Parent->ConnCnt == Parent->BackLog)) {
    DEBUG (
      (EFI_D_ERROR,
      "SockCreate: Socket parent has "
      "reached its connection limit with %d ConnCnt and %d BackLog\n",
      Parent->ConnCnt,
      Parent->BackLog)
      );

    return NULL;
  }

  Sock = AllocateZeroPool (sizeof (SOCKET));
  if (NULL == Sock) {

    DEBUG ((EFI_D_ERROR, "SockCreate: No resource to create a new socket\n"));
    return NULL;
  }

  InitializeListHead (&Sock->Link);
  InitializeListHead (&Sock->ConnectionList);
  InitializeListHead (&Sock->ListenTokenList);
  InitializeListHead (&Sock->RcvTokenList);
  InitializeListHead (&Sock->SndTokenList);
  InitializeListHead (&Sock->ProcessingSndTokenList);

  EfiInitializeLock (&(Sock->Lock), TPL_CALLBACK);

  Sock->SndBuffer.DataQueue = NetbufQueAlloc ();
  if (NULL == Sock->SndBuffer.DataQueue) {
    DEBUG ((EFI_D_ERROR, "SockCreate: No resource to allocate"
      " SndBuffer for new socket\n"));

    goto OnError;
  }

  Sock->RcvBuffer.DataQueue = NetbufQueAlloc ();
  if (NULL == Sock->RcvBuffer.DataQueue) {
    DEBUG ((EFI_D_ERROR, "SockCreate: No resource to allocate "
      "RcvBuffer for new socket\n"));

    goto OnError;
  }

  Sock->Signature           = SOCK_SIGNATURE;

  Sock->Parent              = Parent;
  Sock->BackLog             = SockInitData->BackLog;
  Sock->ProtoHandler        = SockInitData->ProtoHandler;
  Sock->SndBuffer.HighWater = SockInitData->SndBufferSize;
  Sock->RcvBuffer.HighWater = SockInitData->RcvBufferSize;
  Sock->Type                = SockInitData->Type;
  Sock->DriverBinding       = SockInitData->DriverBinding;
  Sock->State               = SockInitData->State;
  Sock->CreateCallback      = SockInitData->CreateCallback;
  Sock->DestroyCallback     = SockInitData->DestroyCallback;
  Sock->Context             = SockInitData->Context;

  Sock->SockError           = EFI_ABORTED;
  Sock->SndBuffer.LowWater  = SOCK_BUFF_LOW_WATER;
  Sock->RcvBuffer.LowWater  = SOCK_BUFF_LOW_WATER;

  //
  // Install protocol on Sock->SockHandle
  //
  CopyMem (
    &(Sock->NetProtocol.TcpProtocol),
    SockInitData->Protocol,
    sizeof (EFI_TCP4_PROTOCOL)
    );

  //
  // copy the protodata into socket
  //
  CopyMem (Sock->ProtoReserved, SockInitData->ProtoData, SockInitData->DataSize);

  Status = gBS->InstallMultipleProtocolInterfaces (
                  &Sock->SockHandle,
                  &gEfiTcp4ProtocolGuid,
                  &(Sock->NetProtocol.TcpProtocol),
                  NULL
                  );

  if (EFI_ERROR (Status)) {
    DEBUG ((EFI_D_ERROR, "SockCreate: Install TCP protocol in "
      "socket failed with %r\n", Status));

    goto OnError;
  }

  if (Parent != NULL) {
    ASSERT (Parent->BackLog > 0);
    ASSERT (SOCK_IS_LISTENING (Parent));

    //
    // need to add it into Parent->ConnectionList
    // if the Parent->ConnCnt < Parent->BackLog
    //
    Parent->ConnCnt++;

    DEBUG (
      (EFI_D_NET,
      "SockCreate: Create a new socket and add to parent, now conncnt is %d\n",
      Parent->ConnCnt)
      );

    InsertTailList (&Parent->ConnectionList, &Sock->ConnectionList);
  }

  if (Sock->CreateCallback != NULL) {
    Status = Sock->CreateCallback (Sock, Sock->Context);
    if (EFI_ERROR (Status)) {
      goto OnError;
    }
  }

  return Sock;

OnError:

  if (Sock->SockHandle != NULL) {
    gBS->UninstallMultipleProtocolInterfaces (
           Sock->SockHandle,
           &gEfiTcp4ProtocolGuid,
           &(Sock->NetProtocol.TcpProtocol),
           NULL
           );
  }

  if (NULL != Sock->SndBuffer.DataQueue) {
    NetbufQueFree (Sock->SndBuffer.DataQueue);
  }

  if (NULL != Sock->RcvBuffer.DataQueue) {
    NetbufQueFree (Sock->RcvBuffer.DataQueue);
  }

  FreePool (Sock);

  return NULL;
}