Example #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 ;
}
Example #2
0
/**
  Cancel the tokens in the specific token list.

  @param[in]       Token                 Pointer to the Token. If NULL, all tokens
                                         in SpecifiedTokenList will be canceled.
  @param[in, out]  SpecifiedTokenList    Pointer to the token list to be checked.

  @retval EFI_SUCCESS          Cancel the tokens in the specific token listsuccessfully.
  @retval EFI_NOT_FOUND        The Token is not found in SpecifiedTokenList.

**/
EFI_STATUS
SockCancelToken (
  IN     SOCK_COMPLETION_TOKEN  *Token,
  IN OUT LIST_ENTRY             *SpecifiedTokenList
  )
{
  EFI_STATUS     Status;
  LIST_ENTRY     *Entry;
  SOCK_TOKEN     *SockToken;

  Status    = EFI_SUCCESS;
  Entry     = NULL;
  SockToken = NULL;

  if (IsListEmpty (SpecifiedTokenList) && Token != NULL) {
    return EFI_NOT_FOUND;
  }

  //
  // Iterate through the SpecifiedTokenList.
  //
  Entry = SpecifiedTokenList->ForwardLink;
  while (Entry != SpecifiedTokenList) {
    SockToken = NET_LIST_USER_STRUCT (Entry, SOCK_TOKEN, TokenList);

    if (Token == NULL) {
      SIGNAL_TOKEN (SockToken->Token, EFI_ABORTED);
      RemoveEntryList (&SockToken->TokenList);
      FreePool (SockToken);

      Entry = SpecifiedTokenList->ForwardLink;
      Status = EFI_SUCCESS;
    } else {
      if (Token == (VOID *) SockToken->Token) {
        SIGNAL_TOKEN (Token, EFI_ABORTED);
        RemoveEntryList (&(SockToken->TokenList));
        FreePool (SockToken);

        return EFI_SUCCESS;
      }

      Status = EFI_NOT_FOUND;

      Entry = Entry->ForwardLink;
    }
  }

  ASSERT (IsListEmpty (SpecifiedTokenList) || Token != NULL);

  return Status;
}
Example #3
0
/**
  Flush the tokens in the specific token list.

  @param  Sock                  Pointer to the socket.
  @param  PendingTokenList      Pointer to the token list to be flushed.

**/
VOID
SockFlushPendingToken (
  IN SOCKET         *Sock,
  IN LIST_ENTRY     *PendingTokenList
  )
{
  SOCK_TOKEN            *SockToken;
  SOCK_COMPLETION_TOKEN *Token;

  ASSERT ((Sock != NULL) && (PendingTokenList != NULL));

  while (!IsListEmpty (PendingTokenList)) {
    SockToken = NET_LIST_HEAD (
                  PendingTokenList,
                  SOCK_TOKEN,
                  TokenList
                  );

    Token = SockToken->Token;
    SIGNAL_TOKEN (Token, Sock->SockError);

    RemoveEntryList (&(SockToken->TokenList));
    FreePool (SockToken);
  }
}
Example #4
0
/**
  Get received data from the socket layer to the receive token.

  @param  Sock                  Pointer to the socket.
  @param  RcvToken              Pointer to the application provided receive token.

  @return The length of data received in this token.

**/
UINT32
SockProcessRcvToken (
  IN     SOCKET        *Sock,
  IN OUT SOCK_IO_TOKEN *RcvToken
  )
{
  UINT32                 TokenRcvdBytes;
  EFI_TCP4_RECEIVE_DATA  *RxData;
  BOOLEAN                IsUrg;

  ASSERT (Sock != NULL);

  ASSERT (SockStream == Sock->Type);

  RxData = RcvToken->Packet.RxData;

  TokenRcvdBytes = SockTcpDataToRcv (
                      &Sock->RcvBuffer,
                      &IsUrg,
                      (UINT32) RxData->DataLength
                      );

  //
  // Copy data from RcvBuffer of socket to user
  // provided RxData and set the fields in TCP RxData
  //
  SockSetTcpRxData (Sock, RxData, TokenRcvdBytes, IsUrg);

  NetbufQueTrim (Sock->RcvBuffer.DataQueue, TokenRcvdBytes);
  SIGNAL_TOKEN (&(RcvToken->Token), EFI_SUCCESS);

  return TokenRcvdBytes;
}
Example #5
0
/**
  Signal the receive token with the specific error or
  set socket error code after error is received.

  @param  Sock                  Pointer to the socket.
  @param  Error                 The error code received.

**/
VOID
SockRcvdErr (
  IN OUT SOCKET       *Sock,
  IN     EFI_STATUS   Error
  )
{
  SOCK_TOKEN  *SockToken;

  if (!IsListEmpty (&Sock->RcvTokenList)) {

    SockToken = NET_LIST_HEAD (
                  &Sock->RcvTokenList,
                  SOCK_TOKEN,
                  TokenList
                  );

    RemoveEntryList (&SockToken->TokenList);

    SIGNAL_TOKEN (SockToken->Token, Error);

    FreePool (SockToken);
  } else {

    SOCK_ERROR (Sock, Error);
  }
}
Example #6
0
/**
  Wake up the connection token while the connection is successfully established,
  then try to process any pending send token.

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

**/
VOID
SockWakeConnToken (
  IN OUT SOCKET *Sock
  )
{
  ASSERT (Sock->ConnectionToken != NULL);

  SIGNAL_TOKEN (Sock->ConnectionToken, EFI_SUCCESS);
  Sock->ConnectionToken = NULL;

  //
  // check to see if some pending send token existed?
  //
  SockProcessSndToken (Sock);
}
Example #7
0
/**
  Called by low layer protocol to indicate that some data is sent or processed.

  This function trims the sent data in the socket send buffer, signals the data
  token if proper.

  @param  Sock                  Pointer to the socket.
  @param  Count                 The length of the data processed or sent, in bytes.

**/
VOID
SockDataSent (
  IN SOCKET     *Sock,
  IN UINT32     Count
  )
{
  SOCK_TOKEN            *SockToken;
  SOCK_COMPLETION_TOKEN *SndToken;

  ASSERT (!IsListEmpty (&Sock->ProcessingSndTokenList));
  ASSERT (Count <= (Sock->SndBuffer.DataQueue)->BufSize);

  NetbufQueTrim (Sock->SndBuffer.DataQueue, Count);

  //
  // To check if we can signal some snd token in this socket
  //
  while (Count > 0) {
    SockToken = NET_LIST_HEAD (
                  &(Sock->ProcessingSndTokenList),
                  SOCK_TOKEN,
                  TokenList
                  );

    SndToken = SockToken->Token;

    if (SockToken->RemainDataLen <= Count) {

      RemoveEntryList (&(SockToken->TokenList));
      SIGNAL_TOKEN (SndToken, EFI_SUCCESS);
      Count -= SockToken->RemainDataLen;
      FreePool (SockToken);
    } else {

      SockToken->RemainDataLen -= Count;
      Count = 0;
    }
  }

  //
  // to judge if we can process some send token in
  // Sock->SndTokenList, if so process those send token
  //
  SockProcessSndToken (Sock);
  return ;
}
Example #8
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);
  }

}
Example #9
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;
  }
}
Example #10
0
/**
  Process the send token.

  @param  Sock                  Pointer to the socket.

**/
VOID
SockProcessSndToken (
  IN OUT SOCKET *Sock
  )
{
  UINT32                  FreeSpace;
  SOCK_TOKEN              *SockToken;
  UINT32                  DataLen;
  SOCK_IO_TOKEN           *SndToken;
  EFI_TCP4_TRANSMIT_DATA  *TxData;
  EFI_STATUS              Status;

  ASSERT ((Sock != NULL) && (SockStream == Sock->Type));

  FreeSpace = SockGetFreeSpace (Sock, SOCK_SND_BUF);

  //
  // to determine if process a send token using
  // socket layer flow control policy
  //
  while ((FreeSpace >= Sock->SndBuffer.LowWater) &&
         !IsListEmpty (&Sock->SndTokenList)) {

    SockToken = NET_LIST_HEAD (
                  &(Sock->SndTokenList),
                  SOCK_TOKEN,
                  TokenList
                  );

    //
    // process this token
    //
    RemoveEntryList (&(SockToken->TokenList));
    InsertTailList (
      &(Sock->ProcessingSndTokenList),
      &(SockToken->TokenList)
      );

    //
    // Proceess it in the light of  SockType
    //
    SndToken  = (SOCK_IO_TOKEN *) SockToken->Token;
    TxData    = SndToken->Packet.TxData;

    DataLen = (UINT32) TxData->DataLength;
    Status  = SockProcessTcpSndData (Sock, TxData);

    if (EFI_ERROR (Status)) {
      goto OnError;
    }

    if (DataLen >= FreeSpace) {
      FreeSpace = 0;

    } else {
      FreeSpace -= DataLen;

    }
  }

  return ;

OnError:

  RemoveEntryList (&SockToken->TokenList);
  SIGNAL_TOKEN (SockToken->Token, Status);
  FreePool (SockToken);
}