自定义博客皮肤VIP专享

*博客头图:

格式为PNG、JPG,宽度*高度大于1920*100像素,不超过2MB,主视觉建议放在右侧,请参照线上博客头图

请上传大于1920*100像素的图片!

博客底图:

图片格式为PNG、JPG,不超过1MB,可上下左右平铺至整个背景

栏目图:

图片格式为PNG、JPG,图片宽度*高度为300*38像素,不超过0.5MB

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

-+
  • 博客(60)
  • 收藏
  • 关注

原创 How To Create a kernel thread

kernel_thread()-->do_fork and modify the value of eip ebx edx in the kernel mode stack.

2016-03-05 00:07:13 779

原创 如何异步取消一个线程

#include<stdio.h>#include<stdlib.h>#include<pthread.h>pthread_t id;void *thread_func(void *args){ printf("child-- start\n"); pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS,NULL); wh

2016-02-29 09:41:12 1025

转载 澄清P问题、NP问题、NPC问题的概念(转)

你会经常看到网上出现“这怎么做,这不是NP问题吗”、“这个只有搜了,这已经被证明是NP问题了”之类的话。你要知道,大多数人此时所说的NP问题其实都是指的NPC问题。他们没有搞清楚NP问题和NPC问题的概念。NP问题并不是那种“只有搜才行”的问题,NPC问题才是。好,行了,基本上这个误解已经被澄清了。下面的内容都是在讲什么是P问题,什么是NP问题,什么是NPC问题,你如果不是很感兴趣就可以不看了。接下

2015-12-29 17:26:29 496

原创 《深入理解Linux网络技术内幕》阅读笔记(三十三)

路由代码只使用每个设备上的转发状态:改变全局配置只是一次性将该改变应用到所有设备的一种简便方法。 只有主机才能接收ICMP重定向消息,而路由器不能够接收。如果全局转发状态变为开启,意味着系统现在被视为一台路由器,因而必须禁止可敬的ICMP重定向的默认配置。 n%fz_divisor的结果与n&fz_hashmask的结果相同(例如100%16 == 100&15),而二进制按位与操作所花费的

2015-10-16 15:25:47 732

原创 《深入理解Linux网络技术内幕》阅读笔记(三十二)

LPM算法从表示最长网络掩码的区域开始循环遍历路由。这是因为网络掩码越长,就意味着路由越具体,也就意味着封包可能得到更接近最终的目的地。 接收封包: 1.如果分包被转发,函数将dst->input初始化为ip_forward,将dst->output初始化为ip_output。 2.如果封包被送往本地,函数将dst->input初始化为ip_local_deliver。此时,不

2015-10-16 01:41:17 657

原创 《深入理解Linux网络技术内幕》阅读笔记(三十一)

为了能使各种操作快速查找到相关的信息,Linux中采用了几种不同的hash表,这些表都指向用于描述路由的相同的数据结构: 1.一组基于网络掩码长度来访问路由的hash表。 2.一组直接搜索fib_info结构的hash表。 3.一个以设备为索引,可以快速搜索配置路由的下一跳的hash表。 4.一个以设备和一条路由为索引,能够快速识别该路由下一跳所用网关的hash表。 在系统启动

2015-10-15 12:47:47 442

原创 《深入理解Linux网络技术内幕》阅读笔记(三十)

路由缓存用于减少路由表查找的时间。路由缓存的核心是与协议无关的目的缓存(Protocol Independent Destination Cache DST)。尽管采用策略路由可有效地创建多张路由表,但所有这些路由表都共享一个路由缓存。 rttable结构的第一个字段是一个联合,这使得rtable和dst_entry结构很容易共享一些数据,例如,指向下一个冲突的hash表项的指针。虽然指针

2015-10-15 09:50:49 2118

原创 《深入理解Linux网络技术内幕》阅读笔记(二十九)

在数据结构名称中的rt,fib与fn前缀分别表示路由,转发信息库和功能。 其中的节点定义:233 struct hlist_head {234 struct hlist_node *first;235 };236 237 struct hlist_node {238 struct hlist_node *next, **pprev;239 };IPV

2015-10-14 15:33:14 923

原创 《深入理解Linux网络技术内幕》阅读笔记(二十八)

