TCP
TCP全称是Transmission Control Protocol。
TCP是传输层的协议。
这里以TCP4作为研究的对象。
TCP4驱动依赖于IP4。
TCP4驱动主要做了以下的事情:
1. 初始化TCP4_SERVICE_DATA结构体,最主要的是为该结构体的成员(IpIo)创建IP4的实例;(使用了IpIoCreate()和IpIoOpen()函数)
2. 创建全局的定时器mTcp4Timer,该定时器定时执行TcpTickingDpc()函数,它处理一大堆超时函数:
TCP_TIMER_HANDLER mTcpTimerHandler[TCP_TIMER_NUMBER] = {
TcpConnectTimeout,
TcpRexmitTimeout,
TcpProbeTimeout,
TcpKeepaliveTimeout,
TcpFinwait2Timeout,
Tcp2MSLTimeout,
};
也处理应答:
TcpSendAck (Tcb);
3. 安装gEfiTcp4ServiceBindingProtocolGuid对应的Protocol(说明下,这里的Protocol是指UEFI框架下的Protocol并不是指TCP这样的网络“协议”)。
同之前的IP4,MNP等一样,后面的内容需要先介绍几个重要的结构体。
TCP4_SERVICE_DATA structure
TCP4_SERVICE_DATA定义在Tcp4Driver.h中,如下所示:
typedef struct _TCP4_SERVICE_DATA {
UINT32 Signature;
EFI_HANDLE ControllerHandle;
IP_IO *IpIo; // IP Io consumed by TCP4
EFI_SERVICE_BINDING_PROTOCOL Tcp4ServiceBinding;
EFI_HANDLE DriverBindingHandle;
LIST_ENTRY SocketList;
} TCP4_SERVICE_DATA;
1. Signature的值是SIGNATURE_32 ('T', 'C', 'P', '4');
2. ControllerHandle,DriverBindingHandle分别对应EFI_DRIVER_BINDING_PROTOCOL中的ImageHandle和DriverBindingHandle;
3. IpIo指向IP4实例,后续会仔细介绍;
4. Tcp4ServiceBinding上绑定着TCP4对应的ServiceBindingProtocol;
5. SocketList用来存放SOCKET结构体,它在Tcp4CreateSocketCallback()函数中被插入到SocketList链表中,在SockCreate()函数被调用时,会执行前述的Callback函数,而最终是在ServiceBindingProtocol的CreateChild函数Tcp4ServiceBindingCreateChild()中创建的Socket;
Socket实际上表示是网络通信的端点,在通过Tcp4ServiceBindingCreateChild()创建子例的时候,其实就是在创建Socket,所以所有Tcp4提供的接口:
EFI_TCP4_PROTOCOL mTcp4ProtocolTemplate = {
Tcp4GetModeData,
Tcp4Configure,
Tcp4Routes,
Tcp4Connect,
Tcp4Accept,
Tcp4Transmit,
Tcp4Receive,
Tcp4Close,
Tcp4Cancel,
Tcp4Poll
};
其实最终都是使用了Socket!
IP_IO structure
IP_IO定义在IpIoLib.h文件中,如下所示:
typedef struct _IP_IO {
///
/// The node used to link this IpIo to the active IpIo list.
///
LIST_ENTRY Entry;
///
/// The list used to maintain the IP instance for different sending purpose.
///
LIST_ENTRY IpList;
EFI_HANDLE Controller;
EFI_HANDLE Image;
EFI_HANDLE ChildHandle;
//
// The IP instance consumed by this IP_IO
//
IP_IO_IP_PROTOCOL Ip;
BOOLEAN IsConfigured;
///
/// Some ip configuration data can be changed.
///
UINT8 Protocol;
///
/// Token and event used to get data from IP.
///
IP_IO_IP_COMPLETION_TOKEN RcvToken;
///
/// List entry used to link the token passed to IP_IO.
///
LIST_ENTRY PendingSndList;
//
// User interface used to get notify from IP_IO
//
VOID *RcvdContext; ///< See IP_IO_OPEN_DATA::RcvdContext.
VOID *SndContext; ///< See IP_IO_OPEN_DATA::SndContext.
PKT_RCVD_NOTIFY PktRcvdNotify; ///< See IP_IO_OPEN_DATA::PktRcvdNotify.
PKT_SENT_NOTIFY PktSentNotify; ///< See IP_IO_OPEN_DATA::PktSentNotify.
UINT8 IpVersion;
} IP_IO
IpIoLib实际上就管理了所有的IP4/IP6的操作。
SOCKET structure
SOCKET结构体定义在Socket.h文件中,如下所示:
struct _SOCKET {
//
// Socket description information
//
UINT32 Signature; ///< Signature of the socket
EFI_HANDLE SockHandle; ///< The virtual handle of the socket
EFI_HANDLE DriverBinding; ///< Socket's driver binding protocol
EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath;
EFI_DEVICE_PATH_PROTOCOL *DevicePath;
LIST_ENTRY Link;
UINT8 ConfigureState;
SOCK_TYPE Type;
UINT8 State;
UINT16 Flag;
EFI_LOCK Lock; ///< The lock of socket
SOCK_BUFFER SndBuffer; ///< Send buffer of application's data
SOCK_BUFFER RcvBuffer; ///< Receive buffer of received data
EFI_STATUS SockError; ///< The error returned by low layer protocol
BOOLEAN InDestroy;
//
// Fields used to manage the connection request
//
UINT32 BackLog; ///< the limit of connection to this socket
UINT32 ConnCnt; ///< the current count of connections to it
SOCKET *Parent; ///< listening parent that accept the connection
LIST_ENTRY ConnectionList; ///< the connections maintained by this socket
//
// The queue to buffer application's asynchronous token
//
LIST_ENTRY ListenTokenList;
LIST_ENTRY RcvTokenList;
LIST_ENTRY SndTokenList;
LIST_ENTRY ProcessingSndTokenList;
SOCK_COMPLETION_TOKEN *ConnectionToken; ///< app's token to signal if connected
SOCK_COMPLETION_TOKEN *CloseToken; ///< app's token to signal if closed
//
// Interface for low level protocol
//
SOCK_PROTO_HANDLER ProtoHandler; ///< The request handler of protocol
UINT8 ProtoReserved[PROTO_RESERVED_LEN]; ///< Data fields reserved for protocol
NET_PROTOCOL NetProtocol; ///< TCP or UDP protocol socket used
//
// Callbacks after socket is created and before socket is to be destroyed.
//
SOCK_CREATE_CALLBACK CreateCallback; ///< Callback after created
SOCK_DESTROY_CALLBACK DestroyCallback; ///< Callback before destroied
VOID *Context; ///< The context of the callback
};