本文旨在向读者介绍和熟悉远视安全®  股份有限公司(现在是香格里拉娱乐的一部分)AXA C API。它将介绍libaxaC编程API,并展示一个简单的工作示例程序。

此信息适用于SIE远程访问(SRA)的用户。本文假设读者熟悉AXA和相关技术。在AXA上,一个很好的起点是 AXA用户指南

本文面向中级C程序员,并不是详尽的API参考资料。为此,读者可以参考随附的 编程辅助工具-基于API手册,可在 AXA GitHub存储库请查看 附加信息 下面的部分。本文涵盖 利巴萨 版本 1.1.2

sratesttool

sratesttool 是一个Unix命令行实用程序,能够执行以下操作:

  • 连接到SRA服务器
  • 启用SIE通道
  • 设置AXA手表
  • 流媒体观看点击到控制台

在这个简短的系列中,香格里拉娱乐将研究所有这些是如何完成的。在第一篇文章中,香格里拉娱乐将介绍包含初始化代码并控制主程序流的主驱动程序。例如:

$sratesttool-s tls:user@sraserver,1021-c,255,ch=255
远视安全SRA测试工具
连接到tls:user@sraserver,1021...
有联系的
正在解析监视:ch=255。。。
解析ch=255正常
正在服务器上设置监视。。。
手表设置正常
正在分析通道:255。。。
解析255 OK
正在服务器上启用频道。。。
通道已启用OK
NMSG手表点击,频道:255@2015-07-29T19:13:21.111788988
NMSG手表点击,频道:255@2015-07-29T19:13:21.612488985
NMSG手表点击,频道:255@2015-07-29T19:13:22.113173007
NMSG手表点击,频道:255@2015-07-29T19:13:22.613782882
NMSG手表点击,频道:255@2015-07-29T19:13:23.114434957
NMSG手表点击,频道:255@2015-07-29T19:13:23.615050077
NMSG手表点击,频道:255@2015-07-29T19:13:24.15665912
NMSG手表点击,频道:255@2015-07-29T19:13:24.616344928
NMSG手表点击,频道:255@2015-07-29T19:13:25.117007970
NMSG手表点击,频道:255@2015-07-29T19:13:25.617640972
^C10总观看次数

请注意 sratesttool 不是AXA协议的完整实现。它是关于如何建立与SRA服务器的简单连接、发出一些命令和流式传输数据的教程。 sratesttool 仅适用于TLS和许多 利巴萨 不采用代码路径,也不执行鲁棒错误检查。它旨在作为入门级程序,让读者熟悉AXA协议和 利巴萨 API

祝你好运。c

代码为 sratesttool 包含在单个源文件中,可以编译成功能齐全的程序。要构建它,您需要链接到 利巴萨 图书馆。您可以在以下位置找到源代码 AXA GitHub存储库。如果您是Debian用户,也可以下载软件包。虽然香格里拉娱乐将在几篇文章中介绍源代码,但完整的源代码可以从Farsight Security的博客代码GitHub页面下载。

序言

第一部分包含源代码许可证,标准C头文件包括进度:

/**版权所有(c)2015,Farsight Security,股份有限公司**根据Apache许可证2.0版(“许可证”)授权;*除非遵守许可证,否则您不得使用此文件。*您可以在**获得许可证的副本http://www.apache.org/licenses/LICENSE-2.0**除非适用法律要求或书面同意,否则根据许可证分发的软件*按“原样”分发,*不作任何明示或暗示的保证或条件。*有关许可证下管理权限和*限制的具体语言,请参阅许可证。*/#包括<sysexits.h>#包括<unistad.h>#包括<signal.h>#包含<limits.h>#include<axa/client.h>#included<axa/axa_endin.h>

服务器特定功能

以下特定于服务器的函数封装了libaxa函数。香格里拉娱乐稍后将详细探讨所有这些,因为现在了解它们的作用就足够了:

  • srvr_connect():连接到服务器。– srvr_cmd():向服务器发送命令并等待响应。
  • srvr_wait_resp():等待服务器的响应。
  • srvr_process():处理来自服务器的消息。
  • srvr_断开连接():断开与服务器的连接。
