mpd在接入PPPoE和PPTP时,最高能支持多少个连接?
敬告:本人对源代码不熟悉,仅仅是查看了一部分,所以本文不一定准确,欢迎批评指正。MPD的官方网站就说,MPD是为成千上万个大量的连接而生,所以mpd的接入能力肯定不一般,但它的接入上限上多少呢?
国外网站有人测试极限到了10000多,但具体是多少呢?
先从mpd的原理开始分析,mpd每接入一个连接,就会为这个连接创建一个ng界面,相当于虚拟的网卡。然而为什么是ng呢?
mpd底层使用了netgraph框架,ng其实就是netgraph的缩写,mpd的支持能力其实就是netgraph的支持能力,于是上面的问题就转化为:netgraph到底能支持多少个虚拟界面呢?
先来看ng的定义:
/usr/src/sys/netgraph/ng_iface.c,552行:
……
priv->unit = alloc_unr(V_ng_iface_unit);
NG_NODE_SET_PRIVATE(node, priv);
priv->node = node;
if_initname(ifp, NG_IFACE_IFACE_NAME, priv->unit);
ifp->if_output = ng_iface_output;
ifp->if_start = ng_iface_start;
ifp->if_ioctl = ng_iface_ioctl;……
……
看到来源了,是V_ng_iface_unit,而这个V_ng_iface_unit值是怎么来的呢?
继续查本文,在845行:
static void
vnet_ng_iface_init(const void *unused)
{
V_ng_iface_unit = new_unrhdr(0, 0xffff, NULL);
}
……
注意new_unrhdr是一个系统调用,可以man unr获得详细信息,就相当于下一个整数,还要注意这儿有一个值:0xffff,这个值在函数的参数中表示为:int high,表示最高数,而第一个参数0则表示为:int low,从这个地方猜想,可以知道netgraph中的界面取值为0-0xffff,也就是0-65535。
当然这只是猜想,再继续验证:
/usr/src/sys/net/if.c,3342行:
void
if_initname(struct ifnet *ifp, const char *name, int unit)
{
ifp->if_dname = name;
ifp->if_dunit = unit;
if (unit != IF_DUNIT_NONE)
snprintf(ifp->if_xname, IFNAMSIZ, "%s%d", name, unit);
else
strlcpy(ifp->if_xname, name, IFNAMSIZ);
}
……
上面的printf已经显示这就是ng*的来源。
那具体的值是多少呢?真的是65536个虚拟界面吗?我们来写个shell程序判断一下,看netgraph到底能创建多少个界面:
% cat ng.sh
#!/bin/sh
for i in $(seq 0 65535); do
/usr/sbin/ngctl mkpeer iface dummy inet
if [ $? -ne 0 ] ; then
echo "failed $i";
break;
else
echo "success $i";
fi
done
结果:
success 65376
success 65377
ngctl: send msg: Cannot allocate memory
failed 65378
另外本系统还有许多vlan:
# ifconfig grep vlan wc -l
304
每条vlan占两行,所以数量为:304/2=152
总数为:65378+152=65530;
另外系统还有两个网卡,一个lo,一个ipfw0
加起来是65534……
好吧,还有两个空,不知道哪儿去了,我想你也不会在6万5千多个界面中,还去在乎那一两个吧!
再说了,vlan和真实的网卡,最大值是不是0xffff还难说呢,还真有0-ffffff的呢,6个f代表多少来着?一千六百多万,可以个大数字呢!
ioapic0: Changing APIC ID to 1
ioapic0 irqs 0-23 on motherboard
NEW_UNRHDR 0-ffffff -> 0xc1a4dd00
npx0: [FAST]
npx0: on motherboard
npx0: INT 16 interface
……
sio0: <16550A-compatible COM port> port 0x3f8-0x3ff irq 4 flags 0x10 on acpi0
sio0: type 16550A
NEW_UNRHDR 0-ffff -> 0xc1b6ab00
ppc0: port 0x378-0x37f irq 7 on acpi0
ppc0: Generic chipset (NIBBLE-only) in COMPATIBLE mode
结论:
如果你打算接入超入65500个用户,那么你需要修改一下netgraph的源代码……