目前互联网业界主流的服务器开发系统主要包括linux和windows两款操作系统,很多网络服务商需要获取客户端的真实IP和Port,特别是IP地址,对业务策略进行制定,优化;同时客户端的IP和Port信息作为基本的统计数据,对线上业务运营的监控和评估具有非常重要的意义。大部分情况下,服务器端可以通过网络API直接获取连接的网络信息,但是针对服务器前侧添加了代理的网络框架来说,就无法直接通过网络API来获取了。而TOA通过扩展TCP首部的可选字段,可以很好的将客户的真实的IP和Port信息传递到服务器端。因此需要一种手段可以在服务器侧来解析TOA字段,linux系统下的获取在业界有比较成熟的方法获取,但是windows系统下至今没有一种成熟的方案去获取。
目前Linux下获取TOA的方法比较成熟,有专门的TOA系统补丁,主要原理是在网络协议栈层面添加钩子函数,解析出TOA信息后替换存放网络信息的结构体的对端IP和Port字段,这样直接通过网络系统API的调用方式,例如getpeername,来获取客户端网络地址信息。但是在windows系统下没有相似的补丁,系统无法识别TOA字段,无法直接通过系统API来解析或者获取TOA信息。
TOA存在于数据包TCP首部的可选域中,因此在windows系统上利用winpcap对网卡进行监控捕获业务流,并利用程序对业务流进行解析获取到TOA值并缓存起来,同时对应用层提供API来进行访问。
该方案的核心功能点主要包括以下几个方面。
1. 业务数据流捕获与过滤
利用winpcap对对外提供服务的网卡进行监控,可以获取该网卡上的所有数据流,但网卡工作在数据链路层,捕获到数据包括真实的业务数据和其他非相关的数据,需要进一步通过设置过滤规则获取到真实的数据流。
我们知道TCP的连接建立需要进行三次握手,目前大部分中间代理通常会在转发SYN包时打上TOA信息,还有部分中间代理会在每个转发包上都携带TOA信息。因此只需要设置成过滤SYN包即可。
同时,考虑到TCP连接的生命周期,还需要对FIN包和RST包进行过滤。
过滤的具体规则如下(该规则采用winpcap的规则语法进行描述):
( tcp[13] & 0x7 != 0 ) and host x.x.x.x and ( tcp port y1 or tcp port y2…) or ( tcp portrange z1-z2 or… )
其中:
tcp[13] & 0x7 != 0 表示对SYN,FIN,RST进行过滤
host x.x.x.x 表示针对服务器对外提供服务的IP进行过滤
tcp port和 tcp portrange表示针对服务器对外提供服务的一个或多个Port和Port段进行过滤。
2. TOA解析及缓存
目标数据包被捕获后,winpcap会触发一个回调函数对该数据包进行处理,在回调处理函数里根据IP/TCP的首部格式进行解析,可以拿到真实的客户端IP和Port信息。
一般应用层请求真实客户端信息的操作是一个异步操作,因此需要对解析出来的真实网络信息进行缓存。
缓存机制涉及以下两个方面:
1)缓存映射表
以数据包的源IP和Port为key建立hashmap,存储的值为解析出来的真实IP和Port。
2)缓存生命周期
3. TOA获取
应用层根据TCP建立或者通信时获取到的源IP和Port为key,向hashmap进行查询获取到真实客户端IP和Port信息。
该框架包括以下几个部分:
旁路线程:
由上层应用程序创建并初始化,用于启动网卡监控服务,过滤目标数据流以及TOA解析。
TOA映射表:
以TCP源IP和Port为key,TOA解析出来的信息为value所建立的hashmap,主要用于存储和查询TOA信息。
缓冲定时器:
由旁路线程创建,周期性扫描老化表,计算缓冲时间,淘汰老化的键值对,防止资源泄露。
具体步骤如下:
缓冲定时器达到定时时间,触发定时处理函数,遍历老化表,计算缓冲时间,当超过设定的老化时间,从老化表和TOA映射表中清除对应的键值对。
在实现上可以以lib或dll的方式提供,在业务服务程序中进行调用和管理。另外也可以以独立的后台服务存在,通过网络通信的方式与需要获取TOA信息的业务服务进行交互。该方法实现简单,方便管理和维护,与linux不同,不需要对底层协议栈进行深度改造,对系统没有依赖性。同时可以实现与业务程序的隔离,不影响正常业务的运行。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。