分布式软总线/authmanager/source/auth_interface.c及其头文件概述(二)
鸿蒙设备认证代码分析
auth_interface.c
知识储备
注意这里的链表应该是个双向链表——也就是头尾相接含左右指针的双向链表
- 使用宏定义的循环进行链表的循环
(common_info_manager.h)
从头结点的下一个——也就是第一个存储数据的结点开始,设置前后两个指针开始遍历,直到后一个指针指向头部结束。
这样的结构可以很好的对链表进行增删查改具体下面会有详细描述
- getInstance与new
在C中实现单例模式:
- 禁止类的外部创建类对象,把构造函数设置为私有
- 类自己维护一个实例对象,使用静态指针
- 提供一个获取实例对象的方法,定义一个静态成员函数用于获取唯一的实例对象
getInstance与new的区别
- new一定要生成一个新对象,分配内存,getInstance则不一定要再次创建,可以使用一个已存在的引用,效能上较优
- getInstance()可以跨栈区域使用,或者远程跨区域使用。
- 单例模式可以防止数据冲突,节省内存空间,在函数static int AuthInitHiChain(uint32_t sessionId)中使用了该方法
综合概述
- 本次博客的内容主要聚焦在双向循环链表的增删查改的函数上。该.c文件中大量出现了两种结构:一是g_authSessionMap[ ]这个存储用户身份认证会话信息的结构体数组;另一个是g_sessionKeyList将对应身份认证密钥上链的双向链表。大量的函数就是针对这两个结构体进行功能性的扩展和检查。
- 将其剖析:通过层层的结构体嵌套我们可以看到数组中蕴含的信息是巨大的:

函数剖析
-
通过标识符在会话密钥列表中删除一个结点
void ClearSessionKeyByFd(int fd)
-
通过seq序列号清除会话密钥结点
static void ClearSessionKeyBySeq(long long seq)
实现方法与上一个函数类似,不再赘述 -
在密钥链表中插入一个新结点
static int AddNewSessionNode(int fd, int index, const struct hc_session_key *session)
这里同样使用了common_info_manager中封装的方法ListInsertTail将对应结点插入对应的链表中——而插入尾部的方法也是非常简洁四行代码对应了头结点和插入结点的四个指针:
理解了双向链表的操作,才能理解后面的函数功能实现
-
结点的替换函数
static int ReplaceOldSessionNode(int fd, int index, const struct hc_session_key *session)
这个函数很有意思,充分利用了空间,这里的替换不是我们想象中的通过某个属性进行替换,而是类似队列的,最先的出队列,后进的在队列尾部
首先是ListPopFront()函数
同样调用函数ListRemoveNode(List *node)将该结点从链表中删除
由于将第一个结点移除了链表,所以就不需要额外的空间来新建一个结点
直接使用memset_s()将其内容重置为0
将新结点的内容分配到其中,通过ListInsertTail(g_sessionKeyList, &node->head)函数将新结点插入尾部完成结点的更替

- AddSessionKey(const struct session_identity *identity, const struct hc_session_key *session)
添加新的密钥链表块

- 两个获取sKey的函数:
一个通过index一个无参数直接获取最新的会话密钥

- 在AddSessionKey(identity, session)函数上层再封装一层函数AuthSetSessionKey()在检查完身份和会话都存在后,将该身份认证信息上链。

- 通过sessionid将对应的密钥从密钥链上删除,对应的会话数组的数据删除 AuthSetServiceResult()

- HiChain的初始化函数
static int AuthInitHiChain(uint32_t sessionId)
在实例化g_hcHandle时使用了get_instance这个单例设计模式。将hiChainCallBack作为方法 ,serverIdentity作为私有属性进行私有构造
- 成功init HiChain之后,根据sessionid在会话数组中删除其对应的数并构造一个请求并发送的函数

- 最后一个是数据的接收函数,也就是在上一个函数的基础上又多一层检查和新会话id的更新,最后根据模式的匹配,调用上一个函数进行数据的接收。
值得注意的是如果给出的seqId是原数组中不存在的,会调用AuthGetNewAuthSession()新建一个数据块
感谢大家的点赞与评论!
更多推荐

所有评论(0)