/*连接到服务器**成功时返回true,失败时返回false*/static bool srvr_connect(void);/*向服务器发送AXA命令并等待响应**成功时返回true,失败时返回false*/static bool srvr_cmd(AXA_tag_t,/*AXA标记或AXA_tag_NONE*/AXA_p_op_t,/*AXA操作码(原始)*/const void*,/*要发送的消息正文*/size_t,**消息长度*/AXA_p_op_tt);/*预期响应操作码*//*等待服务器的响应**成功时返回true,失败时返回false*/static bool srvr_wait_resp(axa_p_op_op_t,/*预期响应操作代码*/axa_p_op_t);/*原始操作码*//*处理来自服务器的消息*/static void srvr-process(void);/*断开与服务器的连接并打印消息*/static void srvr_connect(const char*,/*要打印的消息*/…)/*可选varargs*/AXA_PF(1,2);

其他函数

接下来声明其他函数:

/*停止一切并关机*/
静态无效停止(int/*exitcode*/
                        );
/*信号处理机*/
静态空洞信号项(int/*捕获信号的信号数*/
                        );
/*打印使用情况*/
静态空用法(const char*/*程序名*/
                        );

全局变量

有一小部分全球数据:

  • 静态axa_client_t客户端:不透明blob,包含所有客户端状态。
  • 静态常量char*server_str:传输/用户名/服务器字符串。
  • 静态常量char*watch_str:表链。
  • 静态常量char*channel_str:频道字符串。
  • 静态int终止:当此值大于0时,是时候退出了
  • 静态uint64_t次点击:手表点击次数 sratesttool 已经观察到。
静态axa_client_t客户端;
静态常量char*server_str;
静态常量char*watch_str;
静态常量char*channel_str;
静态int终止;
静态uint64_t点击;

主函数参数处理

main函数的初始节是标准且无趣的命令行参数处理:

intmain(int argc,char**argv){int opt;axa_emsg_t emsg;const char*cp;而(opt=getopt(argc,argv,“c:hs:w:”;}}如果(server_str==NULL ||channel_str==NULL||watch_str==空){fprintf(stderr,“-s,-c,-w都是必须的\n”)return(EX_usage);}

Axa初始化

接下来,香格里拉娱乐遇到第一个 利巴萨 API函数调用。第一节建立了AXA日志子结构。便利设施之一 利巴萨 offers是一个不透明的“三流”日志记录/syslog接口。与 利巴萨,您有以下日志流:

  • trace:跟踪服务器端错误消息的流
  • verror:客户端错误消息的错误流
  • 会计:会计信息(数据包发送/丢失/传输/限制总计)

sratesttool 不使用syslog接口,因此初始化记录器以仅向以下对象发出消息 斯特德尔有关更多信息,请参阅Doxygen手册 axa_parse_log_opt()

日志初始化后,香格里拉娱乐初始化AXA客户端上下文。这是一个不透明的结构,包含打开和维护SRA服务器连接所需的所有状态。

接下来是信号处理。为了有序地退出导致终止的信号 sratesttool 通过垃圾收集和统计报告,香格里拉娱乐捕获并将其传递给香格里拉娱乐的简单信号处理程序。

/*设置全局程序名(用于日志记录)*/axa_set_me(argv[0]);/*将跟踪流设置为仅向stderr发出*/AXA_ASSERT(AXA_parse_log_opt(&emsg,“trace,off,stderr”));/*将错误流设置为仅向stderr发出*/AXA_ASSERT(AXA_parse_log_opt(&emsg,“error,off,stderr”));/*将记帐流设置为仅向stderr发出*/AXA_ASSERT(AXA_parse_log_opt(&emsg,“acct,off,stderr”));/*初始化AXA系统日志接口*/AXA_syslog_init();/*确保所有stdio FD都已打开并准备就绪*/axa_clean_stio();/*初始化客户端上下文(包括AXA IO引擎)*/AXA_client_init(&client);/*捕获并处理这些信号以实现优雅退出*/signal(SIGPIPE,SIG_IGN);信号(SIGHUP,sigterm);信号(SIGTERM,SIGTERM);信号(信号情报,信号项);axa_trace_msg(“远视安全SRA测试工具”);

服务器连接

此时,香格里拉娱乐的AXA客户端已初始化 sratesttool 已准备好开展业务。然后,它会伸出手来尝试连接到服务器。如果出了什么问题, sratesttool 将保释。更稳健的实现,例如 sratoolsratunnel 以及 轴向 将尝试使用指数回退重试算法重新连接。

很多核心 利巴萨 代码包含在srvr_connect()函数中,包括:

  • 打开与服务器的客户端连接。
  • 解析监视字符串并在服务器上设置监视。
  • 解析频道字符串并在服务器上启用频道。
  • 正在启动数据流。

稍后香格里拉娱乐将对此进行更详细的探讨。

/*尝试(一次)连接到SRA服务器,并在出现任何错误时挂起*/
if(!srvr_connect())
{
退出(exit_FAILURE);
}

过程数据

香格里拉娱乐现在进入无限事件循环。第一次检查总是看看 sratesttool 需要退出(由于异步事件,例如用户在控制台上按ctrl-c)。

呼叫 axa_io_wait() 告诉 利巴萨 只需等待长达10ms的服务器输入。在内部,libaxa轮询其文件描述符列表,以查找来自服务器的输入。如果定时器到期并且没有数据可用, axa_io_wait() 会回来的 AXA_IO_BUSY 它只是将控制返回到循环的顶部。如果数据正等待读取, AXA_IO_OK 将被退回 srvr_process() 将被调用来处理它(稍后将详细介绍)。对于sratesttool来说,大多数时候,这应该是观看点击。如果轮询时出现问题, AXA_IO_ERR 被退回 sratesttool 将断开连接并退出。

同样值得注意的是, axa_io_wait() 调用时没有keepalive功能(本例中不需要),也没有隧道调试(仅用于基于SSH的连接)。

/*事件循环,香格里拉娱乐连续等待/发送数据/等待*/for(;){if(terminated!=0){stop(terminate);}/*等待服务器*/交换机的数据长达10ms(axa_io_wait(&emsg,&client.io,/*axa io引擎的地址*/10,/*等待这么多ms*/false,/*唤醒以发送保活*/ffalse))/*注意隧道消息*/{/*axa io错误*/case axa_io_ERR:srvr_disconnect(“%s”,emsg.c);break;/*不完整响应,poll()并重试*/case axa_io_BUSY:break;/*操作已完成,是处理结果的时间*/case axa_io_OK:srvr_process();break;默认值:axa_FAIL(“不可能的axa_io_wait()结果”);}}}