假设需要执行以下两个策略: 1.从校园网1到校园网3的流量要通过路由器RT1,从校园网2到校园网3的流量要通过RT2。 2.从校园网1到因特网的流量要经过DG1(默认网关1),从校园网2到因特网的流量要通过DG2. 注:因为eth0和eth1各自只连了一个局域网,所以不需要指定下一跳地址,只需指定出口设备即可。 因为在每次路由查找时,都可能要检查多个条件,所以主机维护多张独立的路由表,根

2015-10-14 01:39:38 671

原创 《深入理解Linux网络技术内幕》阅读笔记(二十七)

简单地讲,路由器就是一台网络设备,它配备多个网络接口卡,能利用它的网络知识正确转发入口流量。 决定一个入口封包应该送给本地主机还是转发所需要的信息,以及在转发时正确转发封包所需要的信息,都存储在一个被称为转发信息库的数据库中(FIB),它通常被简称为路由表(路由表无非就是许多路由的一个集合)。 大多数主机通常只有一个网络接口,因而不能作为路由器。主机被配置为使用一个默认网关来访问外部地址。不

2015-10-13 17:04:58 2618

原创 《深入理解Linux网络技术内幕》阅读笔记(二十六)

neigh_sysctl_register函数中最复杂的部分是如何将四个参数gc_xxx参数从neigh_table结构中提取出来。实现过程巧妙地利用了neigh_table结构在内存中的安排:与垃圾回收相关的四个参数保存在neigh_table结构中,且位于neigh_parms结构之后,具体代码如下(在函数neigh_sysctl_register中):2056 if (dev)

2015-10-13 12:39:42 627

原创 《深入理解Linux网络技术内幕》阅读笔记(二十五)

有时候,发送方生成一个ARPOP_REQUEST是为了通知接收方一些信息,而不是请求信息。这种封包就称为无端ARP,它通常用下面列出的情况中: 1.L2地址发生变化。 2.重复地址探测。 3.虚拟IP(用于LVM服务)。 主机可以使用无端ARP来检测重复地址的存在,如果你发出一个目的地址是你自己地址的ARP请求,那么只有当存在一台与你有相同IP配置的主机时,才会收到应答。如果不存在重复地址,

2015-10-13 00:03:45 1533

原创 《深入理解Linux网络技术内幕》阅读笔记(二十四)

缓存: 1.邻居映射。由于任何数据都有可能被多次使用,那么缓存L3到L2的映射结果就是有意义的。不缓存错误结果(失败的地址解析),但是会将映射失败的neighbour结构设置为NUD_FAILED态,以便垃圾回收定时器能将其清除。 2.L2帧头。邻居基础结构会缓存L2帧头,这样可以缩短L3封包到L2帧的封装时间。否则,基础结构将要挨个初始化的L2帧头的每个字段。 当向一个目的地址发送第一个封包

2015-10-11 22:34:37 540

原创 《深入理解Linux网络技术内幕》阅读笔记(二十三)

最常用的邻居协议是地址解析协议(ARP)。IP6v6中的相应协议是Neighbor Discovery(ND)协议。 通常所提到的一些术语,比如L2地址,二层地址,硬件地址,MAC地址以及链路层地址都是一个概念。 a:主机A和主机B是邻居。因为它们同属于一个IP子网10.0.1.0/24,所以他们可以直接通信,彼此之间只有一个L3跃点。 b:主机A和主机B仍在同一个子网内,彼此之间可以

2015-10-10 21:40:59 524

原创 《深入理解Linux网络技术内幕》阅读笔记(二十二)

ICMP_ECHO消息类型用于测试远程主机是否可连接。当主机接收到ICMP_ECHO消息时,会以ICMP_ECHOREPLY消息回复。 上图中,当主机X传输IP封包到主机Y时,会发生下列事情: 1.主机X传送一个要给主机Y的封包到路由器RT1。 2.路由器RT1会查询它的路由表,发现下一个跳点是路由器RT2.路由器RT1也了解到因为路由器RT2和主机X位于相同子网上,所以主机X可以直接把封

2015-10-10 10:52:00 546

原创 《深入理解Linux网络技术内幕》阅读笔记(二十一)

如果inet_protos表不含该号码(封包的L4协议),而且也没有raw套接字对该封包感兴趣,则该封包会被丢弃,而一条ICMP无法抵达消息就会传回给发送者。 包报头的空间只能容纳一种L4协议。启用多个L4协议的实例之一就是使用IPsec。使用IPsec时,把封包交给真实的L4协议前,内核必须处理可能的AH,ESP,以及IPcomp报头。 raw套接字: 并非所有的L4协议都是

2015-10-09 20:01:09 105

