【ACCESS精品源码栏目提醒】:网学会员,鉴于大家对ACCESS精品源码十分关注,论文会员在此为大家搜集整理了“【精品文档】PDFp服务器代码走读 - 培训资料”一文,供大家参考学习!
《PPTP服务器代码走读》 本文以accel-pptp-0.8.5/pptpd-1.3.3代码为参考主要介绍了PPTP服务器的初始化和工作流程。
416009467qq.com Table List 表目录 表1 缩略语 ...................................................................................................................................... 4 表2 slot数据项描述 ........................................................................................................................ 8 表3 pptp_header数据项描述 ........................................................................................................... 9 Figure List 图目录 图1 模块初始化流程 ........................................................................................................................ 6 图2 PPTP服务器工作主流程 .......................................................................... 错误未定义书签。
7 图3 PPTP服务器与PPPD进程交互过程 ........................................................ 错误未定义书签。
8 图4 数据包处理过程 ........................................................................................................................ 9 Keywords 关键词 PPTP服务器PPPD工作流程进程调用关系 Abstract 摘 要 本文详细介绍了PPTP服务器accel-pptp-0.8.5/pptpd-1.3.3/的启动和工作流程。
其中针对pptp数据包交互的处理过程进行了详细说明并理清PPTPD进程启动PPPD进程处理LCP/NCP阶段数据包的过程。
List of abbreviations 缩略语清单 表1 缩略语 Abbreviations缩略语 Full spelling 英文全名 Chinese explanation 中文解释 VPN Virtual Private Network 虚拟专用网 PPTP Point To Point Tunnel Protocol 点对点隧道协议 PNS PPTP Network Server PPTP网络服务器 PAC PPTP
Access Conecentrator PPTP访问集中器 1 Introduction 简介 1.1 Purpose 目的 本文档为PPTP-Server模块的详细设计说明描述了PPTP服务器模块的主要处理流程及各分析处理的细节流程用于指导下一阶段编码开发的进行。
1.2 Scope 范围 1.3 Name 软件名称 PPTP服务器模块所在目录accel-pptp-0.8.5/pptpd-1.3.3/。
1.4 Functions 软件功能 本模块主要实现PPTP-Server功能的配置管理、运行流程控制、状态监控等。
1.5 Applications软件应用 本模块应用于WAN端使用PPTP服务器方式进行处理连接请求的管理实现。
2 Detailed Design 详细设计 2.1 模块主流程 2.1.1 模块初始化 暂略 2.1.2 PPTP服务器工作主流程 Netctrl通过命令行启动PPTPD进程PPTPD进程进行命令行参数解析处理pptpd.conf中的配置信息Pptp_manager中建立服务器socket监听客户端链接拉起pptpctrl进程做进一步处理。
Pptpctrl中具体针对不同的pptp报文进行相应的相应处理。
拉起pppd进程进一步处理LCP和NCP协商报文。
链接建立完成 图2 服务器工作主流程 2.1.3 PPTP服务器与PPPD进程交互过程 PPTPCTRL进程在launch_pppd构造命令行参数在PPPD进程拉起时使用PPPD进程进行参数解析处理plugin参数打开pptp.so并执行其中的plugin_init函数:完成pptp_channel注册由pppd转入pppd_plugin中执行pppd_plugin中的pptp_connect函数判断服务器调用pptp_start_server函数进而在PPPD主流程中执行get_input处理LCP和NCP阶段报文调用结束 图3 服务器工作主流程 2.1.4 数据包处理过程 PPTP获得从connectionCall传过来的参数。
用pptp_handle_ctrl_connection处理链接数据Y调用read_pptp_paccket函数返回报文类型Pptp_ctr_typeSwitchctrl_typeSTART_CTRL_CONN_RQST调用deal_start_ctrl_conn发送START_CTRL_CONN_RPLY包STOP_CTRL_CONN_RQST调用deal_stop_ctrl_connt发送STOP_CTRL_CONN_RPLY包STOP_CTRL_CONN_RPLYBreakPPTP_ECHO_RPLYBreakECHO_RQST调用deal_echo发送PPTP_ECHO_RPLCALL_RQST调用startCall启动pppd进一步处理OUT_CALL_RPLY调用deal_out_callCALL_CLEAR_RQST调用deal_call_clrCALL_CLEAR_NTFYBreakSET_LINK_INFO调用deal_set_link_infoPptp_ctrl_type-1send_packet FALSE结束Replay_packetSent发送构造好的包 图3 PPTP数据包处理流程 2.2 业务处理 2.2.1 Data Description 数据描述 1. slot 数据结构描述跟踪一个pptp连接的结构一条连接对应一个实例为一个数组结 构。
记录一条链接的两端的虚拟IP地址还用于记录进程的pid。
数据结构定义 struct slot pid_t pid char local char remote slots 表2 slot数据项描述 数据类型 数据项定义 数据项描述 Pid_t pid pptp_manager中fork出处理链接请求的进程号 Char Local 本地serverip Char remote 客户端ip 2. pptp_header 数据结构描述pptp控制报文头。
在pptpdefs.h中定义了各种pptp类型控制报文的结 构他们都包含该数据结构。
数据结构定义 struct pptp_header u_int16_t length / pptp message length incl header / u_int16_t pptp_type / pptp message type / u_int32_t magic / magic cookie / u_int16_t ctrl_type / control message type / u_int16_t reserved0 / reserved / 表3 pptp_header数据项描述 数据类型 数据项定义 数据项描述 u_int16_t length 控制报文长度 u_int16_t pptp_type 恒为1代表为PPTP控制报文 u_int32_t magic 魔术恒为0x1a2b3c4d u_int16_t ctrl_type 控制报文类型1-15 u_int16_t Reserved0 预留位默认填写0 2.2.2 Function Description 函数描述 标识业务处理 类型一级概要设计 功能概述对pptp服务器工作流程中的主要函数进行走读。
函数调用关系按调用顺序整理。
1. main accel-pptp-0.8.5/pptpd-1.3.3/pptpd.c Function: main Description: pptp服务器主函数 Calls: getopt_long slot_init daemon log_pid pptp_manager Input: pptpd的命令行参数 Output: 无 Return: 无 Others: 服务器进程pptpd由netctrl拉起主工作流程如下 A.分析命令行选项用之初始化后续用于配置pptpServer的一些参数。
B. 读取配置文件默认/etc/pptpd.conf用之初始化后续用于配置pptpServer的 一些参数。
C.初始化链接跟踪结构体。
D.依据配置判断是否启动守护进程并调用pptp_manager建立服务端socket 监听处理客户端连接请求 ---------------------------------------------------------------------------------------------------- 实现 int mainint argc char argv main首先循环处理命令行选项对pptpServer进行配置 while 1 获取命令行传入参数 if c -1 循环结束 下段大段的case代码根据选项信息进行相应配置 下段大量的if语句的工作是读取配置文件configFile信息对pptpServer进行配置 多次调用read_config_filechar filename char keyword char value打开指定的 filename文件查找keyword对应的值返回跟在keyword之后的value。
一点说明 程序优先使用命令行参数对pptpServer进行配置用全局变量记录获取到的配置信息以便后面程序的获取。
然后在不与命令行配置信息冲突的情况下使用默认配置文件/etc/pptpd.conf中的配置信息对pptpServer进行配置。
初始化连接跟踪的结构体用于跟踪客户端链接。
对pppd的可执行文件和选项文件进行检查。
if foreground//不设置前台运行 下段代码用于使进程后台运行Kill掉主进程使子进程成为守护进 程后台运行。
ifdef BCRELAY 启动/bin/bcrelay 记录当前进程pid将其写入/var/run/pptpd.pid保存。
最后调用pptp_manager建立服务端socket监听处理客户端连接请求 2. pptp_manager accel-pptp-0.8.5/pptpd-1.3.3/pptp_manager.c Function: pptp_manager Description: 建立服务器Socket并监听处理客户端连接请求。
Calls: connectCall Input: pptpd的命令行参数 Output: 建立子进程处理客户端连接 Return: 无 Others: 由pptpd主函数调用并调用connectCall处理客户端请求 ---------------------------------------------------------------------------------------------------- 实现 int pptp_managerint argc char argv 建立管道用于监听子进程中返回的SIGCHLD信号和SIGTERM信号 if建立失败 exit-1 注册信号处理函数如有信号到达将信号序号输出到sigpipe0方便在select中 对其监听。
ifcreateHostSocket exit-1 调用createHostSocket建立服务器Socket并激活使其处于listen状态。
这是个普通的TCP socket特别之处在于与端口PPTP服务器端口1723绑定 主循环监听服务器端口 While1 注册服务器套接字hostSocket和管道读端sig_fd到监听描述符集中。
轮询端口状态判断是否有可读描述符。
IfSIGCHLD 等待子进程结束更改链接跟踪Slots中对应实例状态 IfSIGTERM 结束slot中所有子进程 If收到客户端发起的请求 accept三次握手建立链接 ifaccept失败 打印出错信息。
else ifaccept成功 监听链接是否有数据有则读取数据包。
对控制报文头进行初步判错处理。
建立子进程调用connectCall进一步处理链接请求。
父进程中关闭当前客户端链接继续监听新客户端请求。
3. connectCall accel-pptp-0.8.5/pptpd-1.3.3/pptp_manager.c Function: connectCall Description: 主要负责拉起pptpctrl进程并为该进程构造传入参数。
Calls: execvePPTP_CTRL_BIN ctrl_argv environ Data Accessed: 无 Data Updated: 无 Input: 客户端链接描述符slot中跟踪序号 Output: 无 Others: 由 pptp_manager调用 ---------------------------------------------------------------------------------------------------- 实现 static void connectCallint clientSocket int clientNumber 将文件描述符“标准输入”0指向clientSocket 构造pptpctrl中用到的命令行参数ctrl_argv 启动pptpctrl进程 execvePPTP_CTRL_BIN ctrl_argv environ 4. main accel-pptp-0.8.5/pptpd-1.3.3/pptpctrl.c Function: main Description: pptpctrl主函数 Calls: sigpipe_assign getsockname pptp_handle_ctrl_connection Input: connectCall中构造的ctrl_argv Output: 无 Return: 无 Others: 由connectCall拉起pptpctrl进程主工作流程如下 A.将命令行传入的参数按顺序解析读取到各全局变量中。
B. 获取本地socket和客户端socket的ip地址连同slot中存储的local和 remote IP作为参数传入pptp_handle_ctrl_connection。
---------------------------------------------------------------------------------------------------- 实现 int mainint argc char argv 解析从connectCall传来的命令行参数 将主函数命令行参数存入全局变量中便于在pptp_handle_ctrl_connection 使用 获取本地socket和对端实际IP 取得现有链接描述符标志并在该基础上设置标志为non-blocking 修改gagrv 注册信号处理函数 通过PAC_VALUE1PNS_VALUE0做判断标志为call_id_pair赋值 确定unit值5-13文件/tmp/pptp/unit在netctrl中初始化为00000000 将对端ip以字符串形式写到文件/tmp/pptp/logininfog_ppp_unit中 调用pptp_handle_ctrl_connection处理链接数据 5. pptp_handle_ctrl_connection accel-pptp-0.8.5/pptpd-1.3.3/pptpctrl.c Function: pptp_handle_ctrl_connection Description: 处理pptp控制报文的函数和拉起pppd进程对链接进行进一步处理。
Calls: make_echo_req_packet read_pptp_packet Input: slot中对应链接的local和remoteIP地址。
Output: 无 Others: 由pptpctrl进程调用 ---------------------------------------------------------------------------------------------------- 实现 void pptp_handle_ctrl_connectionchar pppaddrsstruct in_addr inetaddrs 主循环监听处理Control Message 监听链接设置超时间为idleTime60s Case -1:监听出错 goto leave_clear_call Case 0:监听超时 超时发起空闲链路检测构造echo request包。
if FD_ISSETsig_fd fds 终止信号 信号处理退出进程。
监听到客户端链接端口可读处理控制报文 调用read_pptp_packet函数解析报文类型并构造相应的reply包 switchread_pptp_packet case出错 goto leave_drop_call STOP_CTRL_CONN_RQST: 回送STOP_CTRL_CONN_RPLY包关闭链接 CALL_CLR_RQST 清除链接请求12回送Call-Disconnect-Notify13包并 关闭链接。
OUT_CALL_RQST: 确定隧道两端的Call ID建立PPTP类型的socket具体: 1.read_pptp_packet调用deal_out_call处理此类包。
2.deal_out_call调getcall建立PX_PROTO_PPTP类型socket并与服务器实际IP绑定在bind函数中生成本地call-id。
3.deal_out_call进一步组织OUT_CALL_RPLY包。
启动pppd进程处理请求 /user/sbin/pppd -direct pptp -P chap -b ... ... ... ... 其他情况回送在read_pptp_header中构造号的rply_packet。
等待 echo reply 等待时间超时 goto leave_clear_call 出错段 2.2.3 ADDRESS MANAGEMENT 地址管理 管理客户端地址是PPTP服务器的重要功能因此单独列一部分对PPTP服务器的地址管理功能实现进行详细说明。
1. pptp_delegate 标志 标志作用 先从pptp_delegate这个全局变量说起该变量作为标志控制由pptpd还是由pppd中为客户端分配地址。
如果为FALSE则在pptpd中管理客户端IP并将服务器的虚拟IP和为拨入客户端分配的虚拟IP地址作为命令行参数传递给pppd进程。
如果为TRUE则不在pptpd中管理IP对应处传参0。
标志初始化 该全局变量默认为FALSE可以在启动pptpd进程时通过命令行-D或者在配置文件/etc/pptpd.conf加入一行delegate来设置为TRUE。
PPTP服务器中使用默认值在pptpd中管理客户端IP。
2. slot 结构体 struct slot pid_t pid char local char remote slots 结构体作用 服务器用其记录、分配、回收客户端IP地址。
初始化 pptpd.c的main中调用slot_initpptp_connections对slots数组进行初始化pid0两指针指向NULL。
传入的pptp_connections为最大维护链接数也是slots数组的大小默认值为100可以通过命令行-C或者配置文件/etc/pptpd.conf加入一行connections来实现配置。
pptpd.c的main函数中: if pptp_delegate 读取配置文件/etc/pptpd.conf中remoteip后对应的配置信息到tmp中。
if read_config_fileconfigFile REMOTEIP_KEYWORD tmp