【freeDiameter】服务端和客户端的连接流程

连接流程详解

进程启动时,先使用main_cmdline解析命令行参数,比如使用-c就会使用指定路径的配置文件,使用-d就会启用后台进程。

之后使用fd_core_initialize初始化核心库。具体会先使用fd_conf_init初始化配置,比如设置各项的默认值,初始化字典,初始化主事件队列等。之后使用fd_dict_base_protocol,定义了一些基础的 AVP,例如 Vendor-Id、Host-IP-Address、Supported-Vendor-Id等,他们都作为字典对象存放在字典中,以供查询。之后是初始化三个队列,分别是fd_g_localfd_g_outgoing、fd_g_incomingfd_g_local 用于存储需要在本地处理的消息,fd_g_outgoing 用于管理所有待发送到远程对等体的消息,fd_g_incoming 用于存储所有已经接收到但尚未进行进一步处理的消息。之后还有fd_hooks_init、fd_sess_start、fd_p_expi_init。
在这里插入图片描述

接着是fd_core_parseconf 解析配置文件,解析的规则由fdd.lfdd.y生成,其会更新fd_g_config并建立对应的数据结构,其中的ConnectPeer模块会创建peer并调用fd_psm_begin进行启动。

在这里插入图片描述

如上图,fd_psm_begin启动后会创建线程p_psm_th,线程p_psm_th会创建线程connect_thrconnect_thr会像对端发送sctp连接,与对端进行sctp四次握手,成功后将连接cnx构建成事件放到peer的事件队列中,并且创建一个线程rcvthr_notls_sctp来接收消息构建事件并放到连接cnx的事件队列中,线程rcvthr_notls_sctp在成功接收一个普通消息后便结束(即接收到的是sctp的普通消息而非通知,等待的是CEA)。
在这里插入图片描述

之后p_psm_th就能从peer事件队列中取到连接事件并进行处理。具体就是向对端发送CER,然后将连接的事件队列与peer的事件队列进行同步,收到的CEA也就能同步到peer的事件队列中,p_psm_th就能取出CEA事件进行处理。

在这里插入图片描述

p_psm_th取到CEA事件后会创建一个rcvthr_notls_sctp线程来循环接收消息并放到连接的事件队列(peer事件队列)中,之后p_psm_th就可以从peer中一直取消息事件进行处理。

之后使用fd_rtdisp_init初始化运行时分发模块,创建三个线程分别负责dispatch_thrrouting_out_thrrouting_in_thrdispatch_thr 调用 process_thr 函数,并将 msg_dispatch 作为处理函数,fd_g_local 作为消息队列;routing_in_thr调用 process_thr 函数,使用 msg_rt_in 作为处理函数,fd_g_incoming 作为消息队列;routing_out_thr调用 process_thr 函数,使用 msg_rt_out 作为处理函数,fd_g_outgoing 作为消息队列。

msg_rt_in 函数负责处理进入的Diameter消息,包括解析消息头、检查路由信息、决定消息是本地处理还是转发,如果是本地处理就将消息放到fd_g_local中,转发就放到fd_g_outgoing。它确保请求消息根据路由规则和本地配置被正确地分发,并且响应消息被送回正确的请求者。如果消息不符合协议规范或无法处理,该函数还会处理错误响应。

msg_dispatch是消息分发处理函数。它解析消息,检查是否有注册的回调函数来处理该消息,并根据回调函数的返回值或消息类型决定如何进一步处理消息。在test_app中,服务端注册了 ta_tr_cb函数来处理Test_Request。在处理并构建完应答后,会将应答消息或报错消息发布到fd_g_outgoing中等待发送。

msg_rt_out处理Diameter消息路由输出的函数。根据路由规则和对等体状态确定如何转发消息。

接着是调用fd_core_start启动服务器,fd_core_start主要调用了fd_servers_start,fd_psm_start,core_runner_thread,core_state_set

fd_servers_start 函数的作用是初始化并启动 freeDiameter 守护进程的服务器监听功能。其内部会调用new_serv新建一个服务实例,还会启用一个serv_th线程负责监听。该服务会创建一个队列存放客户端的连接请求,并创建一定量的线程运行client_worker,监听线程会将监听到的连接请求放到服务实例的队列中,client_worker会负责处理这些连接对象。如图
在这里插入图片描述

先创建一个线程rcvthr_notls_sctp接收一个消息(CER),将其构建成事件放到连接对象的事件队列中,接着client_worker会去取事件,将事件解析成消息后,判断如果是CER会交给fd_peer_handle_newCER处理。

在这里插入图片描述

fd_peer_handle_newCER会先在peer队列中找到该CER对应的peer,然后将其构建成事件添加到peer的事件队列中,让peer的状态机去处理。

在这里插入图片描述

在peer的状态机中,线程p_psm_th会从peer的事件队列中取出CER事件处理,成功后会向对端发送CEA,并且会创建线程rcvthr_notls_sctp来循环的接收消息,并放到连接的事件队列中(peer事件队列)。

pthread_create(&core_runner, NULL, core_runner_thread, NULL)创建核心运行器线程,这是一个主要的事件处理线程,负责处理守护进程的主要事件循环,直到接收到关闭信号。在test_app的例子中,ta_cli_init注册了ta_cli_test_message回调函数,当指定的信号被触发时,负责处理信号的线程会向主事件队列中发送事件,在由core_runner_thread调用对应的回调函数处理。

core_state_set(CORE_RUNNING)更新内部状态标志,表明核心组件已经启动并运行。用于同步。

之后主线程还会创建负责捕捉处理信号的线程catch_signals,其会循环捕捉信号,处理后将事件发送到主事件队列中。

从上面的流程可知,freeDiameter的节点是不分客户端和服务端的,每一个节点都具有发起连接和接收连接的功能。假设我们先开启了peer1,后开启peer2,从抓到的包中可以看到,CER是由peer2发给peer1

在这里插入图片描述

相反,如果先开启peer2,后开启peer1CER则是由peer1发给peer2

在这里插入图片描述

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值