原创 《深入理解Linux网络技术内幕》阅读笔记(二十)

上图流程中,为何要两次查询来了解正在请求者是否已有一个项目具有相同的目的地地址呢?因此类似项目可能在读取锁放开以及写入锁被取得之间的时间建立而加入该树中。 inet_peer结构:内核会为最近联系过的每台远程主机都维护一个此结构的实例。 IP封包ID选择: 1.不能分段的封包(DF=1):加入这种情况是为了处理window系统IP协议栈中的bug。ID会间接从sock数据结构中取出,每次包裹函

2015-10-09 14:57:09 690

原创 《深入理解Linux网络技术内幕》阅读笔记(十九)

如果封包没有被分段,offset=0且MF=0.相反的,如果我们手上有一个片段,则满足下列条件: 1.第一个片段有offset=0且MF=1. 2.界于第一个片段和最后的片段之间的所有片段,这两个字段都为非0. 3.最后一个片段有MF=0且offset为非0. 2.4版以前的内核有个名为ip_build_xmit_slow的函数,会以倒序方式为本地产生的封包建立并传输IP片段。这种做法有一些

2015-10-09 00:41:09 502

原创 《深入理解Linux网络技术内幕》阅读笔记(十八)

中央传递封包的函数是dst_output;本章所探讨的函数都是在此函数之前执行的,也就是替该函数把封包准备好。在此阶段,内核的任务包括: 1.查询下一个跳点。IP层必须知道外出设备以及用作下一个跳点的下一个路由器。 2.初始化IP报头。几个字段会在此阶段填入(诸如封包ID)。 3.处理选项。软件必须尊重需要把一个地址或时间戳加进报头里的那些选项。 4.分段。如果IP封包太大,无法在外出设备上

2015-10-08 16:53:49 482

原创 《深入理解Linux网络技术内幕》阅读笔记(十七)

IP校验和始终由内核在软件中计算和验证。 net_device->features字段会表明设备的能力。除了各种可以设定的标志外,有些标志可用于定义硬件校验和计算能力: NETIF_F_NO_CSUM:此设备很可靠,不需要使用任何L4校验和。 NETIF_F_IP_CSUM:此设备可以在硬件中计算L4校验和,但是只针对使用IPv4的TCP和UDP。 NETIF_F_HW_CSUM:此设备可以

2015-10-07 21:14:22 765

原创 《深入理解Linux网络技术内幕》阅读笔记(十六)

当copied被设定时,若封包需要分段,IP层就必须把该选项拷贝至每个片段。class会根据四条准则对此选项分类;这些字段可根据IP选项过滤封包,或者把不同的Qos参数施加至这些封包。 不含选项的IP报头的大小是20字节。当 IP选项的大小不是4字节的倍数时,传送者会以IPOPT_END选项为IP报头补白,使其对齐4字节边界。这是必要的,因为IP报头的Header Length字段是以4字节的倍数

2015-10-06 15:07:10 616

原创 《深入理解Linux网络技术内幕》阅读笔记(十五)

注意Netfilter钩子函数位置: 当开启STP时: 1.处理入口BPDU。 2.BPDU也可能是本地产生的。 3,入口网络数据不是转发到正确端口就是扩散到所有端口。 4.STP阻塞的端口不能用于接收和传输数据流量。 当STP关闭时: 1.入口BPDU会被认为是数据流量。 2.不会产生本地BPDU。 3.入口数据流量依然转发至正确端口或者扩散到所有端口。 4.所有网桥端

2015-10-05 22:25:48 575

原创 《深入理解Linux网络技术内幕》阅读笔记(十四)

这棵树的叶子就是主机。主机链接到所谓的接入网桥上:能把网络连通能力给予主机的网桥。接入网桥主要是用于在连到同一个网桥上的主机间转发流量。 分发层的网桥主要是用于在和一些接入网桥直接相连的主机间桥接流量。(例如,D1会负责搞定A1和A2) STP协议(生成树协议)目标: 已知一个图形以及一个根节点R,要定义出根是R的最佳生成树。但是,一个重要的区别是:该算法不是在单一主机上执行,然后再把结果

2015-10-04 15:01:02 932

原创 《深入理解Linux网络技术内幕》阅读笔记(十三)

