美文网首页
net-snmp源码详解一-网络模块整体框架

net-snmp源码详解一-网络模块整体框架

作者: 布灵不灵的丙丙 | 来源:发表于2021-01-27 17:12 被阅读0次

网络模块整体框架

一般的网络框架处理流程如下:

  • 使用IO多路复用(linux下的select, poll, epoll)分离网络IO。

  • 对分离出来的网络IO进行操作,分为socket句柄可读、可写和出错三种情况。

  • 定时器事件,即检测一个定时器事件列表,如果有定时器到期,则执行该定时器事件。

net-snmp也类似,代码整体逻辑如下:

while (netsnmp_running) 
{
    //更新配置文件
    update_config();
    
    //IO multiplexing
    count = netsnmp_large_fd_set_select(numfds, &readfds, &writefds, &exceptfds, tvp);
    if(count)
    {
        snmp_read2(&readfds);
    }
    
    /*
     * 如果更新配置之后,要先保存配置,防止之后崩溃
     */
     snmp_store_if_needed();

     /*
      * 处理定时器事件
      */
      run_alarms();

     netsnmp_check_outstanding_agent_requests();
}

处理定时器事件的代码如下:

void
run_alarms(void)
{
    struct snmp_alarm *a;
    unsigned int    clientreg;
    struct timeval  t_now;

    /*
     * Loop through everything we have repeatedly looking for the next thing to
     * call until all events are finally in the future again.  
     */

    while ((a = sa_find_next()) != NULL) {
        netsnmp_get_monotonic_clock(&t_now);

        if (timercmp(&a->t_nextM, &t_now, >))
            return;

        clientreg = a->clientreg;
        a->flags |= SA_FIRED;
        DEBUGMSGTL(("snmp_alarm", "run alarm %d\n", clientreg));
        (*(a->thecallback)) (clientreg, a->clientarg);
        DEBUGMSGTL(("snmp_alarm", "alarm %d completed\n", clientreg));

        a = sa_find_specific(clientreg);
        if (a) {
            a->t_lastM = t_now;
            timerclear(&a->t_nextM);
            a->flags &= ~SA_FIRED;
            sa_update_entry(a);
        } else {
            DEBUGMSGTL(("snmp_alarm", "alarm %d deleted itself\n",
                        clientreg));
        }
    }
}

即遍历一个升序定时器列表,将定时器对象与当前时间(t_now)做比较,如果当前时间已经大于或等于定时器设置的时间,则表明定时器时间已经到了,执行定时器对应的回调函数。

再来看看对snmp_read2的处理:

void
snmp_read2(netsnmp_large_fd_set * fdset)
{
    struct session_list *slp;
    snmp_res_lock(MT_LIBRARY_ID, MT_LIB_SESSION);
    for (slp = Sessions; slp; slp = slp->next) {
        snmp_sess_read2((void *) slp, fdset);
    }
    snmp_res_unlock(MT_LIBRARY_ID, MT_LIB_SESSION);
}

int
snmp_sess_read2(void *sessp, netsnmp_large_fd_set * fdset)
{
    struct session_list *psl;
    netsnmp_session *pss;
    int             rc;

    rc = _sess_read(sessp, fdset);
    psl = (struct session_list *) sessp;
    pss = psl->session;
    if (rc && pss->s_snmp_errno) {
        SET_SNMP_ERROR(pss->s_snmp_errno);
    }
    return rc;
}
int
_sess_read(void *sessp, netsnmp_large_fd_set * fdset)
{
    if (transport->flags & NETSNMP_TRANSPORT_FLAG_LISTEN) 
    {
        int             data_sock = transport->f_accept(transport);
        return 0;
    }
    length = netsnmp_transport_recv(transport, rxbuf, rxbuf_len, &opaque,
                                    &olength);
     _sess_process_packet(sessp, sp, isp, transport,
                                           ocopy, ocopy?olength:0, pptr,
                                           pdulen)
}

_sess_read()函数根据状态标识transport->flags确定一个socket是侦听的socket还是普通与客户端连接的socket,如果是侦听sokcet则接收客户端的连接;如果是与客户端连接的socket,则先检测socket上有多少字节可读,如果没有字节可读或者检测字节数时出错,则关闭socket,反之调用处理函数。

snmpd程序使用一个session_list链表来管理所有的socket。

struct session_list *Sessions = NULL;   /* MT_LIB_SESSION */

所以在删除或者新增socket时,实际上就是从这个session_list中删除或者向这个session_list中增加对象。多线程操作,需要一个锁来进行保护:

netsnmp_session *
snmp_open(netsnmp_session *session)
{
    struct session_list *slp;
    slp = (struct session_list *) snmp_sess_open(session);
    if (!slp) {
        return NULL;
    }

    snmp_res_lock(MT_LIBRARY_ID, MT_LIB_SESSION);
    slp->next = Sessions;
    Sessions = slp;
    snmp_res_unlock(MT_LIBRARY_ID, MT_LIB_SESSION);

    return (slp->session);
}

int
snmp_close(netsnmp_session * session)
{
    struct session_list *slp = NULL, *oslp = NULL;

    {                           /*MTCRITICAL_RESOURCE */
        snmp_res_lock(MT_LIBRARY_ID, MT_LIB_SESSION);
        if (Sessions && Sessions->session == session) { /* If first entry */
            slp = Sessions;
            S

相关文章

网友评论

      本文标题:net-snmp源码详解一-网络模块整体框架

      本文链接:https://www.haomeiwen.com/subject/pomazktx.html