监听网络环境变化

0. 概述

监听网络环境变化情况一般来说可以通过以下方式进行:

  • 方式1:BIRD协议(BFD机制:状态更新间隔调整 + 状态机转换(tla+))

  • 方式2:libnl

  • 方式3:netlink参考链接

阅读全文 »

bird源码剖析(1)

  1. 使用bird主要是通过读取bird.conf文件进行协议相关配置;
  2. 通过configure.ac文件,设置CONFIG_FILE变量为配置文件;
  3. autoconfconfigure.ac中的宏展开,生成configure脚本;
  4. 【中间过程】
  5. conf/conf.c文件中通过config_parse函数进行语法解析;
  6. sysdep/unix/main.c文件分析:

    • 首先调用parse_args函数对配置文件解析(解析指定路径,无指定则选择默认配置);
    • 初始化操作,包括:log_switch(), random_init(), net_init(), resource_init(), timer_init(), olock_init(), io_init(), rt_init(),if_init()
    • 设置log文件、随机初始化、网络、资源(pool)、等相关初始化配置;
  7. 核心文件夹

    • filter:过滤器相关;
    • lib:底层实现相关;
      • lib/birdlib.h:包含编译bird-gdb.py;
    • nest:BIRD核心相关;
    • proto:协议相关;
    • sysdep:glibc系统相关;
    • test:暂未了解【猜测是用来debug的,里面包含了gdb等】;
  8. 其他知识点

    • .Y(Yet Another Compiler Compiler)是Unix/Linux上一个用来生成编译器的编译器。yacc生成的编译器主要是用C语言写成的语法解析器(Parser),需要与词法解析器Lex一起使用,再把两部份产生出来的C程序一并编译。

    • .m4文件:M4实际上是一种编程语言,后缀是.m4,说明这个文件是使用.m4写的,说的专业一点,这实际上就是一个通用宏处理器。 它经常被用来生成Makefile的脚本语言来使用。

    • toml文件:配置文件,一种非常基础的文件格式。

    • distribution(often abbreviated as distro);

    • misc文件夹:contains miscellaneous file types that do not fit within other categories.

    • sysdep文件夹:(在Linux源码中是/arch,在glibc中是/sysdep

    • glibc是GNU发布的libc库,即c运行库。glibc是linux系统中最底层的api,几乎其它任何运行库都会依赖于glibc。glibc除了封装linux操作系统所提供的系统服务外,它本身也提供了许多其他一些必要功能服务的是心啊。

    • stdarg.h: a header in the C standard library of the C programming language that allows functions to accept an indefinite number of arguments.

    • ···用法:可变参数函数是可以采用可变数量的参数并用省略号代替最后一个参数声明的函数。例如:static void bt_log_overall_result(int result, const char *fmt, ...)

      • 意义:max函数之所以看起来简单是因为其可变参数表的长度是已知的(通过num参数传入),且可变参数表中参数的类型也是已知的(都为int型)。然而,printf函数则没有这么幸运。首先,printf函数可变参数的个数不能轻易的得到,而可变参数的类型也不是固定的,需由格式字符串进行识别(由%f、%d、%s等确定),因此则涉及到可变参数表的更复杂应用。
    • asciz:编译相关;

    • ISP:互联网服务提供商,如电信、网通等;

    • Linux Kernel Netlink Route Syncer

      • netlink套接字是用以实现用户进程与内核进程通信的一种特殊的进程间通信(IPC),也是网络应用程序与内核通信的最常用的接口;
      • netlink是一种特殊的socket,它是Linux所特有的,类似于BSD中的AF_ROUTE,但远比其功能强大,目前在Linux内核中使用netlink进行应用与内核通信的应用很多;
    • GNU的autoconf可以用来生成makefile。一个GNU程序的编写,需要autoscan, aclocal, autoconf和automake这四个工具;

    • GNU软件安装的三部曲是:./configure, make, make install

      • ./configure根据autoconf, aclocal等工具生成一个makefile文件。检测你的安装平台的目标特征的。比如它会检测你是不是有CC或GCC,并不是需要CC或GCC,它是个shell脚本。
      • make从Makefile中读取指令,然后编译;
      • make install是用来安装的,它也从Makefile中读取指令,安装到指定的位置。
    • 守护进程(Daemon)是运行在后台的一种特殊进程。它独立于控制终端并且周期性地执行某种函数或等待某些发生的事件。守护进程最重要的特性是后台运行。其次,守护进程必须与其运行前的环境隔离开来(这些环境包括未关闭的文件描述符、控制终端、会话和进程组、工作目录以及文件的创建掩模等)。这些环境通常是守护进程从执行它地方父进程中集成下来的。最后,守护进程的启动方式有其特殊之处。它可以在linux系统启动时从启动脚本/etc/rc.d中启动,可以由作业规划进程crond启动,还可以由用户终端执行。

    • 为避免挂起控制终端将Daemon放入后台执行,相应的解决方法是在进程中调用fork使父进程终止,让Daemon在子进程中后台执行。

    • C使用:

      • read()用于读取打开文件的内容,返回实际读取的字节数;

      • getgrnam()用于逐一搜索参数指定的组名称,找到时便将改组的数据以group结构返回;

      • getgrgid()用于根据参数gid指定的组识别码逐一搜索组文件,找到时便将该组的数据以group结构返回;

      • getopt()函数用于解析命令行选项,可用来捕获选项(如-c, -v等),在sysdep/unix/main.coptstring = bc:dD:ps:P:u:g:flRh

        a:b:cd::e,这就是一个选项字符串。对应到命令行就是-a ,-b ,-c ,-d, -e 。冒号又是什么呢? 冒号表示参数,一个冒号就表示这个选项后面必须带有参数(没有带参数会报错哦),但是这个参数可以和选项连在一起写,也可以用空格隔开,比如-a123 和-a 123(中间有空格) 都表示123是-a的参数;两个冒号的就表示这个选项的参数是可选的,即可以有参数,也可以没有参数,但要注意有参数时,参数与选项之间不能有空格(有空格会报错的哦),这一点和一个冒号时是有区别的。

      • setsid()的作用:(1)新建一个对话;(2)新建进程组;

      • strrchr(str, c):查找str中最后一次出现字符的位置,并返回从字符串中的这个位置起,直到字符串结束的所有字符;

      • 每个打开的文件描述符(fd标志)在进程表中都有自己的文件表项。dup()函数被调用时,内核在进程中创建一个新的文件描述符,此描述符是当前可用文件描述符的最小数值,这个文件描述符指向oldfd所拥有的文件表项。

      • pthread_self():获得自身线程标识。

      • pthread_create():创建线程调用。

      • va_start(va_list ap, last_arg):将初始化ap变量,与va_argva_end宏是一起使用的,last_arg是最后一个传递给函数的已知的固定参数,即省略号之前的参数。

      • ftrubcate(int fd, off_t length):改变文件大小,即会将参数fd指定的文件大小改为参数length指定的大小。

      • 在头文件中使用#ifdef#ifndef是非常重要的,可以防止双重定义的错误。具体而言,其作用是当满足某条件时对一组语句进行编译,而当条件不满足时则编译另一组语句。

      • isatty():检查给定的设备类型函数名;

      • socket(AF_UNIX, SOCK_STREAM, 0);用于实现同一主机上的进程间通信;

    • Makefile语法:

      • makefile.PHONY的作用是声明伪目标。声明为为目标后,在执行对应的命令时,make就不会去检查是或否存在对应的文件,而是每次都会运行标签对应的命令;
    • patsubst函数用于将文件模式进行替换,其格式为$(patsubst原模式,目标模式,文件列表)

      • makefile中加入shell指令,以实现自动查找头文件及动态库路径。
    • BIRD使用命令:

      • 启动:systemctl start bird
      • 停止:systemctl stop bird
      • 重启:systemctl restart bird
      • 打开/关闭开机自启动:sudo systemctl enable/disable bird
      • 客户端程序birdc,它可以连接到BIRD服务并且控制它的行为。默认情况下birdc会连接系统服务的BIRD,如果启动BIRD时采用了-s参数,那么birdc也要指定同样的socket路径。

协议基础概念

  1. socket

    • 定义:网络上的两个程序通过一个双向的通信连接实现数据的交换,这个连接的一端称为一个socket。通常也称作”套接字“,用于描述IP地址和端口,是一个通信链的句柄,可以用来实现不同虚拟机或不同计算机之间的通信。
    • 本质:编程接口API,对TCP/IP的封装。提供可供程序员做网络开发所用的接口;
    • 举例:socket像一个多孔插座。一台主机犹如布满各种插座的房间,每个插座有一个编号,有的插座提供220V交流电,有的提供110V交流电,有的则提供有线电视节目。客户软件将插头插到不同编号的插座,就可以得到不同的服务。
  2. TCP/IP和HTTP协议的关系

    • TCP/IP协议:传输层协议,主要解决数据如何在网络中传输;
    • HTTP协议:应用层协议,主要解决如何包装数据;
    • 举例1:我们在传输数据时,可以只使用传输层TCP/IP协议,但是那样的话,如果没有应用层,便无法识别数据内容。如果想要使传输的数据有意义,则必须使用到应用层协议。
    • 举例2:WEB使用HTTP协议作应用层协议,以封装HTTP文本信息,然后使用TCP/IP做传输层协议将它发到网络上。
  3. hook

    • 定义:指程序A在程序B里埋入的一段代码。当程序B运行到某种特定状态,或者某个特定条件成立,就会调用A埋入的那段代码。
    • 意义:一般来说程序B希望把一些定制能力开放给用户或者第三方的开发者。
    • 举例:例如github上有很多git repo,每个repo都有很多人提交代码,而且很多时候这些人之间互相不认识。假如我希望我的某个repo,只要有人提交了代码就自动运行一个测试程序,然后把测试结果发给我,这件事github自己要做就很不现实,因为它不知道我想如何测试,也不知道我想根据测试结果做什么,这时候 GitHub 的解决方案就是设计一个 hook API,允许我写一个“钩子函数(hook)”,并在我的 repo 的 “收到新 commit” 这个 “事件(event)” 上 “注册(register)” 这个钩子函数,以后 GitHub 只要收到该 repo 的 commit 就会触发这个钩子函数,执行我写的代码,我想做什么就我自己控制了。GitHub 事实上确实有这个功能(实际上是 git 底层就支持的),提供了 commit 前后的钩子接口,commit 前的钩子里你甚至可以根据运行情况决定是不是直接拒绝这个 commit。还有一种情况,钩子的接口不是程序 B 自己提供的,而是操作系统提供的机制,甚至是黑客强行在程序 B 中注入的,这就涉及到一些特定技术了,在特定环境下也是能做到的。不过,好孩子不干这个 ^_^
  4. MPLS

    • 本质:一种隧道技术,在一定程度山更可以保证信息传输的安全性;
    • 体系结构
      • 控制平面:无连接的,主要功能是负责标签的分配、LFIB的建立、LSP的建立、拆除等;
      • 转发/数据平面:面向连接的,对IP包进行标签的添加和删除,同时依据标签转发表对收到的分组进行转发;
  5. 平滑重启(graceful restart):(参考

    • 定义:在主备切换或协议重启时保证转发业务不中断的机制。

    • 高可靠性(HA, High Availability)技术:HA是一整套综合技术,主要包括冗余容错、链路保证、节点故障修复及流量工程。其中,GR是一种冗余容错技术,目前已经被广泛的使用在主备切换和系统升级方面,以保证关键业务的不间断转发。

    • 前提

      • 仅适用于带双主控、线卡具有独立处理器的硬件平台;
      • GR用于软件或硬件错误导致Active RP重起或Active RP失效;或者管理员的主备切换命令。
    • 传统技术和GR技术的比较

      • 传统主备切换时造成的网络问题

        OSPF GR

      • 采用GR技术解决了主备切换时造成的网络问题

        OSPF GR2

      • 注意:如果在R1在GR的过程中,网络拓扑发生了变化,那么可能导致短暂的路由环路或路由黑洞。对于这个问题的处理方法,目前不同厂商的实现略有不同。与业务中断的危害相比较,是否可以容忍可能出现的短暂的路由环路和路由黑洞,对这个问题的不同观点决定了在具体实现上的不同。

  6. 网络流量工程

    • 定义:根据各种数据业务流量的特性选取传输路径的处理过程。用于平衡网络中不同交换机、路由器以及链路之间的负载;

WebRTC

WebRTC(Web Real-Time Communication)是一个可以用在视频聊天、音频聊天或P2P文件分享Web App中的API。

WebRTC是一个可以在Web程序中实现音频,视频和数据的实时通信的开源项目。在实时通信中,音视频的采集和处理是一个很复杂的过程。比如音视频流的编解码、降噪和回声消除等,但是在WebRTC中,这一切都交由浏览器的底层封装来完成。我们可以直接拿到优化后的媒体流,然后在其输出到本地屏幕和扬声器,或者转发给其对等端。长话短说,就是一个支持网页浏览器进行实时语音对话、视频对话、数据传输的API

  1. WebRTC已经实现了对于实时通信,免插件音视频数据传输的标准制定,需求是:
    • 许多网络服务已经使用了RTC,但是需要下载,本地应用或者是插件;
    • 下载安装升级插件是复杂的,可能出错的;
    • 插件可能很难部署、调试、故障排除等;
    • 插件可能需要技术授权,复杂集成和昂贵的技术;
  2. 因此WebRTC项目的指导原则是:API应该是开源的,免费的,标准化的,浏览器内置的,比现有技术更高效的;
  3. WebRTC有3个模块:
    • Voice Engine(音频引擎)
      • voice engine包含iSAC/iLBC Codec(音频编解码器,前者是针对宽带和超宽带,后者是针对窄带);
      • netEQ for voice(处理网络抖动和语音包丢失);
      • Echo Canceler(回声消除器)/noise reduction(噪声抑制);
    • NetEQ Engine(视频引擎)
      • VP8 Codec(视频图像编解码器);
      • Video jitter buffer(视频抖动缓冲器、处理视频抖动和视频信息包丢失);
      • Image enhancements(图像质量增强);
    • Transport(数据传输)
      • SRTP(安全的实时传输协议,用以音视频流传输);
      • Multiplexing(多路复用);
      • P2P, STUN+TURN+ICE(用于NAT网络和防火墙穿越的);
      • 除此之外,安全传输可能还会用到DTLS(数据报安全传输),用于加密传输和密钥协商;
      • 整个WebRTC通信是基于UDP的;
  4. 核心组件
    • 音视频引擎:OPUS、VP8/VP9、H264
    • 传输层协议:底层传输协议为UDP
    • 媒体协议:SRTP/SCTP
    • 数据协议:DTLS/SCTP
    • P2P内网穿透:STUN/TURN/ICE/Trickle ICE;
    • 信令与SDP协商:HTTP/WebSocket/SIP/Offer Answer模型;
  5. NAT和NAT穿透
    • NAT即网络地址转换,就是替换IP报文头部的地址信息。NAT通常部署在一个组织的网络出口位置,通过将内部网络IP转换为出口的IP地址提供公网可达以及和上层协议的连接能力;
    • NAT的分类:
      • 静态NAT:将单个私有IP地址与单个公共地址映射,即将私有IP地址转换为公共IP地址;
      • 动态NAT:多个专用IP地址映射到公用IP地址池。当我们知道固定用户想要在给定的时间点访问Internet的数量时,将使用它;
      • PAT(NAT重载):使用NAT重载可以将需要本地(专用)IP地址转换为单个公用IP地址。端口号用于区分流量,即哪个流量属于哪个IP地址。这是最常用的方法,因为它具有成本效益,因为仅使用一个真实的全局(公共)IP地址就可以将数千个用户连接到Internet.
  6. STUN协议(Simple traversal of UDP over NAT protocol)

ifconfig解析

0. 具体示例说明

cKDTree

  • KDTree:是查找大数据的最近邻居的快速方法;
  • 作用:快速将GPS点位根据最邻近距离投影到最近路网(两千万点位在2min内完成匹配);
阅读全文 »

DataLoader深入剖析

DataLoader本质是一个可迭代对象:

  • 使用iter()访问,不能使用next()访问

  • 使用iter(dataloader)返回的是一个迭代器,然后可以使用next()访问

  • 也可以使用for inputs, labels in dataloaders进行可迭代对象的访问
  • 一般我们实现一个dataset对象,传入到dataloader中,然后内部使用yeild返回每一个batch的数据;

蚁群算法

蚁群算法具有分布计算、信息正反馈、启发式搜索特征,本质是进化算法中的一种启发式全局优化算法。蚁群算法应用广泛,如旅行商问题、指派问题、job-shop调度问题、车辆路径问题、图着色问题、网络路由问题等。和传统的路由算法相较,该算法在网络路由中具有信息分布式性、动态性、随机性和异步性等特点,而这些特点正好能满足网络路由的需要。

阅读全文 »

路由算法

路由算法是路由协议必须高效地提供其功能,尽量减少软件和应用的开销。路由器使用路由算法来找到到达目的地的最佳路由。

阅读全文 »