117 subscribers
34 photos
35 links
How to code?
@Lazymio
Download Telegram
How2Code
为什么对于一个共享库不推荐静态链接 libc?
假设共享库 B 静态链接了 glibc2.23,现在程序 A 要用到共享库 B,同时程序 A 自己是动态链接或者静态链接了一个其他版本的 libc 甚至不是 gnu 实现的 libc,那么就会有下面一些问题:
1 libc 内部是有很多全局变量的,两份 libc 会导致其内部的状态不一致进而产生难以定位的 bug
2 libc 不同版本之间的内部结构体内存布局是有差异的,相互传递会导致问题
3 libc 本身是跟着内核版本走的,这也是影响 libc 向前兼容的因素之一
所以说对于 buffer 来说 unread 是邪恶的吗?
Tun/Tap 的原理远比我想的简单,但是复杂的问题是 lwip 好难懂....
Windows 适配器强制工作在 L2 而且内核网络栈不管适配器 ARP 帧的解析,所以 TAP Driver 想在 Windows 上跑 TUN 模式实际上实现的时候还是 TAP 模式然后自己处理 ARP 通过 ARP Spoofing 然后去掉 IP 头来达到TUN的效果。
How2Code
Windows 适配器强制工作在 L2 而且内核网络栈不管适配器 ARP 帧的解析,所以 TAP Driver 想在 Windows 上跑 TUN 模式实际上实现的时候还是 TAP 模式然后自己处理 ARP 通过 ARP Spoofing 然后去掉 IP 头来达到TUN的效果。
回过头来看 Linux 怎么处理的。实际上在 Linux 中创建 tun interface的时候 interface 的物理地址是全 0 而且会被设置 NOARP 标志表示关闭了 ARP 协议(这样就完全工作在 L3 了),并且最终到达 tun interface 的包没有 L2 的头部只有 L3 的头部,这是内核支持的。个人理解是不同 interface 有不同的封装成帧方式,内核只交付 L3 的包。
但是在 Windows 上可能天生缺少类似的设计,所以 TAP Driver 为了实现 TUN 模式只好拿 TAP 模式去模拟。
libuv写多了看javascript都觉得眉清目秀了起来
要是几天不出个 Internal Error 我都怀疑我用的不是 MSVC 了
数据千万条,事务第一条
并发不注意,回滚两行泪
Forwarded from Lazymio
python2只是没有区分bytes和string
Forwarded from Lazymio
犯了C++的错误
libpcap 捕获的包长度可能大于 MTU 吗?
其实是有可能的,关键在于网卡的 Offload,简单来说操作系统为了更好的 IO 性能,可能几个包一起交付给网卡然后硬件分片/分段,然而 libpcap 工作在操作系统和网卡之间所以虽然最后发出去的包小于 MTU 但是 libpcap 看到的是大于 MTU 的啦。
struct base1
{
virtual ~base1() { }
int value1;
};

struct base2
{
virtual ~base2() { }
int value2;
};

struct derived : public base1, public base2
{
};

int main()
{
derived obj;
base1* p1 = &obj;
base2* p2 = &obj;
assert(static_cast<void*>(p1) == static_cast<void*>(p2));
}

C++ is amazing!
好吧,其实就是多继承问题。
How2Code
struct base1 { virtual ~base1() { } int value1; }; struct base2 { virtual ~base2() { } int value2; }; struct derived : public base1, public base2 { }; int main() { derived obj; base1* p1 = &obj; base2* p2 = &obj; assert(static_cast<void*>(p1)…
struct base1
{
virtual ~base1() { }
int value1;
};

struct base2
{
virtual ~base2() { }
int value2;
};

struct derived : public base1, public base2
{
};

int main()
{
derived obj;
base1* p1 = &obj;
base2* p2 = &obj;
assert(dynamic_cast<void*>(p1) == dynamic_cast<void*>(p2));
}

More amazing.
原因是 dynamic_cast 返回的地址是最派生类的起始地址,也就是 &obj.
没用的小知识: 怎么让宏必须以分号结尾🤔
没用的小知识: 怎样快速Abort😏