连接到服务器并设置状态

香格里拉娱乐将剖析的第一个srvr_*函数是一个很大的函数,负责连接到SRA服务器、设置监视和启用通道。首先,香格里拉娱乐解释AXA特有的重要数据类型/变量:

  • axa_p_watch_t 手表:AXA手表对象;包含AXA手表规格的所有状态。
  • axa_p_channel_t channel:AXA通道对象;包含AXA通道规范的所有状态。
  • axa_emsg_t emsg:AXA错误消息对象;如果libaxa函数中发生错误,这将包含导致错误的详细信息。
  • axa_tag_t cur_tag:标记是用于在AXA会话的生命周期内唯一“标记”特定事件的标识符。为了引用这些事件,客户端或服务器将使用标签。某些AXA邮件不需要标记,在这种情况下,香格里拉娱乐将使用该值 AXA_TAG_NONE所需标签在相应客户端请求的生命周期内必须是唯一的。一些客户端请求(如手表)可以无限期持续,并会引发许多服务器响应,所有响应都带有相同的标签。
静态布尔值
srvr_connect(void)
{
axa_p_watch_t手机表
size_t watch_len
[UNK][UNK]axa_p_channel_t通道
[UNK][UNK]axa_emsg_t emsg
[UNK][UNK]布尔值;
[UNK][UNK]axa_tag_t cur_tag

连接到服务器

这个 axa_client_open() 函数试图打开服务器连接并为客户端的连接建立状态。通过引用传递的前两个参数将由以下内容填写 libaxa;emsg; 如果出了什么问题, 客户 如果没有什么)。下一个论点, server_str 是以下格式的特制文本字符串:transport:user@server[,港口]。

  • 传输:SRA支持TLS或SSH作为加密传输。sratesttool只支持TLS,所以这里的参数应该是TLS。
  • user:用户的用户名。当您的帐户打开时,Farsight Security会提供此功能。
  • 服务器:SRA服务器的IP地址或主机名。
  • port:仅用于TLS,指定SRA服务器监听TLS连接的端口。

输入套接字缓冲区大小设置为 256  1024,由于SRA传输的SIE数据量可能很大,因此该值大于正常值。在内部,这将被要求由 设置锁定(.SO_RCVBUF..)

