Tor源码分析五 -- 客户端执行流程(libevent调度)

Tor源码 -- core分析 tor coreor connectioncircuitstream or connection or connection负责op与or或者or与or的连接(两个主机之间的连接)。 包括TLS连接,handshake等等。 到目前为止, tor有3种握手方式:certificate up-front, renegotiation, in-protocol. or_connection_st.h声明了or connection数据类型,connection_or.c文件有操作函数。 circuit stre 阅读详情

  上一源码分析的小节中,已经将系统的主要流程启动过程介绍完毕。实际上,系统在如此启动之后,就可以通过正确的流程将Tor系统完整的启动起来,为用户提供应用程序代理服务,以达到匿名通信的目标。本节的目标,不是为了详细介绍系统初始化后的正确启动流程,而是介绍系统是如何通过Libevent的调度实现成功启动的。也就是说,本节的重点在于说明Libevent调度机制在Tor系统之中的应用。

  上节当中也简要介绍了Libevent的三种应用方式:信号处理;定时处理;网络套接字处理。这三种处理内容对于Libevent来说均是事件,只是事件的属性与回调函数不同而已。Libevent根据自身的调度机制,优先级队列等,来进行事件的调度。事件大多在被创建之时就被加入到Libevent事件集之中,Libevent一旦发现事件被激活,就会执行事件相应的回调函数。而值得说明的是,激活事件的方式根据事件类别的不同而有所区别:

  1)signal - 信号处理事件:挂起的信号处理事件在进程接收到相应信号时被激活,信号的发送者可以是用户,也可以是另外一个进程等;

  2)time - 定时处理事件:挂起的定时处理事件在定时器到时时被激活,定时器的时间设定会在定时处理事件生成时就指定;

  3)socket - 网络套接字处理事件:挂起的网络套接字处理事件主要分两种,分别为读事件和写事件;读事件在相应套接字有数据可读时被激活;写事件比较特殊,它总是处于激活状态的,也就是说,只要套接字是正常可写的,写事件就会不断被激活;因为写事件的情况特殊,所以Tor系统对其的处理是动态地增删,而不是像读事件一样一直放置于事件池内部。利用Libevent的事件池输出调试函数event_base_dump_events可以看到事件池内事件的变动和简单状态,是调试Tor系统的重要手段。(我们讨论非阻塞的读写事件,若读写事件是阻塞的,则Tor系统的单线程执行很容易就会被阻塞,系统就无法正常运行)


0. 系统中的普通事件

  此处暂且介绍客户端系统的事件集,服务器端的事件集可以由此作为依据进行猜测。


  0.1. 监听事件(socket)  -- 系统初始化阶段 tor_init()

  客户端系统中的监听事件主要分为两种:socket监听;control监听。

  以上两种监听事件的目的是不同的:socket监听是监听Tor提供给用户程序的应用端口,接收的是应用请求;control监听是监听Tor提供给用户的控制端口,通过向控制端口传送相应的命令,可以有效控制Tor系统的执行,该部分的控制规则可以在文件control-spec.txt中找到详细的说明。

  监听事件的添加是在监听连接创建之后马上执行的,主要处理代码在初始化阶段,入口函数为options_act_reversible。其后主要是通过connection_listener_new函数中的处理来完成事件的新建和添加。connection_start_reading函数完成了事件向事件集中添加的具体操作。在完成了添加之后,一旦进入到主循环的Libevent循环,就将控制权交给Libevent,通过Libevent的机制进行调度,执行提供的回调函数。

  此处值得先一提的是,对于所有连接的读事件和写事件,执行的回调函数分别相同:conn_read_callback,conn_write_callback。在后期的分析之中,会着重介绍这两个函数对网络套接字事件所执行的具体处理。


  0.2. 信号事件(signal) -- 系统无限循环开启前 do_main_loop()

  与大多数的Linux软件编程类似,Tor系统进程需要准确地控制进程以接收信号完成相应操作。信号的处理是件相对繁琐的事情,我们此处略去信号的具体处理细节,而把注意力集中在Tor系统是如何利用Libevent来进行信号控制。其实其过程也相对简单,只利用了一个函数:

/** Set up the signal handlers for either parent or child. */
void
handle_signals(int is_parent)
{
#ifndef _WIN32 /* do signal stuff only on Unix */
  int i;

  // 定义需要处理的信号
  static const int signals[] = {
    SIGINT,  /* do a controlled slow shutdown */
    SIGTERM, /* to terminate now */
    SIGPIPE, /* otherwise SIGPIPE kills us */
    SIGUSR1, /* dump stats */
    SIGUSR2, /* go to loglevel debug */
    SIGHUP,  /* to reload config, retry conns, etc */
#ifdef SIGXFSZ
    SIGXFSZ, /* handle file-too-big resource exhaustion */
#endif
    SIGCHLD, /* handle dns/cpu workers that exit */
    -1 };

  //信号事件集
  static struct event *signal_events[16]; /* bigger than it has to be. */

  if (is_parent) { // 父进程信号处理交由Libevent进行
    for (i = 0; signals[i] >= 0; ++i) {
      signal_events[i] = tor_evsignal_new(
                       tor_libevent_get_base(), signals[i], signal_callback,
                       (void*)(uintptr_t)signals[i]);
      if (event_add(signal_events[i], NULL))
        log_warn(LD_BUG, "Error from libevent when adding event for signal %d",
                 signals[i]);
    }
  } else { // 子进程信号处理由系统默认信号处理机制sigaction完成
    struct sigaction action;
    action.sa_flags = 0;
    sigemptyset(&action.sa_mask);
    action.sa_handler = SIG_IGN;
    sigaction(SIGINT,  &action, NULL);
    sigaction(SIGTERM, &action, NULL);
    sigaction(SIGPIPE, &action, NULL);
    sigaction(SIGUSR1, &action, NULL);
    sigaction(SIGUSR2, &action, NULL);
    sigaction(SIGHUP,  &action, NULL);
#ifdef SIGXFSZ
    sigaction(SIGXFSZ, &action, NULL);
#endif
  }
#else /* MS windows */
  (void)is_parent;
#endif /* signal stuff */
}
  总的说来,上述函数执行完毕之后,系统会在Libevent事件列表中挂入信号处理事件。信号的处理从此就交由Libevent自动执行。具体是如何处理的,则需要进一步研究回调函数signal_callback。而这并不是本文的重点,所以此处略去。


  0.3.定时事件(time) -- 系统无限循环开启前 do_main_loop()

  Tor系统为了维护系统重要模块和组件,需要进行每秒一次的系统维护工作。同时,系统中的流量控制模块也需要进行定期的流量审查和令牌填充等操作。所以,定时事件是Tor系统必须要处理的重要事件。定时事件根据上面的描述,有主要分为两个:每秒一次的系统定时维护事件;定期的流量控制事件。

  /* set up once-a-second callback. */
  if (! second_timer) { //每秒执行的系统维护定时器事件
    struct timeval one_second;
    one_second.tv_sec = 1;
    one_second.tv_usec = 0;

    second_timer = periodic_timer_new(tor_libevent_get_base(),
                                      &one_s
Tor源码分析八 -- 客户端执行流程(second_elapsed_callback函数) 在之前的客户端源码分析中,我们讲述了整个客户端的事件集和相关调度规则。每一类事件的激活都有相应的条件,要么是socket可读写,要么是收到信号,要么是定时事件到达,还有手动的事件激活。总而言之,系统中添加的所有事件经过Libevent的调度,使得整个系统有条不紊的运行起来。同时,每个事件均有其对应的事件处理函数,在系统运行起来之后,一旦事件被激活,就会调用相应的回调函数进行处理。   本文我们着 阅读详情

相关推荐

Tor源码分析九 -- 客户端执行流程(网络信息的下载)

源码分析到这里,大家应该已经大致了解到Tor系统的前期启动没有做任何的下载操作。前期启动的最关键环节,就是正常开启Libevent的调度机制,从而有条不紊地进行系统内所有子模块的维护等。我们需要再次强调的是,系统的主进程内,是没有做任何直接的获取网络状态,获取路由描述符,获取额外路由信息的操作。系统将这些操作视为需要实时维护的工作,因为所有这些网络信息都有其时限。所以,对这些网络信息的获取,全部置

WInScar的专栏 4410

Tor源码分析 -- 附录 Tor Manual

TOR(1) Manual Page Analysis NAME tor - The second-generation onion router SYNOPSIS tor [OPTION value]… DESCRIPTION tor is a connection-oriented anonymizing communication service. Use

WInScar的专栏 5570

Tor源码分析二 -- 目录结构

Tor由于经过了长年的开发,版本到现在已经有很多。笔者选用的是tor-0.2.3.25版本。关于版本变迁和更新说明,请大家自行查看:   https://gitweb.torproject.org/tor.git (需翻墙) 1. 源码目录关系图   Tor的源码目录中包括doc, contrib, src等一些列很莫名的文件。其实,在这些所有的文件中,除了src文件夹,其他都可

WInScar的专栏 6306

Tor源码分析十一 -- 客户端执行流程(网络信息的下载续)

通过上一节中我们对连接和链路的重新描述,我们可以继续进行源码的分析了。在本节中,我们会开始着重讲述链路的建立,以及链路所基于的OR连接的建立,同时还有部分Libevent调度的再度分析。大家会明白,进行到此处之时,我们已经开始接触Tor系统最底层,最深藏着的连接机制以及调度机制。这个部分,是整个系统的精髓。后期几乎所有的应用请求连接处理等,都是重复地使用该部分的代码。 1. 链路建立以及

WInScar的专栏 3258

Tor源码分析十 -- 连接和链路

源码分析到这个部分,为了让大家明白源码中的编码逻辑,不得不开始从头梳理程序内部的复杂连接和链接组织形式。否则大家后期会更加一头雾水。笔者开始分析源码之时,没有这些宏观的概念,只能死嚼代码,硬猜硬想,再加以检查代码进行验证,才得以明白程序的主要框架逻辑。如果再以猜测验证的模式向大家讲述源码,必定会越来越混乱。所以,在本节之中,我们会将系统中所有的连接类型,链路类型和他们之间的关系和代码之中的关联方式

WInScar的专栏 6405

Tor源码文件分析 -- Log

日志模块是Tor系统中一个非常重要的部件。它将Tor系统中的所有事件,分成不同的严重级别,分成不同的系统域,进行统一的日志处理。同时它还维护着一个日志记录链表。日志记录链表内存储的是所有日志需要输出的目标日志文件或目标日志输出位置。下文中我们会详细地对日志模块进行分析,并简要说明源文件中的各函数的简单作用。 1. 严重等级和域   日志模块内定义了5个严重等级,其具体的设定如下:/**

WInScar的专栏 3709

Tor源码分析七 -- 握手协议

本节主要讲述Tor系统中所用到的握手协议。握手协议分三层:TCP握手;TLS握手;Tor握手。其中Tor握手又分为三个层次:OR握手;链路建立;流建立。   TCP的三次握手我想应该学计算机方向的朋友无人不知了,所以此处就略去。而TLS是SSL的升级版本,其握手过程与SSLv3几乎一致。同时由于TLS根据客户端的不同握手选择,会有些许握手过程中的差别,我们希望大家能够找到TLS相关的书籍翻阅。此

WInScar的专栏 9308

Tor源码文件分析 -- Connection_OR

作为连接类型中最重要的一种连接,OR连接对OP与OR之间,OR与OR之间的通信负全责。也就是说,OR连接的存在,是解决底层两机之间通信的必要条件。所以,有必要对OR连接的源码文件进行深入分析,并对OR连接先做简要介绍。后期,在介绍Tor系统的全部连接之时,会更加详细地介绍各种连接及他们的作用。   OR连接,即Onion Router连接,是用以连接Tor系统内两结点的连接。该连接的主要功能包括

WInScar的专栏 2624

Tor源码分析四 -- 客户端执行流程(初入主循环)

在上个小节中,已经基本分析了Tor系统的初始化过程。该过程中,最重要的部分,就是对默认配置文件、输入配置文件以及命令行参数进行综合整理,定出最后的配置方案。而后通过配置方案,启动系统的基础部分。这里值得说明的是,Tor系统的所有配置选项,均可以在Tor Manual中找到。并且,根据Tor系统配置成不同的身份,使用的配置选项也会有细微差别。默认的配置固化在代码内部,有兴趣的朋友可以就初始化部分往下

WInScar的专栏 3758

Tor源码文件分析 -- Connetion_Edge

所谓的Edge连接主要是形容在链路两端所使用的连接,包括AP连接与EXIT连接两种。Edge连接的存在,主要是为了个应用程序连接提供服务,所以才将两种Edge连接命名为Application Proxy应用代理连接和EXIT出口连接。这两种连接主要出现于链路两端,即链路第一跳与链路最后一跳,分别用于接受应用请求和处理应用请求的发出。因为Edge连接在Tor系统中也具有重要的作用,所以本篇就简单分析

WInScar的专栏 2427

【libevent】le_proxy :Simple and Fast TCP Proxy

官方sample 原文 2016年的 异步api ,处理网络事件 This is a simple and fast proxy written in C. This makes use of libevent library. This library basically provides asynchronous API’s to deal with networking events. 非阻塞的api ,高效 As it makes use of non blocking API c..

突围 684

网络反监控软件 Tor源码附带openssl开发包

网络反监控软件 Tor源码附带openssl开发包

别再手动对照了!用Python+ArcGIS Pro一键搞定三调数据转土地三大类

本文介绍如何利用Python和ArcGIS Pro实现三调数据向土地三大类的自动化转换,大幅提升国土空间规划和土地变更调查的工作效率。通过封装分类规则为Python函数并集成到ArcGIS Pro脚本工具中,解决了传统手动操作耗时且易错的问题,适用于大规模数据处理场景。

weixin_29081101的博客 304

从零搭建智能视觉小车:OpenART图像处理+增强现实避坑指南

本文详细指导如何从零搭建智能视觉小车,重点介绍OpenART图像处理与增强现实技术在AprilTag识别中的应用。涵盖硬件选型、环境配置、算法优化及实战调试全流程,特别分享智能汽车竞赛中的避坑技巧和优化方案,帮助开发者构建稳定高效的视觉系统。

yhn456789的博客 1056

Oracle Scheduler任务故障诊断 实战指南

当基础环境无异常时,需聚焦任务本身的配置与状态。定义(JOB)→ 调度(SCHEDULE)→ 执行(SLAVE进程)→ 日志(LOG),每个环节都可能存在卡点。Oracle Scheduler任务的“隐性故障”看似棘手,实则是环境配置、资源竞争、时间逻辑等问题的集中体现。通过本文的诊断工具和排查思路,你可以构建从“基础环境→任务配置→执行链路→日志追踪”的全维度分析体系,让每一个“消失”的任务都无所遁形。

Nuzbb的博客 1074

免费搞定DWG转DXF:ODA File Converter保姆级配置指南(附常见报错解决)

本文详细介绍了如何使用ODA File Converter免费工具实现DWG到DXF的格式转换,包括环境配置、命令行参数解析、编程集成方案及常见问题解决。特别针对网络访问异常、参数配置等实际痛点提供应对策略,帮助用户高效完成工程设计文件的格式转换。

weixin_29291185的博客 6037

SMETANA 安装使用教程

关于SMETANA的安装和简单使用信息

qq_44940977的博客 1170

人群仿真软件:AnyLogic_(12).AnyLogic高级功能应用

在AnyLogic中,自定义行人行为是通过编写Java代码来实现的。行人行为的自定义可以包括行走路径的选择、速度变化、交互行为等。这使得仿真模型更加灵活和真实。

kkchenjj的博客 1060

第10篇:Agent + 爬虫 = 全自动数据采集专家

在企业级数据采集场景中,传统爬虫的痛点已经到了无法忽视的地步:而Agent + 爬虫的组合,就是这些痛点的终极解决方案。它的核心逻辑是:把爬虫从「人工写死的固定执行脚本」,升级为「能自主分析、自主决策、自主适配、自主修复的智能采集机器人」。我们在生产环境中做过对比测试:传统爬虫开发10个网站的采集脚本需要3人天,而Agent采集机器人只需要3分钟,页面改版后的修复成本从1人天降到了0,采集任务的成功率从62%提升到了95%以上。终端执行以下命令,安装基础依赖,与前9篇环境完全兼容: 二、核心能力拆解:Age

专注于Python爬虫开发,分享爬虫技巧、项目实战与反爬经验,使用Scrapy、BeautifulSoup等工具,解决数据抓取难题。 1576

华为ONU远程登录管理配置

华为P602E、EG8040CONU、EG8240H5、W626E等ONU、ONT默认无法配置管理IP,无法远程telnet登录管理。校园网项目中因故障诊断需要远程登录ONU可以通过OLT的远程WEB代理功能链接登录,具体配置如下:

symstandsun的博客 6110

怀旧版电脑GBC模拟器

再现原版GBC掌机的界面,电脑运行连游戏界面都一样大小,很怀旧,很真实,(英文版)强烈推荐,很小的文件,很难才找到的。

jdk-8u144-linux-x64.tar.gz.

该资源为搭建Linux系统Java环境用,资源的后缀为tar.gz格式的压缩包

复分析 阿尔福斯(Ahlfors) 第三版答案 英文

答案分为十章,有部分习题没有答案,全英文复分析阿尔福斯(Ahlfors) 第三版答案

Probability and Statistics - 4th edition

Probability and Statistics - 4th edition

上一篇: Tor源码文件分析 -- Circuits全局变量
下一篇: Tor源码分析六 -- 总体框架图
WInScar
博客等级 码龄17年 134粉丝 56原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值