4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/** @file
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Implementation of the Socket.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Copyright (c) 2009 - 2010, Intel Corporation. All rights reserved.<BR>
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync This program and the accompanying materials
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync are licensed and made available under the terms and conditions of the BSD License
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync which accompanies this distribution. The full text of the license may be found at
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync http://opensource.org/licenses/bsd-license.php.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync**/
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync#include "SockImpl.h"
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/**
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Get the first buffer block in the specific socket buffer.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] Sockbuf Pointer to the socket buffer.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @return Pointer to the first buffer in the queue. NULL if the queue is empty.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync**/
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncNET_BUF *
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncSockBufFirst (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN SOCK_BUFFER *Sockbuf
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync )
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync{
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync LIST_ENTRY *NetbufList;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync NetbufList = &(Sockbuf->DataQueue->BufList);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (IsListEmpty (NetbufList)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return NULL;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return NET_LIST_HEAD (NetbufList, NET_BUF, List);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync}
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/**
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Get the next buffer block in the specific socket buffer.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] Sockbuf Pointer to the socket buffer.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] SockEntry Pointer to the buffer block prior to the required one.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @return Pointer to the buffer block next to SockEntry. NULL if SockEntry is
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync the tail or head entry.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync**/
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncNET_BUF *
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncSockBufNext (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN SOCK_BUFFER *Sockbuf,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN NET_BUF *SockEntry
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync )
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync{
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync LIST_ENTRY *NetbufList;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync NetbufList = &(Sockbuf->DataQueue->BufList);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ((SockEntry->List.ForwardLink == NetbufList) ||
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync (SockEntry->List.BackLink == &SockEntry->List) ||
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync (SockEntry->List.ForwardLink == &SockEntry->List)
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return NULL;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return NET_LIST_USER_STRUCT (SockEntry->List.ForwardLink, NET_BUF, List);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync}
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/**
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync User provided callback function for NetbufFromExt.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] Event The Event this notify function registered to, ignored.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync**/
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncVOID
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncEFIAPI
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncSockFreeFoo (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN EFI_EVENT Event
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync )
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync{
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync}
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/**
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Get the length of the data that can be retrieved from the socket
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync receive buffer.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] SockBuffer Pointer to the socket receive buffer.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[out] IsUrg Pointer to a BOOLEAN variable.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync If TRUE the data is OOB.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] BufLen The maximum length of the data buffer to
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync store the received data in the socket layer.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @return The length of the data can be retreived.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync**/
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncUINT32
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncSockTcpDataToRcv (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN SOCK_BUFFER *SockBuffer,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync OUT BOOLEAN *IsUrg,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN UINT32 BufLen
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync )
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync{
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync NET_BUF *RcvBufEntry;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINT32 DataLen;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync TCP_RSV_DATA *TcpRsvData;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync BOOLEAN Urg;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ASSERT ((SockBuffer != NULL) && (IsUrg != NULL) && (BufLen > 0));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Get the first socket receive buffer
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync RcvBufEntry = SockBufFirst (SockBuffer);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ASSERT (RcvBufEntry != NULL);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync TcpRsvData = (TCP_RSV_DATA *) RcvBufEntry->ProtoData;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Check whether the receive data is out of bound. If yes, calculate the maximum
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // allowed length of the urgent data and output it.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync *IsUrg = (BOOLEAN) ((TcpRsvData->UrgLen > 0) ? TRUE : FALSE);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (*IsUrg && (TcpRsvData->UrgLen < RcvBufEntry->TotalSize)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DataLen = MIN (TcpRsvData->UrgLen, BufLen);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (DataLen < TcpRsvData->UrgLen) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync TcpRsvData->UrgLen = TcpRsvData->UrgLen - DataLen;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync } else {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync TcpRsvData->UrgLen = 0;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return DataLen;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Process the next socket receive buffer to get the maximum allowed length
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // of the received data.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DataLen = RcvBufEntry->TotalSize;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync RcvBufEntry = SockBufNext (SockBuffer, RcvBufEntry);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync while ((BufLen > DataLen) && (RcvBufEntry != NULL)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync TcpRsvData = (TCP_RSV_DATA *) RcvBufEntry->ProtoData;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Urg = (BOOLEAN) ((TcpRsvData->UrgLen > 0) ? TRUE : FALSE);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (*IsUrg != Urg) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync break;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (*IsUrg && TcpRsvData->UrgLen < RcvBufEntry->TotalSize) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (TcpRsvData->UrgLen + DataLen < BufLen) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync TcpRsvData->UrgLen = 0;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync } else {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync TcpRsvData->UrgLen = TcpRsvData->UrgLen - (BufLen - DataLen);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return MIN (TcpRsvData->UrgLen + DataLen, BufLen);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DataLen += RcvBufEntry->TotalSize;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync RcvBufEntry = SockBufNext (SockBuffer, RcvBufEntry);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DataLen = MIN (BufLen, DataLen);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return DataLen;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync}
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/**
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Copy data from socket buffer to an application provided receive buffer.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] Sock Pointer to the socket.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] TcpRxData Pointer to the application provided receive buffer.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] RcvdBytes The maximum length of the data can be copied.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] IsUrg If TRUE the data is Out of Bound, FALSE the data is normal.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync**/
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncVOID
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncSockSetTcpRxData (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN SOCKET *Sock,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN VOID *TcpRxData,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN UINT32 RcvdBytes,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN BOOLEAN IsUrg
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync )
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync{
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINT32 Index;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINT32 CopyBytes;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINT32 OffSet;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_TCP4_RECEIVE_DATA *RxData;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_TCP4_FRAGMENT_DATA *Fragment;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync RxData = (EFI_TCP4_RECEIVE_DATA *) TcpRxData;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync OffSet = 0;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ASSERT (RxData->DataLength >= RcvdBytes);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync RxData->DataLength = RcvdBytes;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync RxData->UrgentFlag = IsUrg;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Copy the CopyBytes data from socket receive buffer to RxData.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync for (Index = 0; (Index < RxData->FragmentCount) && (RcvdBytes > 0); Index++) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Fragment = &RxData->FragmentTable[Index];
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync CopyBytes = MIN ((UINT32) (Fragment->FragmentLength), RcvdBytes);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync NetbufQueCopy (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Sock->RcvBuffer.DataQueue,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync OffSet,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync CopyBytes,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Fragment->FragmentBuffer
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Fragment->FragmentLength = CopyBytes;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync RcvdBytes -= CopyBytes;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync OffSet += CopyBytes;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync}
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/**
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Process the send token.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in, out] Sock Pointer to the socket.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync**/
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncVOID
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncSockProcessSndToken (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN OUT SOCKET *Sock
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync )
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync{
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINT32 FreeSpace;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync SOCK_TOKEN *SockToken;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINT32 DataLen;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync SOCK_IO_TOKEN *SndToken;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_TCP4_TRANSMIT_DATA *TxData;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_STATUS Status;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ASSERT ((Sock != NULL) && (SockStream == Sock->Type));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync FreeSpace = SockGetFreeSpace (Sock, SOCK_SND_BUF);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // to determine if process a send token using
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // socket layer flow control policy
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync while ((FreeSpace >= Sock->SndBuffer.LowWater) && !IsListEmpty (&Sock->SndTokenList)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync SockToken = NET_LIST_HEAD (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync &(Sock->SndTokenList),
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync SOCK_TOKEN,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync TokenList
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // process this token
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync RemoveEntryList (&(SockToken->TokenList));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync InsertTailList (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync &(Sock->ProcessingSndTokenList),
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync &(SockToken->TokenList)
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Proceess it in the light of SockType
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync SndToken = (SOCK_IO_TOKEN *) SockToken->Token;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync TxData = SndToken->Packet.TxData;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DataLen = TxData->DataLength;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = SockProcessTcpSndData (Sock, TxData);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (EFI_ERROR (Status)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync goto OnError;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (DataLen >= FreeSpace) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync FreeSpace = 0;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync } else {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync FreeSpace -= DataLen;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncOnError:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync RemoveEntryList (&SockToken->TokenList);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync SIGNAL_TOKEN (SockToken->Token, Status);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync FreePool (SockToken);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync}
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/**
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Get received data from the socket layer to the receive token.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in, out] Sock Pointer to the socket.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in, out] RcvToken Pointer to the application provided receive token.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @return The length of data received in this token.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync**/
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncUINT32
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncSockProcessRcvToken (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN OUT SOCKET *Sock,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN OUT SOCK_IO_TOKEN *RcvToken
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync )
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync{
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINT32 TokenRcvdBytes;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_TCP4_RECEIVE_DATA *RxData;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync BOOLEAN IsUrg;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ASSERT (Sock != NULL);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ASSERT (SockStream == Sock->Type);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync RxData = RcvToken->Packet.RxData;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync TokenRcvdBytes = SockTcpDataToRcv (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync &Sock->RcvBuffer,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync &IsUrg,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync RxData->DataLength
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Copy data from RcvBuffer of socket to user
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // provided RxData and set the fields in TCP RxData
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync SockSetTcpRxData (Sock, RxData, TokenRcvdBytes, IsUrg);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync NetbufQueTrim (Sock->RcvBuffer.DataQueue, TokenRcvdBytes);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync SIGNAL_TOKEN (&(RcvToken->Token), EFI_SUCCESS);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return TokenRcvdBytes;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync}
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/**
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Process the TCP send data, buffer the tcp txdata, and append
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync the buffer to socket send buffer, then try to send it.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] Sock Pointer to the socket.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] TcpTxData Pointer to the application provided send buffer.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_SUCCESS The operation completed successfully.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_OUT_OF_RESOURCES Failed due to resource limits.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync**/
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncEFI_STATUS
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncSockProcessTcpSndData (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN SOCKET *Sock,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN VOID *TcpTxData
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync )
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync{
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync NET_BUF *SndData;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_STATUS Status;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_TCP4_TRANSMIT_DATA *TxData;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync TxData = (EFI_TCP4_TRANSMIT_DATA *) TcpTxData;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // transform this TxData into a NET_BUFFER
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // and insert it into Sock->SndBuffer
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync SndData = NetbufFromExt (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync (NET_FRAGMENT *) TxData->FragmentTable,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync TxData->FragmentCount,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync 0,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync 0,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync SockFreeFoo,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync NULL
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (NULL == SndData) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DEBUG (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync (EFI_D_ERROR,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync "SockKProcessSndData: Failed to call NetBufferFromExt\n")
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return EFI_OUT_OF_RESOURCES;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync NetbufQueAppend (Sock->SndBuffer.DataQueue, SndData);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // notify the low layer protocol to handle this send token
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (TxData->Urgent) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = Sock->ProtoHandler (Sock, SOCK_SNDURG, NULL);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (EFI_ERROR (Status)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return Status;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (TxData->Push) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = Sock->ProtoHandler (Sock, SOCK_SNDPUSH, NULL);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (EFI_ERROR (Status)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return Status;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // low layer protocol should really handle the sending
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // process when catching SOCK_SND request
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = Sock->ProtoHandler (Sock, SOCK_SND, NULL);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (EFI_ERROR (Status)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return Status;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return EFI_SUCCESS;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync}
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/**
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Flush the tokens in the specific token list.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] Sock Pointer to the socket.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in, out] PendingTokenList Pointer to the token list to be flushed.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync**/
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncVOID
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncSockFlushPendingToken (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN SOCKET *Sock,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN OUT LIST_ENTRY *PendingTokenList
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync )
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync{
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync SOCK_TOKEN *SockToken;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync SOCK_COMPLETION_TOKEN *Token;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ASSERT ((Sock != NULL) && (PendingTokenList != NULL));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync while (!IsListEmpty (PendingTokenList)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync SockToken = NET_LIST_HEAD (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync PendingTokenList,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync SOCK_TOKEN,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync TokenList
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Token = SockToken->Token;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync SIGNAL_TOKEN (Token, Sock->SockError);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync RemoveEntryList (&(SockToken->TokenList));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync FreePool (SockToken);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync}
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/**
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Wake up the connection token while the connection is successfully established,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync then try to process any pending send token.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in, out] Sock Pointer to the socket.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync**/
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncVOID
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncSockWakeConnToken (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN OUT SOCKET *Sock
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync )
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync{
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ASSERT (Sock->ConnectionToken != NULL);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync SIGNAL_TOKEN (Sock->ConnectionToken, EFI_SUCCESS);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Sock->ConnectionToken = NULL;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // check to see if some pending send token existed?
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync SockProcessSndToken (Sock);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync}
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/**
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Wake up the listen token while the connection is established successfully.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in, out] Sock Pointer to the socket.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync**/
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncVOID
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncSockWakeListenToken (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN OUT SOCKET *Sock
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync )
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync{
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync SOCKET *Parent;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync SOCK_TOKEN *SockToken;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_TCP4_LISTEN_TOKEN *ListenToken;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Parent = Sock->Parent;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ASSERT ((Parent != NULL) && SOCK_IS_LISTENING (Parent) && SOCK_IS_CONNECTED (Sock));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (!IsListEmpty (&Parent->ListenTokenList)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync SockToken = NET_LIST_HEAD (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync &Parent->ListenTokenList,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync SOCK_TOKEN,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync TokenList
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ListenToken = (EFI_TCP4_LISTEN_TOKEN *) SockToken->Token;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ListenToken->NewChildHandle = Sock->SockHandle;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync SIGNAL_TOKEN (&(ListenToken->CompletionToken), EFI_SUCCESS);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync RemoveEntryList (&SockToken->TokenList);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync FreePool (SockToken);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync RemoveEntryList (&Sock->ConnectionList);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Parent->ConnCnt--;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DEBUG (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync (EFI_D_INFO,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync "SockWakeListenToken: accept a socket, now conncnt is %d",
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Parent->ConnCnt)
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Sock->Parent = NULL;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync}
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/**
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Wake up the receive token while some data is received.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in, out] Sock Pointer to the socket.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync**/
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncVOID
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncSockWakeRcvToken (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN OUT SOCKET *Sock
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync )
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync{
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINT32 RcvdBytes;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINT32 TokenRcvdBytes;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync SOCK_TOKEN *SockToken;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync SOCK_IO_TOKEN *RcvToken;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ASSERT (Sock->RcvBuffer.DataQueue != NULL);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync RcvdBytes = (Sock->RcvBuffer.DataQueue)->BufSize;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ASSERT (RcvdBytes > 0);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync while (RcvdBytes > 0 && !IsListEmpty (&Sock->RcvTokenList)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync SockToken = NET_LIST_HEAD (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync &Sock->RcvTokenList,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync SOCK_TOKEN,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync TokenList
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync RcvToken = (SOCK_IO_TOKEN *) SockToken->Token;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync TokenRcvdBytes = SockProcessRcvToken (Sock, RcvToken);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (0 == TokenRcvdBytes) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return ;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync RemoveEntryList (&(SockToken->TokenList));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync FreePool (SockToken);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync RcvdBytes -= TokenRcvdBytes;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync}
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/**
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Create a socket with initial data SockInitData.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] SockInitData Pointer to the initial data of the socket.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @return Pointer to the newly created socket, return NULL when an exception occurs.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync**/
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncSOCKET *
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncSockCreate (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN SOCK_INIT_DATA *SockInitData
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync )
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync{
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync SOCKET *Sock;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync SOCKET *Parent;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_STATUS Status;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_GUID *TcpProtocolGuid;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINTN ProtocolLength;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ASSERT ((SockInitData != NULL) && (SockInitData->ProtoHandler != NULL));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ASSERT (SockInitData->Type == SockStream);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ASSERT ((SockInitData->ProtoData != NULL) && (SockInitData->DataSize <= PROTO_RESERVED_LEN));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (SockInitData->IpVersion == IP_VERSION_4) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync TcpProtocolGuid = &gEfiTcp4ProtocolGuid;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ProtocolLength = sizeof (EFI_TCP4_PROTOCOL);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync } else {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync TcpProtocolGuid = &gEfiTcp6ProtocolGuid;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ProtocolLength = sizeof (EFI_TCP6_PROTOCOL);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Parent = SockInitData->Parent;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ((Parent != NULL) && (Parent->ConnCnt == Parent->BackLog)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DEBUG (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync (EFI_D_ERROR,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync "SockCreate: Socket parent has reached its connection limit with %d ConnCnt and %d BackLog\n",
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Parent->ConnCnt,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Parent->BackLog)
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return NULL;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Sock = AllocateZeroPool (sizeof (SOCKET));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (NULL == Sock) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DEBUG ((EFI_D_ERROR, "SockCreate: No resource to create a new socket\n"));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return NULL;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync InitializeListHead (&Sock->Link);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync InitializeListHead (&Sock->ConnectionList);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync InitializeListHead (&Sock->ListenTokenList);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync InitializeListHead (&Sock->RcvTokenList);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync InitializeListHead (&Sock->SndTokenList);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync InitializeListHead (&Sock->ProcessingSndTokenList);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EfiInitializeLock (&(Sock->Lock), TPL_CALLBACK);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Sock->SndBuffer.DataQueue = NetbufQueAlloc ();
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (NULL == Sock->SndBuffer.DataQueue) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DEBUG (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync (EFI_D_ERROR,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync "SockCreate: No resource to allocate SndBuffer for new socket\n")
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync goto OnError;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Sock->RcvBuffer.DataQueue = NetbufQueAlloc ();
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (NULL == Sock->RcvBuffer.DataQueue) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DEBUG (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync (EFI_D_ERROR,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync "SockCreate: No resource to allocate RcvBuffer for new socket\n")
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync goto OnError;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Sock->Signature = SOCK_SIGNATURE;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Sock->Parent = Parent;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Sock->BackLog = SockInitData->BackLog;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Sock->ProtoHandler = SockInitData->ProtoHandler;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Sock->SndBuffer.HighWater = SockInitData->SndBufferSize;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Sock->RcvBuffer.HighWater = SockInitData->RcvBufferSize;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Sock->Type = SockInitData->Type;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Sock->DriverBinding = SockInitData->DriverBinding;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Sock->State = SockInitData->State;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Sock->CreateCallback = SockInitData->CreateCallback;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Sock->DestroyCallback = SockInitData->DestroyCallback;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Sock->Context = SockInitData->Context;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Sock->SockError = EFI_ABORTED;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Sock->SndBuffer.LowWater = SOCK_BUFF_LOW_WATER;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Sock->RcvBuffer.LowWater = SOCK_BUFF_LOW_WATER;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Sock->IpVersion = SockInitData->IpVersion;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Install protocol on Sock->SockHandle
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync CopyMem (&Sock->NetProtocol, SockInitData->Protocol, ProtocolLength);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // copy the protodata into socket
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync CopyMem (Sock->ProtoReserved, SockInitData->ProtoData, SockInitData->DataSize);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = gBS->InstallMultipleProtocolInterfaces (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync &Sock->SockHandle,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync TcpProtocolGuid,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync &Sock->NetProtocol,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync NULL
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (EFI_ERROR (Status)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DEBUG (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync (EFI_D_ERROR,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync "SockCreate: Install TCP protocol in socket failed with %r\n",
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status)
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync goto OnError;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (Parent != NULL) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ASSERT (Parent->BackLog > 0);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ASSERT (SOCK_IS_LISTENING (Parent));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // need to add it into Parent->ConnectionList
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // if the Parent->ConnCnt < Parent->BackLog
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Parent->ConnCnt++;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DEBUG (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync (EFI_D_INFO,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync "SockCreate: Create a new socket and add to parent, now conncnt is %d\n",
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Parent->ConnCnt)
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync InsertTailList (&Parent->ConnectionList, &Sock->ConnectionList);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (Sock->CreateCallback != NULL) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = Sock->CreateCallback (Sock, Sock->Context);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (EFI_ERROR (Status)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync goto OnError;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return Sock;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncOnError:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (Sock->SockHandle != NULL) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync gBS->UninstallMultipleProtocolInterfaces (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Sock->SockHandle,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync TcpProtocolGuid,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync &Sock->NetProtocol,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync NULL
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (NULL != Sock->SndBuffer.DataQueue) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync NetbufQueFree (Sock->SndBuffer.DataQueue);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (NULL != Sock->RcvBuffer.DataQueue) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync NetbufQueFree (Sock->RcvBuffer.DataQueue);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync FreePool (Sock);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return NULL;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync}
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/**
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Destroy a socket.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in, out] Sock Pointer to the socket.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync**/
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncVOID
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncSockDestroy (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN OUT SOCKET *Sock
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync )
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync{
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync VOID *SockProtocol;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_GUID *TcpProtocolGuid;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_STATUS Status;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ASSERT (SockStream == Sock->Type);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (Sock->DestroyCallback != NULL) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Sock->DestroyCallback (Sock, Sock->Context);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Flush the completion token buffered
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // by sock and rcv, snd buffer
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (!SOCK_IS_UNCONFIGURED (Sock)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync SockConnFlush (Sock);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync SockSetState (Sock, SO_CLOSED);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Sock->ConfigureState = SO_UNCONFIGURED;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Destory the RcvBuffer Queue and SendBuffer Queue
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync NetbufQueFree (Sock->RcvBuffer.DataQueue);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync NetbufQueFree (Sock->SndBuffer.DataQueue);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Remove it from parent connection list if needed
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (Sock->Parent != NULL) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync RemoveEntryList (&(Sock->ConnectionList));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync (Sock->Parent->ConnCnt)--;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DEBUG (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync (EFI_D_WARN,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync "SockDestory: Delete a unaccepted socket from parent now conncnt is %d\n",
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Sock->Parent->ConnCnt)
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Sock->Parent = NULL;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Set the protocol guid and driver binding handle
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // in the light of Sock->SockType
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (Sock->IpVersion == IP_VERSION_4) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync TcpProtocolGuid = &gEfiTcp4ProtocolGuid;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync } else {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync TcpProtocolGuid = &gEfiTcp6ProtocolGuid;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Retrieve the protocol installed on this sock
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = gBS->OpenProtocol (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Sock->SockHandle,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync TcpProtocolGuid,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync &SockProtocol,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Sock->DriverBinding,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Sock->SockHandle,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_OPEN_PROTOCOL_GET_PROTOCOL
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (EFI_ERROR (Status)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DEBUG (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync (EFI_D_ERROR,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync "SockDestroy: Open protocol installed on socket failed with %r\n",
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status)
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync goto FreeSock;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Uninstall the protocol installed on this sock
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // in the light of Sock->SockType
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync gBS->UninstallMultipleProtocolInterfaces (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Sock->SockHandle,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync TcpProtocolGuid,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync SockProtocol,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync NULL
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncFreeSock:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync FreePool (Sock);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync}
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/**
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Flush the sndBuffer and rcvBuffer of socket.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in, out] Sock Pointer to the socket.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync**/
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncVOID
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncSockConnFlush (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN OUT SOCKET *Sock
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync )
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync{
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync SOCKET *Child;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ASSERT (Sock != NULL);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Clear the flag in this socket
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Sock->Flag = 0;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Flush the SndBuffer and RcvBuffer of Sock
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync NetbufQueFlush (Sock->SndBuffer.DataQueue);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync NetbufQueFlush (Sock->RcvBuffer.DataQueue);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Signal the pending token
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (Sock->ConnectionToken != NULL) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync SIGNAL_TOKEN (Sock->ConnectionToken, Sock->SockError);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Sock->ConnectionToken = NULL;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (Sock->CloseToken != NULL) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync SIGNAL_TOKEN (Sock->CloseToken, Sock->SockError);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Sock->CloseToken = NULL;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync SockFlushPendingToken (Sock, &(Sock->ListenTokenList));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync SockFlushPendingToken (Sock, &(Sock->RcvTokenList));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync SockFlushPendingToken (Sock, &(Sock->SndTokenList));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync SockFlushPendingToken (Sock, &(Sock->ProcessingSndTokenList));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Destroy the pending connection, if it is a listening socket
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (SOCK_IS_LISTENING (Sock)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync while (!IsListEmpty (&Sock->ConnectionList)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Child = NET_LIST_HEAD (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync &Sock->ConnectionList,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync SOCKET,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ConnectionList
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync SockDestroyChild (Child);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Sock->ConnCnt = 0;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync}
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/**
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Set the state of the socket.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in, out] Sock Pointer to the socket.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] State The new socket state to be set.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync**/
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncVOID
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncSockSetState (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN OUT SOCKET *Sock,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN UINT8 State
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync )
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync{
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Sock->State = State;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync}
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/**
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Clone a new socket, including its associated protocol control block.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] Sock Pointer to the socket to be cloned.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @return Pointer to the newly cloned socket. If NULL, an error condition occurred.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync**/
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncSOCKET *
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncSockClone (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN SOCKET *Sock
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync )
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync{
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync SOCKET *ClonedSock;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync SOCK_INIT_DATA InitData;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync InitData.BackLog = Sock->BackLog;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync InitData.Parent = Sock;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync InitData.State = Sock->State;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync InitData.ProtoHandler = Sock->ProtoHandler;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync InitData.Type = Sock->Type;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync InitData.RcvBufferSize = Sock->RcvBuffer.HighWater;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync InitData.SndBufferSize = Sock->SndBuffer.HighWater;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync InitData.DriverBinding = Sock->DriverBinding;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync InitData.IpVersion = Sock->IpVersion;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync InitData.Protocol = &(Sock->NetProtocol);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync InitData.CreateCallback = Sock->CreateCallback;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync InitData.DestroyCallback = Sock->DestroyCallback;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync InitData.Context = Sock->Context;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync InitData.ProtoData = Sock->ProtoReserved;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync InitData.DataSize = sizeof (Sock->ProtoReserved);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ClonedSock = SockCreate (&InitData);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (NULL == ClonedSock) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DEBUG ((EFI_D_ERROR, "SockClone: no resource to create a cloned sock\n"));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return NULL;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync SockSetState (ClonedSock, SO_CONNECTING);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ClonedSock->ConfigureState = Sock->ConfigureState;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return ClonedSock;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync}
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/**
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Called by the low layer protocol to indicate the socket a connection is
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync established.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync This function just changes the socket's state to SO_CONNECTED
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync and signals the token used for connection establishment.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in, out] Sock Pointer to the socket associated with the
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync established connection.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync**/
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncVOID
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncSockConnEstablished (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN OUT SOCKET *Sock
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync )
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync{
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ASSERT (SO_CONNECTING == Sock->State);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync SockSetState (Sock, SO_CONNECTED);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (NULL == Sock->Parent) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync SockWakeConnToken (Sock);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync } else {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync SockWakeListenToken (Sock);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync}
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/**
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Called by the low layer protocol to indicate the connection is closed.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync This function flushes the socket, sets the state to SO_CLOSED, and signals
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync the close token.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in, out] Sock Pointer to the socket associated with the closed
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync connection.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync**/
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncVOID
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncSockConnClosed (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN OUT SOCKET *Sock
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync )
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync{
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (Sock->CloseToken != NULL) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync SIGNAL_TOKEN (Sock->CloseToken, EFI_SUCCESS);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Sock->CloseToken = NULL;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync SockConnFlush (Sock);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync SockSetState (Sock, SO_CLOSED);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (Sock->Parent != NULL) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync SockDestroyChild (Sock);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync}
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/**
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Called by low layer protocol to indicate that some data was sent or processed.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync This function trims the sent data in the socket send buffer, and signals the data
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync token if proper.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in, out] Sock Pointer to the socket.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] Count The length of the data processed or sent, in bytes.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync**/
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncVOID
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncSockDataSent (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN OUT SOCKET *Sock,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN UINT32 Count
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync )
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync{
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync SOCK_TOKEN *SockToken;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync SOCK_COMPLETION_TOKEN *SndToken;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ASSERT (!IsListEmpty (&Sock->ProcessingSndTokenList));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ASSERT (Count <= (Sock->SndBuffer.DataQueue)->BufSize);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync NetbufQueTrim (Sock->SndBuffer.DataQueue, Count);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // To check if we can signal some snd token in this socket
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync while (Count > 0) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync SockToken = NET_LIST_HEAD (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync &(Sock->ProcessingSndTokenList),
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync SOCK_TOKEN,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync TokenList
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync SndToken = SockToken->Token;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (SockToken->RemainDataLen <= Count) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync RemoveEntryList (&(SockToken->TokenList));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync SIGNAL_TOKEN (SndToken, EFI_SUCCESS);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Count -= SockToken->RemainDataLen;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync FreePool (SockToken);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync } else {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync SockToken->RemainDataLen -= Count;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Count = 0;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // to judge if we can process some send token in
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Sock->SndTokenList, if so process those send token
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync SockProcessSndToken (Sock);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync}
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/**
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Called by the low layer protocol to copy some data in the socket send
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync buffer starting from the specific offset to a buffer provided by
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync the caller.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] Sock Pointer to the socket.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] Offset The start point of the data to be copied.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] Len The length of the data to be copied.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[out] Dest Pointer to the destination to copy the data.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @return The data size copied.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync**/
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncUINT32
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncSockGetDataToSend (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN SOCKET *Sock,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN UINT32 Offset,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN UINT32 Len,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync OUT UINT8 *Dest
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync )
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync{
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ASSERT ((Sock != NULL) && SockStream == Sock->Type);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return NetbufQueCopy (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Sock->SndBuffer.DataQueue,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Offset,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Len,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Dest
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync}
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/**
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Called by the low layer protocol to deliver received data to socket layer.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync This function will append the data to the socket receive buffer, set the
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync urgent data length, and then check if any receive token can be signaled.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in, out] Sock Pointer to the socket.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in, out] NetBuffer Pointer to the buffer that contains the received data.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] UrgLen The length of the urgent data in the received data.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync**/
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncVOID
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncSockDataRcvd (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN OUT SOCKET *Sock,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN OUT NET_BUF *NetBuffer,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN UINT32 UrgLen
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync )
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync{
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ASSERT ((Sock != NULL) && (Sock->RcvBuffer.DataQueue != NULL) &&
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UrgLen <= NetBuffer->TotalSize);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync NET_GET_REF (NetBuffer);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ((TCP_RSV_DATA *) (NetBuffer->ProtoData))->UrgLen = UrgLen;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync NetbufQueAppend (Sock->RcvBuffer.DataQueue, NetBuffer);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync SockWakeRcvToken (Sock);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync}
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/**
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Get the length of the free space of the specific socket buffer.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] Sock Pointer to the socket.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] Which Flag to indicate which socket buffer to check:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync either send buffer or receive buffer.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @return The length of the free space, in bytes.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync**/
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncUINT32
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncSockGetFreeSpace (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN SOCKET *Sock,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN UINT32 Which
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync )
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync{
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINT32 BufferCC;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync SOCK_BUFFER *SockBuffer;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ASSERT (Sock != NULL && ((SOCK_SND_BUF == Which) || (SOCK_RCV_BUF == Which)));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (SOCK_SND_BUF == Which) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync SockBuffer = &(Sock->SndBuffer);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync } else {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync SockBuffer = &(Sock->RcvBuffer);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync BufferCC = (SockBuffer->DataQueue)->BufSize;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (BufferCC >= SockBuffer->HighWater) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return 0;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return SockBuffer->HighWater - BufferCC;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync}
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/**
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Called by the low layer protocol to indicate that there will be no more data
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync from the communication peer.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync This function sets the socket's state to SO_NO_MORE_DATA and signals all queued
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IO tokens with the error status EFI_CONNECTION_FIN.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in, out] Sock Pointer to the socket.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync**/
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncVOID
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncSockNoMoreData (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN OUT SOCKET *Sock
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync )
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync{
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_STATUS Err;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync SOCK_NO_MORE_DATA (Sock);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (!IsListEmpty (&Sock->RcvTokenList)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ASSERT (0 == GET_RCV_DATASIZE (Sock));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Err = Sock->SockError;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync SOCK_ERROR (Sock, EFI_CONNECTION_FIN);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync SockFlushPendingToken (Sock, &Sock->RcvTokenList);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync SOCK_ERROR (Sock, Err);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync}
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync