使用CONNMARK解决Linux上源进源出问题

FWMARK是啥? FWMARK是Linux在处理网络数据包的时候给数据包加上的一个标识,我们可以根据fwmark配置不同的转发规则。 作用域 FWMARK作用于单个数据包。 比如我们可以采用ip rule add fwmark 0x1234 lookup 456这样,让被mark为0x1234的数据包查询路由表456出去。 由于FWMARK是针对单个PACKET而言的,因此在下文中我们所指的Packet Mark与这里的FWMARK相同。 如何给出去/进来的数据包设置FWMARK? 如果要对服务器外出连接设置fwmark,可以使用socket,可以通过setsockopt来设置数据包的MARK,详见这里。 如果要对于某个Wireguard网卡的流入数据包设置fwmark,可以使用wg set $WG_IFACE…

GDB Watchpoint在x86、MIPS、ARM上的实验与MIPS Illegal instruction

MIPS上遇到的glibc的坑 最近突发奇想可以用硬件提供的Debug功能来做一些简单的安全防护,于是进行了一个小实验测试在不支持硬件Debug的平台上设置GDB的Watchpoint带来的性能影响。但是在MIPS平台上测试的时候遇到了一个小问题。 首先将测试程序通过mipsel-linux-gnu-gcc在其它平台上交叉编译,只添加-static -g用于使用静态编译以及开启调试,并在x86上使用qemu-user-static测试通过,然后通过sftp传到MIPS平台上(手边除了FPGA的软核只有一台使用mt7621CPU的路由器为MIPS架构硬件,因此选择了我的路由器作为实验环境),结果发生了以下一幕。 root@OpenWrt:/tmp/gdb-perf# file a.out a.out: ELF 32-bit LSB executable, MIPS, MIPS32 rel2 version 1 (SYSV),…

基于块设备的Linux内核内存监视模块

就在完成了支持Linux 5.10的ramdisk驱动模块后不久,突发奇想,既然之前提到Linux内核模块之间地址空间是完全共享的,那么可以编写一个模块,通过块设备驱动的方式来直接对内存进行读写。 因此,我便对之前块设备驱动的代码做了些许改动,编写了一个新的模块,名为spy。 于是我便尝试从新的模块对之前的ramdisk模块进行一个数据盗取。 获取数据的地址 Linux内核本身提供了一个查看内核符号的接口,位于/proc/kallsyms,我们只需要将它cat出来然后用grep选择我们所需的数据即可。 $ sudo cat /proc/kallsyms | grep myramdisk ffffffffc0bd8024 r _note_7 [myramdisk] ffffffffc0bd7000…

Linux内核调试环境的搭建 QEMU+GDB

最近在折腾Linux内核,但是折腾调试环境以及修改内核的编译选项就折腾了我一晚上的时间。 我使用的调试环境包括: QEMU(用于软件模拟系统执行环境,方便对硬件各寄存器等状态进行调试,为了方便起见,这里使用x86_64环境) GDB 以下是我的折腾步骤: Step 0. 安装必要工具 需要确保你已经有以下软件包(对于Debian/Ubuntu): build-essential gdb qemu-system-x86 rsync(用于带权限的文件复制) 如果你采用其他发行版,可以参考对应发行版的相关Wiki,以及使用软件包管理器的搜索功能。 Step 1. 准备内核 Substep…

博客复更

最近在研究Linux内核相关的东西,准备写几篇文章记录一下。但是自己的博客太久没有打理了。 本来打算将博客迁移到Hugo上,但是发现评论的迁移和搜索的实现比较麻烦,因此最终还是决定继续使用WordPress。 之前WordPress最让我头疼的问题是在于代码高亮插件。在不同的代码高亮插件间切换令人崩溃。同时由于我使用的代码高亮插件在遇到<和>字符的时候会自动escape,但是在编辑器中每次打开再保存会又escape一次,不知道为什么会有这样奇怪的设定。这也就导致了我一直纠结于博客系统而就放弃了内容上的更新。 今天仔细研究了一下相关方案,发现WordPress上有一个插件可以很好地解决问题,插件名叫WP Githuber MD。可以直接在里面使用Markdown来编写,同时还自带了优化Markdown文档的种种插件,比如用于代码高亮的prism.js,以及用于数学公式的KaTex。 改了几篇文章下来,感觉比之前使用WordPress编辑器+各种插件+部分手写HTML要方便不少。最终决定采用这个方案继续写博客了。也感谢大家这么多年来对我的博客的支持,希望接下来继续生产许多有价值的内容。

HDU 6657 – Acesrc and Cube Hypernet

题意: 给一个纸条,问是否可以折成一个立方体,纸条用一个h*w的矩阵上的#来描述,h<=100,w<=100,T<=30(数据组数)。 分析: 当时多校赛场上读完题就想到了可以枚举点然后BFS填充格子,只要有一个起点能满足不重复地填充给出图形上的所有#号点,且立方体被填满,就输出yes。由于h<=100,w<=100,所以最大的正方体的边长为100/4=25,因此我们枚举点25*25,check使用25*25*6的复杂度可以完成。 不过因为后来跟榜先搞别的题去了这题就先放一边,结果我们队后来因为开车那题自闭到最后. 这题的难点在于处理BFS时转向的问题。 我们可以先建立一个三维坐标,第一维是所属的面,第二维和第三维是这个坐标在这个面中的位置。如下图所示,中间的数字是面坐标的编号。 然后对于编号1的面,向周围4个面走的时候都是直接走即可,不需要进行坐标变换。 而对于需要进行坐标变换的情况,比如从0这个面一直向上走,走到4,需要将x和y坐标对调,然后逆时针转90°,再继续填充这个格子。 对于6个面,向4个方向走只有6*4=24种情况,所以直接把这24种情况x和y和方向的变化写出来(可以用if或者switch),然后直接做就完了。 然后就直接上一段很丑的代码吧。(为什么这么丑还要写博客呢,因为这算是在多校期间补的题中AC的人最少的一道题吧) 代码: #include <bits/stdc++.h> using namespace std; int…

二维ST表学习笔记

众所周知,ST表是一种离线解决RMQ(区间最值)问题的方法。 可以在O(n \log {n} ) 的时间内进行预处理,然后在O(1)时间内查询到结果。 复习一维 我们先来复习一下,一维st表的预处理和查询过程。 对于预处理,我们先定义一个名为st的二维数组,其中st[i][j]表示以i为起点,从起点开始(含起点)往后2^j个元素的最值。 满足i+2^j-1不越界 因为2^0 = 1 ,因此st[i][0]=a[i] 然后我们用2个for循环去打表就行了 接着是查询,这里我画了个图来解释。 其中橙色的线表示两个区间。 一维代码…