返回值来自 axa_client_open() 在一个小的开关表中进行评估,该表根据以下内容检查错误或不合逻辑:

  • AXA_CONNECT_ERR:出了点大问题,打印 emsg 然后退出。
  • AXA_CONNECT_TEMP:发生临时错误,打印 emsg 然后退出。在更健壮的实现中,香格里拉娱乐可能会退缩并重试。
  • AXA_CONNECT_DONE:连接已完成。
  • AXA_CONNECT_NOP:连接已完成 AXA_P_OP_NOP 被发送到服务器。这样做是为了让客户端可以告诉服务器客户端正在使用的AXA协议的版本。如果需要,服务器可以降级到旧版本的协议。
  • AXA_CONNECT_USER:对于基于TCP的套接字连接,不适用于TLS(或SSH)连接,在这种情况下应该是一个错误。
axa_trace_msg(“连接到%s…”,server_str);switch(axa_client_open(&emsg,/*如果func失败,将包含错误*/&client、/*客户端上下文*/server_str、/*服务器地址字符串*/false、/*true以启用RAD模式*/ffalse、/*SSH隧道调试时为true*/256*1024、/*socket缓冲区大小*/ffalse)/*true表示非阻塞*/{/*永久性故障,连接已关闭,检查emsg*/case axa_CONNECT_ERR:axa_error_msg(“%s”,emsg.c);return(false);/*表示临时故障,连接已经关闭,检查emsg。*在更健壮的实现中,香格里拉娱乐将尝试重新连接到*服务器。*/case axa_CONNECT_TEMP:axa_error_msg(“%s”,emsg.c);srvr_dennect(“%s“,emsg-c);return(false);/*连接完成*/case axa_CONNECT_DONE:break;/*等待TCP SYN/ACK或TLS握手的非阻塞连接*/情况AXA_CONNECT_INCOM:AXA_FAIL(“AXA_client_open不可能的结果”);/*连接已完成(包括AXA_P_OP_NOP的xmit)*/case AXA_connect_NOP:中断;/*连接已完成(包括AXA_P_OP_USER的xmit)*/case AXA_connect_USER:srvr_disconnect(“%s”,emsg.c);return(false);}

暂停输出

成功连接到服务器后,但在设置任何监视或启用频道之前 AXA_P_OP_P_P_PAUSE 命令已发送。这个“暂停”命令告诉服务器停止发送数据,并在服务器端实际丢弃数据。这是一个全局开关,用于暂停当前用户所有通道的数据输出。

这是香格里拉娱乐第一次遇到 srvr_cmd() 用于向SRA服务器发送命令和数据的函数。稍后香格里拉娱乐将详细介绍它,但现在重要的是要注意它接受AXA标记参数:

  • AXA_TAG_MIN:“最小”标签值,这是一个非特定的标签值,当香格里拉娱乐需要一个标签但不关心哪个标签时使用。

以及两个AXA操作码参数:

  • AXA_P_OP_P_P_PAUSE:表示请求服务器执行的操作的操作码。在这种情况下,暂停数据流。
  • AXA_P_OP_OK:服务器应提供的操作码,以便将操作视为成功。
/*在香格里拉娱乐准备好之前,阻止任何手表点击*/
如果(!srvr_cmd(AXA_TAG_MIN、AXA_P_OP_PAUSE、NULL、0、AXA_A_P_OP_OK)
{
return(false)
}

解析并设置手表

接下来,通过调用来解析监视字符串 axa_parse_watch()如果解析它时出现问题, 利巴萨 将尽最大努力在中发出有用的错误消息 emsg。但是,如果观察字符串没有意义,函数将以空值失败 emsg

有关SRA手表外观的详细说明,请参阅 sratool(1).

成功解析手表后,通过调用在服务器上设置它 srvr_cmd() AXA操作码为 AXA_P_OP_WATCH 以及预期的服务器响应 AXA_P_OP_OK

cur_tag=1/*解析监视字符串*/axa_trace_msg(“解析监控:%s…\n”,watch_str)res=axa_parse_watch(&emsg、&watch、&watch_len、watch_str)if(!res){if(emsg.c[0]=='0'){axa_error_msg(“无法识别”-w%s“,watch_str);}else{axa_error _msg(“-w%s”:%s”,watch_str,emsg.c);}返回(false);}else{axa_trace_msg(“解析%s正常”,watch_str);}/*在服务器上设置监视*/axa_trace_msgif(!srvr_cmd(cur_tag、AXA_P_OP_WATCH、&WATCH、WATCH_len、AXA_P-OP_OK){返回(false);}AXA_trace_msg(“手表设置正常”);

解析并启用频道

接下来,以与上述相同的方式,在服务器上解析并启用通道字符串。

memset(&通道,0,大小(通道));/*解析通道字符串*/axa_trace_msg(“解析通道:%s…\n”,channel_str)if(!axa_parse_ch(&emsg,&channel.ch,channel_str,strlen(channel_str),true,true){axa_error_msg(“-c%s”:%s”,channel_strs,emsg.c);return(false);}else{axa_trace_msg(“parse%s OK\n”,chancell_str);}channel.on=1axa_trace_msg(“正在服务器上启用通道…\nif(!srvr_cmd(AXA_TAG_MIN,AXA_P_OP_CHANNEL,&通道,sizeof(通道),AXA_A_P_OP_OK){返回(false)}

取消暂停输出

在信道被启用之后, sratesttool 已准备好开始流式传输观看热门歌曲。它通过发送操作码让服务器知道 AXA_P_OP_GO 它告诉服务器是时候取消使用输出了。

现在服务器连接过程完成,函数成功返回。

if(!srvr_cmd(AXA_TAG_MIN、AXA_P_OP_GO、NULL、0、AXA_A_P_OP_OK){返回(false);}AXA_trace_msg(“通道已启用正常”);return(true);}

在服务器上运行命令

下一个函数,正如香格里拉娱乐已经看到的, srvr_cmd(),用于向SRA服务器发送操作码和数据。这是一个包装 axa_client_send() 通过附加代码断开连接 srvr_断开连接() 如果出现问题。

香格里拉娱乐已经介绍了标签和操作码参数,但 srvr_cmd() 函数还接受不透明指针及其长度形式的数据。呼叫 axa_client_send() 向服务器发出请求,如果没有失败,则调用 srvr_wait_resp() 以处理响应。

静态boolsrvr_cmd(axa_tag_t标签,axa_p_op_top,const void*b,size_t b_len,axa_p_op_t resp_op){axa_p_hdr_t hdr;axa_emsg_t emsg;char pbuf[axa_p_STRLEN];if(!axa_client_send(&emsg,&client,tag,op,&hdr,b,b_len)){srvr_connect(“发送%s利息:%s”,axa_pmoto_str(pbuf,sizeof(pbuf),true,&hdr,b),emsg.c)return(false);}return(srvr_wait_resp(resp_p,op));}

等待服务器的响应

主事件循环,其中 sratesttool 从SRA服务器接收输入,并决定如何处理它,称为 srvr_wait_resp() 接下来将介绍。该功能可分为三个部分:

  1. 检查是否到了退出的时间
  2. 从服务器接收输入
  3. 确定如何处理输入

检查是否到了退出的时间

第一件事 srvr_wait_resp() 检查全局哨兵值 结束 设置为true。在这种情况下,其中一个信号 sratesttool 被初始化为catch,已被catch。大多数时候,这将是 签名 用户按下“ctrl-c”在控制台上。在这种情况下, 停止() (如下所述)被调用,开始关机过程。

静态boolsrvr_wait_resp(axa_p_op_t resp_op,axa_p_top_t orig_op){布尔结果,完成;axa_emsg_t emsg;结果=假;完成=假;做{if(终止!=0){停止(终止);}

从服务器接收输入

如果还没到退出的时候,控制权就交给了 axa_input().此函数接受标准 emsg 香格里拉娱乐已经看到的论点,指向 客户端.io 上下文,以及阻塞和等待输入的毫秒数,在本例中为 INT_MAX (在等待数据时,这可以被视为一个不确定的块)。

结果被切换,并对以下情况进行评估:

  • AXA_IO_ERR:发生致命错误,转储错误并返回false,这将导致上层终止程序。
  • AXA_IO_BUSY:在poll()计时器到期或发生其他非致命情况之前没有输入。控制权继续回到顶部。
  • AXA_IO_OK:已收到有效数据,是时候考虑如何处理了。
switch(axa_input(&emsg,&client.io,INT_MAX){案例axa_io_ERR:axa_error_msg(“%s”,emsg.c);返回案例axa_io BUSY:继续案例axa_io.OK:中国默认值:axa_FAIL(“不可能的axa_input”)24英寸);}

确定如何处理输入

接下来, sratesttool 在大型交换表中评估接收到的AXA协议消息头的操作码。为了后代,列出了所有可能的操作码,在更健壮的实现中,每个代码路径都可能被填充。假使 sratesttool 只有两个服务器响应是有趣的:

  • AXA_P_OP_HELLO:处理来自服务器的“hello”消息。服务器使用的AXA协议版本将被保存,客户端将尝试调整到它可以理解的版本。
  • AXA_P_OP_OK:处理来自服务器的“结果”消息。在这里 sratesttool 确保接收到的操作码是预期的操作码。

在处理响应之后, axa_recv_flush() 被调用进行清除(free())来自IO上下文的AXA协议消息。

如果出了什么问题, axa_client_backoff() 这将导致客户端关闭与服务器的连接并关闭IO上下文。

switch((axa_p_op_t)client.io.recv_hdr.op){案例axa_p_NOP_NOP:break案例axa_p-op_HELLO:if(!axa_client_HELLO(&emsg,&client,NULL)){axa_error_msg(“%s”,emsg.c);}else{axa_trace_msg(“连接正常”);}断裂案例AXA_P_OP_OPT:完成=真;断裂;case AXA_P_OP_OK:例如(resp_OP==客户端.io.recv_hdr.OP&&&orig_OP==客户端-io.recv_body->result.orig_OP){result=true;done=true;}break案例AXA_P_OP_ERROR:AXA_ERROR_msg(“服务器返回错误”);done=真;新福;案例AXA_P_OP_MISSED:案例AXA_P-OP_MISSED_RAD:案例AXA_ P_OP_WHIT:案例AXA_P_OP_AHIT:案件AXA_P_OP _WLIST:案例AXA_P.OP_ALIT:案例AXA_P_OP_CLIST:/*在此函数中,这些都是意外的操作代码*/断裂案例AXA_P_OP_USER:案例AXA_P_up_OP_JOIN:案例AXA-P_OP_OP_ause:案例AXA_P_OP_GO_GO:案例AXR_P_OP_WGET:案例AX_AP_OP_nop_OP_nanom:案例AX A-P_o0_get:案例TAA_P_OP-STOP:案例AXA。P_OP_ALL_STOP:案例AXI_OP_OP_CHANNEL:案例AXB_P_OP_CGET:案例AXA_P_OP_ACT:案例AXA_P.OP_RADU:默认值:AXA_FAIL(“无法从%s执行%d的AXA操作”,client.io.recv_hdr。OP,客户端.io)标签);}axa_recv_flush(&client.io);}而(!完成)out:if(!result){/*如果香格里拉娱乐没有得到正确的响应,现在断开连接*/axa_client_backoff(&client);}return(结果);}

断开与服务器的连接

如果出了什么大问题, sratesttool 将通过以下方式发出错误消息 axa_verror_msg() 并通过以下方式关闭服务器连接 axa_client_backoff()如前所述,更稳健的实施可能会利用内部 后退 计时器并尝试重新连接。

停止和关闭

这个 停止() 函数在任何时候都会被调用 打断 哨兵评估为不 0。它执行有序关机,报告手表点击次数,然后退出程序。

静态空AXA_NORETURNstop(int s){AXA_client_close(&client);AXA_io_cleanup();AXA_trace_msg(“%”PRIu64“总监视点击数”,点击数);退出;}

从服务器读取SIE数据

每次SIE数据准备就绪时从主事件循环调用的函数被调用 srvr_process()首先, axa_recv_buf() 调用并评估结果。值得注意的是 axa_recv_buf() 如果这是不可取的,可以使用前面介绍的其他服务器读取功能,例如 axa_io_wait()axa_input().一旦 AXA_IO_OK 返回后,控制传递到另一个交换表,在那里评估响应操作码。

静态voidsrvr_process(void){int n;char buf[BUFSIZ];axa_emsg_t emsg;struct timespec ts;struct tm*tm_info;switch(axa_recv_buf(&emsg,&client.io)){case axa_io_OK:break;case axa_io _ERR:srvr_onnect(“%s”,emsg.c);return;case axa-io_BUSY:return;/*等其他的*/case axa_io_KEEPALIVE:/*本例不适用*/case axa_io_TUERR:/*此示例不适用**/break

处理手表点击

唯一的案例 sratesttool 感兴趣的是 AXA_P_OP_WHIT当接收到的报头操作码是“监视命中”时, sratesttool 接下来计算出向客户端报告的手表命中类型,NMSG或IP。虽然 sratesttool 对手表点击的内容不感兴趣,它确实需要提取时间戳,时间戳根据类型存储在不同的地方。接下来,使用手表点击的类型、它发生的SIE通道和手表点击的时间戳(包括纳秒)构建一个人类可读的字符串。这个 击打 计数器递增并且控制进行到切换表的末尾, axa_recv_flush() 被调用以从IO上下文中清除AXA协议消息。

n=0switch((axa_p_op_op_t)client.io.recv_hdr.op){case axa_p_NOP_NOP:break;case axa_A_p_op_up_ERROR:srvr_connect(“”);return;case axa_p_op_MISSED:case axa_p-op_MISSED_RAD:break,case axa_p.op_WHIT:switch(client.io.recov_body->WHIT.hdr.type){case ax A_p_WHIT_NMSG:ts.tv_sec=client.io.recv_body->WHIT.NMSG.hdr.tv_sec;ts.tv_nsec=client.io.recv_body->WHIT.NMSG.hdr.ts.tv_nsec;break;案例axa_p_WHIT_IP:ts.tv_sec=axa_P2H32(客户端.io.recv_body->WHIT。IP.hdr.tv.tv_sec)ts.tv_nsec=1000*axa_P2H22(客户端-io.recv.body->whik。IP.hdr.tv.tv_usec)断裂n=strftime(buf+n,26,“%Y-%m-%dT%H:%m:%S”,tm_info)snprintf(buf+n,BUFSIZ-n,“.%ld”,ts.tv_nsec)axa_trace_msg(“%s观看命中,频道:%3d@%s\n“,客户端.io.recv_body->whit.hdr.type==axa_P_whit_NMSG“NMSG”:“IP”,客户端/io.recv.body->whith.hdr.ch,buf)点击++;断裂;案例AXA_P_OP_OP_AHIT:案例AXA_P_up_OP_OK:案例AXA_P_OP_up_HELLO:案例AXR_P_OP_g_WLIST:案例axe_P_OP_nop_OPT:案例AXB_P_OP_CLIST:中国;案例AXA_P_OP_USER:案例AXA_A_P_OP_JOIN:案例AXA P_OP_ause:案例AXA_P_OP_GO:案例AXA_P_OP_WATCH:案例AXR_P_OP_up_get:案例AX_AP_OP_OP_nom:案例AXA-P_OP_g:案例TAA_P_oi_top_gtop:案例AXA。P_OP_ALL_STOP:案例AXI_OP_OP_CHANNEL:案例AXB_P_OP_CGET:案例AXA_P_OP_ACT:案例AXA_P.OP_RADU:默认值:AXA_FAIL(“无法从%s执行%d的AXA操作”,client.io.recv_hdr。OP,客户端.io)标签);}axa_recv_flush(&client.io);}

信号处理器

信号处理程序只需设置全局哨兵 结束 信号的积分值。这使得上层能够:

  1. 知道何时发生了异步事件,是时候退出了
  2. 知道向哪个信号发送 sratesttool

如果信号被反复发送,则被视为紧急和 sratesttool 将通过以下方式重置默认信号处理程序 信号(sig、sig_DFL) 这将立即终止程序。

voicesigterm(int sig){终止=sig;信号(sig,sig_DFL);/*在重复信号时提前退出*/}

使用方法

最后,香格里拉娱乐以一个简单的使用函数结束,该函数指示用户如何调用 sratesttool

static voidusage(const char*name){printf(“SRA测试工具(c)2015 Farsight Security,股份有限公司\n”);printfuser@server,端口]\n”);printf(“ttuser:SRA用户名\n””);print f(“tt服务器:SRA服务器\n”)\n“);}

结论

香格里拉娱乐已经介绍了 sratesttool,一个非常简单的“hello world”SRA客户端。如果您有兴趣了解更多信息,请查看AXA发行版存储库,其中包含 sratool 这些是构建在SRA客户端之上的更稳健的实现 利巴萨

附加信息