2021年10月

根据RFC,IPv6有两种地址管理方式,分别是有状态Stateful无状态Stateless。如其名所示,Stateful模式下主机IPv6地址由路由器分配,而Stateless模式下主机IPv6地址根据协议自身计算得出。大概可以猜到的是,Stateful模式下管理较为方便(如DDNS等),而Stateless模式则是减轻了路由器的工作负担(毕竟IPv6地址池那么大一个,记录所有地址还是很消耗资源的)。

OpenWrt默认使用了Stateless的方式管理IPv6下的内网NAT,然而我想知道内网设备中有多少获取到了IPv6地址= = 于是试图网上冲浪找出配置方法。

左摸索右摸索,也不知道是不是关键词用得不对,老半天才在一篇国人折腾IPv6的文章中摸到了个边。注意到文中配置有个未经解释的ra_management参数,搜了一下发现OpenWrt官网上给出了极为惨淡的解释:

ra_management    integer    1        RA management mode
                                     0: no M-Flag but A-Flag
                                     1: both M and A 
                                     2: M but not A

这里提到了AM两个标志位,而这两个标志位正是DHCPv6中用于控制StatefulStateless模式的标志。

Flag Type Name Message Manual SLAAC DHCPv6
A Autonomous Prefix Information No Yes Maybe
M Managed ICMPv6 134 RA No No Yes
O Other ICMPv6 134 RA No Maybe Yes
L On-Link Prefix Information No Yes Yes

也就是说,理论上,将ra_management设置为2的话就可以强制启用Stateful模式管理IPv6地址。有待试验。

参考: https://blogs.infoblox.com/ipv6-coe/the-ipv6-prefix-information-option-or-fun-with-the-l-flag/

大意了,没有闪

起因是在VS新建了一个C++项目,然后试图引用一个用C写的函数库。结果编译运行的时候报错了,提示无法解析的外部符号。根据常识,这个问题一般与C++的函数重载有关,但是在仔细检查了库函数和调用时函数的签名之后发现并没有问题。用grepdumpbin对着编译出来的.lib静态库文件捣腾了老半天,也愣是没有找出问题所在。

左思右想,唯一的端倪在于用dumpbin观察.lib静态库文件时发现,编译出来的库函数是没有带C++后缀的,而报错的地方所调用的库函数是带了C++后缀的,这也正是导致出现函数名不匹配的地方。无奈之下只能去网上冲浪,带着我也描述不清的问题试图找出解决方法。

在万能的StackOverflow上看到了这个回答之后才意识到,函数名是在编译期确定的。由于头文件本身作为源文件参与编译,编译器只能通过源文件信息来确定这是C还是C++代码。很显然,.c后缀的被MSVC作为C代码编译,而.cpp文件则是作为C++代码编译。

而正是这细微的编译规则差异导致了本次的问题:在库函数源代码中,由于是以.c源文件的形式参与编译,遵循了C语言不允许函数重载的规则,编译出来的函数名就是头文件中所定义的函数名;而在我写的调用程序中,因为使用了.cpp格式的文件,代码使用了C++规则编译,因而给头文件中定义的函数名加上了C++的小尾巴(如@UAEXXZ这种)。在之后的链接过程中再用C++风格的函数名去匹配C风格的函数体,由于两者名字不一致,就产生了无法解析的外部符号问题。

解决方法也非常简单,在写C/C++混合调用的程序时,被调用者(主要是头文件)最好加上用#ifdef __cplusplus包装的extern "C"标记,以确保最大的兼容性

据MathWorks所述,在Matlab 2018之后就允许普通用户从官网下载安装器,制作离线安装包。然而,官方下载器又做的非常脑瘫,只支持单线程顺序下载,并且还没有暂停功能。

然而这些都是题外话,好不容易用100M的校园网带宽挂完了下载之后,安装出了幺蛾子:一打开,先是弹出一个错误界面,然后进入安装器界面后给出模棱两可的错误信息:There was an error communicating with the backend services.。起初我以为是某墙的问题,后来发现断网也无法避免。上网找了半天,没几个和Matlab安装有关的报错信息。最后在官方论坛某帖子的回复里看到了一小段回复(链接):

When I received this error, it was not due to proxy settings or firewall settings. Rather, when I downloaded the installer, the download location was on a remote drive (a windows remote profile DFS location). I copied the setup file to the local drive, and it ran fine.

大意是说,下载的Matlab安装程序不能放在外部文件系统上,包括可移动设备和网络驱动器等。而我恰好为了做备份,直接把Matlab下载到了外置的移动硬盘上,然后直接从移动硬盘上启动了安装程序,从而导致了该问题;而回复者通过把安装程序拷回内置磁盘的方式解决了问题。但是动辄近20GB的完整安装文件来回移动,可以说是duck不必。在Windows下,我们可以尝试活用mklink,把外置磁盘中的文件夹软链接至内置磁盘中,让Matlab以为它是从内置磁盘读取的数据。

事实证明这个方法是有效的。从内置磁盘的软连接中重新启动Matlab安装程序,启动界面正常了,报错也消失了,问题解决。