LSP摘要

2019-10-24  本文已影响0人  赵海洋

以下部分取自网络,部分取自书籍,部分是自己理解,均可能有误,如有误导,多有得罪。

SPI和WinSock

Winsock SPI全称是The Winsock Service Provider Interface。是提供网络服务的基本模块所调用的一些api,而winsock则基于SPI定义一应用程序编程接口(给普通应用程序访问和控制网络而使用的api接口)

LSP分两种:一种是IFS LSP,一种是non IFS LSP。
简单地说, IFS LSP制作简单,可以完成大部分的数据包监听工作;
non IFS LSP制作复杂,但是可以进行一些特殊的overlapped I/O操作,如在overlapped初始化完成后、调用WSPSend (WriteFile)、 WSPSendTo、WSPRecv (ReadFile)、 WSPRecvFrom,、or WSPIoctl之前对数据进行一些处理工作。
LSP相互之间可以叠加,但在non IFS LSP之上不可以叠加IFS LSP。也就是说,如果一个BSP是non IFS,则第三方提供的LSP必须是non IFS,否则无法安装在SPI上。

分层协议

传输服务提供者有两类:基础服务提供者(BSP)和分层服务提供者(即LSP)。基础服务提供者执行网络传输协议(比如TCP/IP)的具体细节其中包括在网络上收发数据之类的核心网络协议功能。“分层式”(Layered)服务提供者只负责执行高级的自定义通信功能,并依靠下面基础服务提供者,在网络上进行真正的数据交换。
而服务提供者的协议信息里(WSAPROTOCOL_INFO结构的ProtocolChain)表示了是否该依赖于其它分层或基本协议。

IFS

from : https://docs.microsoft.com/zh-cn/windows/win32/winsock/socket-handles-2

A socket handle can optionally be a file handle in Windows Sockets 2. A socket handle from a Winsock provider can be used with other non-Winsock functions such as ReadFile, WriteFile, ReadFileEx, and WriteFileEx.

The XP1_IFS_HANDLES member in the protocol information structure for a provider determines whether a socket handle from a provider is an Installable File System (IFS) handle. Socket handles that are IFS handles can be used without a performance penalty with other non-Winsock functions (ReadFile and WriteFile, for example).

Any non-IFS socket handles when used with non-Winsock functions (ReadFile and WriteFile, for example) result in interactions between the provider and the file system where extra processing overhead is involved that can result in a significant performance penalty. When using socket handles with non-Winsock functions, the error codes propagated from the base file system are not always mapped to Winsock error codes. Consequently, it is recommended that socket handles be used only with Winsock functions.

反正意思就是,如果provider的协议里(WSAPROTOCOL_INFO结构的dwServiceFlags1成员)有XP1_IFS_HANDLES标志,则这个socket就可以直接使用ReadFile等文件函数,并且几乎无性能损耗(多少还是有一些)。

当SPI客户机调用WSPSocket、WSPAccept和WSPJointLeaf函数时,服务提供者必须返回套接字句柄。返回SPI客户机的套接字句柄既可以是可安装文件系统(IFS)句柄,又可以是非IFS句柄。如果一个服务提供者返回的是IFS句柄,就会被视作IFS提供者;反之,就是非IFS提供者。微软的基础传输提供者全都是IFS句柄。

如果你是一个IFS提供者,则你将一个socket返回给调用者时就会导致以下限制:

LSP相关函数解析

WSPStartup

每一个LSP模块都要提供的一个入口函数,定义为:

int WSPStartup(
  WORD                wVersionRequested,
  OUT LPWSPDATA           lpWSPData,
  LPWSAPROTOCOL_INFOW lpProtocolInfo,
  WSPUPCALLTABLE      UpcallTable,
  OUT LPWSPPROC_TABLE     lpProcTable
);

其中lpWSPData和lpProcTable都是我们编写的LSP模块要提供给调用者的,而lpProtocolInfo和UpcallTable是调用者提供给LSP模块使用的。lpProtocolInfo指向的WSAPROTOCOLINFOW结构中包含一个字段ProtocolChain,该字段标志你的服务提供者和机器上的其他提供者是如何排序的。分层式服务提供者的一项要求是搜索ProtocolChain字段,以便决定它自己在服务提供者数组中所处的位置(通过搜索层目录条目这一方式),以及确定数组中的下一个提供者。如果下一个提供者是另一层,就必须把未经修改的lpProtocolInfo结构投给下一层的WSPStartup函数。如果下一层提供者是本数组中的最后一位(即基础提供者),你的提供者就必须在调用基础提供者的WSPStartup函数之前,利用这个基础提供者的WSAPROTOCOLINFOW结构,在lpProtocolInfo结构上执行交换。程序清单14-1演示了分层提供者应该怎样通过编程来管理lpProtocolInfo结构。

你的服务提供者就应该保留一个实例计数,以便了解WSPStartup函数被调用了多少次,再相应地调用WSPCleanup多少次,以便抵消WSPStartup被调用的次数。

SPI安装

传输提供者的安装方式决定了它是一个分层提供者(LSP),还是一个基础提供者(BSP)。安装程序只在Winsock2系统配置数据库中,配置了传输提供者,这个系统配置数据库是一个目录,系统上已安装的服务提供者都在这个目录中。配置数据库让Winsock2得知服务提供者已存在,并定义了提供的服务类型。Winsock应用程序建立套接字时,Winsock2便利用这个数据库来判断需要加载哪些传输服务提供者。WS2_32.DLL在数据库中搜索第一个与socket和WSASocketAPI调用的套接字输入参数(比如说地址家族、套接字类型和协议)匹配的提供者。一旦找到与之匹配的条目,Ws2_32.dll便加载相应的服务提供者之DLL(动态数据链接库),这个DLL是定义在该目录中的。

安装卸载和查询它们需要四个SPI函数。这四个函数的前缀均为WSC:

这些函数利用WSAPROTOCOL_INFOW结构,对服务提供者数据库进行查询和操作。

上一篇 下一篇

猜你喜欢

热点阅读