中继器: 通常配有两个端口,只是简单地把一个端口所接收的东西复制到另一个端口,反之亦然。它复制的数据是按位复制的,并且对协议毫不关心。 网桥: 它了解链路层协议,因此可以按帧复制数据,而非按位复制。也就是说,网桥在每个端口上至少可以缓存一个帧。大多数LAN都用网桥——也常称为交换机(switch)。 路由器: 它是了解L3网络层协议,例如IP,的设备,它可以根据路由表转发入口封包。在使用路

2015-10-03 16:19:01 639

原创 《深入理解Linux网络技术内幕》阅读笔记(十二)

这些分层通常称为网络协议栈,因为通信会往下传播通过各个分层,直到实际上经过线路或无线频道传输,然后再返回来。报头也会以LIFO的方式添加和删除掉。 每一层都有很多种协议可以用。在最底层的接口交换数据,而所用的协议是预先决定的(协议的驱动程序被关联至该接口)。 接收帧的时候,会传送帧副本给网络嗅探器(如tcpdump)。 封包要往下传送到另一层以便于被传送至该路由器。但是,IP层必须在此

2015-10-03 13:59:35 1159

原创 《深入理解Linux网络技术内幕》阅读笔记(十一)

准备接收: 准备传输: 每个cpu都有一个output_queue队列,里面包含有数据要传输的设备。每个设备有自己的qdisc队列(若设备的队列规则存在时),里面包含该设备需要发送的sk_buff队列(若在dev_queue_xmit传输失败,则在软中断里面重新发送)。 dev->qdisc指向一个队列的实例,里面包含了队列本身以及操作队列的方法(enqueue、dequeue、req

2015-10-02 22:36:41 659

原创 《深入理解Linux网络技术内幕》阅读笔记(十)

中断处理函数会: 1.把帧拷贝到sk_buff数据结构。 2.对一些sk_buff参数做初始化,以便在稍后由上面的网络层使用。 3.更新其他一些该设备私用的参数。 4.为NET_RX_SOFTIRQ软IRQ调度以准备执行,借此通知内核新帧的事。 Netpoll:是一个通用的架构,可通过轮询网络适配卡(NIC)而传送及接收帧,把中断事件的需求删除掉。任何内核功能都可使用Netpoll,以受益

2015-10-02 17:35:32 2962

原创 《深入理解Linux网络技术内幕》阅读笔记(九)

当特定事件发生时,设备驱动程序会代表内核指示设备产生硬件中断。处理函数会把该帧排入队列某处,然后通知内核。该技术是低流量负载下的最佳选择。遗憾的是,在高流量负载下就无法良好运作:每接收一个帧就强制产生中断,很快就会让cpu为处理中断事件浪费所有的时间。 负责接收帧的代码分成两部分,首先,驱动程序把该帧拷贝到内核可访问的输入队列,然后,内核再予以处理。在高流量负载下,中断代码会持续抢占正在处理的代码

2015-10-02 01:38:33 578

原创 《深入理解Linux网络技术内幕》阅读笔记(八)

net_device数据结构插入在一个全局列表和两张hash表中。这些不同的结构可让内核按要求浏览或查询net_device数据库。 1.dev_base:内含所有net_device实例的全局列表能够让内核轻易浏览设备。 2.dev_name_head:以设备名称为索引的hash表。 3.dev_index_head:以设备ID dev->ifindex为索引的hash表。

2015-10-01 17:14:55 735

原创 《深入理解Linux网络技术内幕》阅读笔记(七)

parse_args是一个函数,用于解析输入字符串,而输入的字符串内是一些参数,其形式为变量名称=值,寻找特定关键字,并启用适当的处理函数。 内核组件可以利用__setup宏注册关键字和相关联的处理函数。 __setup宏把注册的信息存放在段.init.setup:238 /*239 * Only for really core code. See moduleparam.h for th

2015-10-01 01:29:01 685

原创 《深入理解Linux网络技术内幕》阅读笔记(六)

PCI的优点之一是,其支持寻找IRQ和每个设备所需的其他资源的探测方式相当优雅。模块可以在加载期间接收一些输入参数,以告知该如何配置其所负责的所有设备。但是,有些时候,特别是PCI这类总线,让驱动程序自行检查系统上的设备,然后为其负责的那些设备做配置会比较简单一点。必要时,可以退回到手动配置。 探测方式有两种: 静态: 给定一个设备PCI ID,内核就能根据id_table向量查询出正确的PC

2015-09-30 22:11:48 605

原创 《深入理解Linux网络技术内幕》阅读笔记(五)

通过中断,NIC能够告知其驱动程序几种不同的事情,包括: 1.接收一帧。 2.传输失败。 3.DMA传输已成功完成。给定一个帧传输,当帧上载至NIC的内存准备在此媒介上传输时,驱动程序就会将持有该帧的缓冲区释放掉。使用同步传输时(无DMA),当该帧已上传至NIC,驱动程序就会立刻知道。但使用DMA时,也就是使用异步传输,设备驱动程序必须等待NIC发出明确的中断事件。 4.设备有足够内存处理新

2015-09-26 13:02:51 693

原创 《深入理解Linux网络技术内幕》阅读笔记(四)

通知链 数据结构: 14 struct notifier_block 15 { 16 int (*notifier_call)(struct notifier_block *self, unsigned long, void *); 17 struct notifier_block *next; 18 int priority; 19 };

2015-09-25 23:14:24 1013

原创 《深入理解Linux网络技术内幕》阅读笔记(三)

Netlink Netlink套接字代表用户空间和内核的IP网络配置之间的首选接口。Netlink也可作为内核部分以及多个用户空间进程之间的消息传输系统。 通过Netlink套接字,你可以使用标准套接字API打开或关闭套接字,使用套接字传输数据或者接收套接字数据。 Netlink使用新的PF_NETLINK协议族,只支持SOCK_DGRAM类型,而且定义了几种协议,每一种都用于网络协议栈的不同

2015-09-25 20:10:09 777

原创 《深入理解Linux网络技术内幕》阅读笔记(二)

数据结构191 struct sk_buff_head {192 /* These two members must be first. */193 struct sk_buff *next;194 struct sk_buff *prev;195 196 __u32 qlen;197

2015-09-25 15:19:02 1191

原创 《深入理解Linux网络技术内幕》阅读笔记(一)

垃圾收集: 内存是有限的共享资源,不应该浪费,特别是在内存中,因为内核不使用虚拟内存。多数内核子系统会实现某种垃圾收集,以回收由未使用的或无效的数据结构实例所持有的内存。根据特定的功能所需而定,你会发现有两种主要的垃圾收集: 异步: 这种垃圾收集类型和特定事件无关。一个定时器会定期启用一个函数,以扫描一组数据结构,然后把那些适合删除的数据结构释放掉(常见的准则为是否存在null引用计数)。

2015-09-24 22:39:38 1674

原创 利用typeof实现一个自己的sizeof

不知道C里面的sizeof是怎么实现的,我自己利用typeof实现一个sizeof,实现的宏为:#define SIZEOF(val) ((size_t)((typeof(val) *)0+1))测试代码:#include<stdio.h>#define SIZEOF(val) ((size_t)((typeof(val) *)0+1))void main(){ unsigned int a

2015-09-22 12:37:29 755 1

原创 Linux内核命名空间中关于pid管理的一些理解

记得看《深入Linux内核架构》时,里面有讲到关于命名空间的概念,但是现在却基本上弯光了,唉。所以今天特意自己翻看一下内核4.2代码,整理一下命名空间中关于pid管理的部分,等什么时候有空了,再去翻看那本著作吧(写的比较乱〒_〒)。 命名空间的概念网上有很多,关于pid管理的话,大致思想应该就是各个task_struct的pid在各自的命名空间里面是唯一的,但是在全局不唯一。 通过一个函数fin

2015-09-18 22:14:16 2106 1

原创 用户态进程如何在堆栈执行代码

用户态进程在堆栈执行代码时,因为内核在加载该进程的时候,取消了在堆栈上执行代码的权限,因此如果在其上执行代码的话,进程会直接死掉。 接下来是在堆栈执行代码的测试例子,主要思路是给物理内存加上可执行代码的权限。代码如下:#include<stdio.h>#include<stdlib.h>#include<string.h>#include<unistd.h> #include<sys/m

2015-09-17 15:16:50 1218

原创 关于如何使用内核模块来卸载文件系统(文件系统正在被使用)的测试和验证

今天做的一个测试,当做笔记记录一下。 测试环境: 我在/home目录下面建立一个proc文件夹,然后把proc文件系统挂载到上面,结果如下: 然后执行sleep 200 < ./proc,模拟./proc被使用情况。以下是测试模块的代码和注释:#include <linux/gfp.h>#include <linux/syscalls.h>#include <linux/rcupdat

2015-09-17 14:44:45 729

空空如也

空空如也

TA创建的收藏夹 TA关注的收藏夹

TA关注的人

提示
确定要删除当前文章?
取消 删除