阅读:2027回复:16
如何能知道上层的 TCP 连接已关闭或 UDP 通讯已结束?(20分!)
我正在做一个 NAT 网关,现在遇到了一个最大的难题!!!
在动态映射和端口映射方式中需要涉及到地址资源和端口资源的释放,可是我怎么才能知道上层的 TCP 连接已关闭或 UDP 通讯已结束了呢? 由于一方死机导致的连接失效也应该释放资源,这个又怎么能知道呢? |
|
沙发#
发布于:2002-08-02 16:09
你在哪一层做nat?
我能想到的方式:记录每一条连接 + 时间扫描 |
|
板凳#
发布于:2002-08-02 16:25
哈哈,果然是 swift 第一个到。
我用 Hook NDIS 的方法做,应该算伪 IM 层吧。 你说的“时间扫描”是用定时器定期检查吗?相当于一个超时值?我想过很多方法,这个也想到过,可是这个时间粒度怎么把握?你有没有想到这种情况,有一个 TCP 连接,它每 2 个小时才传输一次数据,这怎么办,总不能认为它已经终止连接了吧? 我认为在 NAT 里面有两个最大的难点,这就是其中之一,请各位高手多关注一下,讨论一下。 |
|
地板#
发布于:2002-08-02 17:42
有想到过,我没做过nat,但做过类似的东西,我没想到什么好办法,只好用时间扫描!
只要你决定用了,时间粒度就不难定了,综合你支持的最大nat数,定一个长一点的时间链就行了,也就是tcp的establish和udp可能长一点! 还有你做nat不是要转发包吗?转发包你也是在imd这层实现? 在receive里调用send?这样行吗? |
|
地下室#
发布于:2002-08-02 18:09
啊?难道在 receive 里调用 send 不行吗?我发的是包的副本啊。
如果转发不能在 IM 实现的话那要在哪层呢? 听了你说的话,好象我之前建立起来的概念都土崩瓦解了!!! [编辑 - 8/2/02 by edust] |
|
5楼#
发布于:2002-08-03 03:36
1. 首先,udp是无连接的,不存在状态这么一说,所以不必要担心UDP的问题。
2. 对于TCP连接,很多os的协议栈都认为如果一个连接超过75s没有 数据包通过的话就认为该连接已经断开。并且是通过计时器来实现的。你可以在driver中开一个定时器以及一个COUNTER,每隔5s钟对NAT映射表进行一次扫描,如果5s之内没有数据包通过则counter -1,如果有数据包通过则counter值复位;直到counter小于某个值时将相应的映射表项清空。 3. 包的转发如果用应用层来实现的话,则要涉及到许多内存分配释放等事情,而且效率明显要降低。因此,在driver中处理是比较好的选择,但是这样系统的拓展性就要差一些。在receive里面调用send是完全可以的 |
|
6楼#
发布于:2002-08-03 09:09
to SevenYears_2002:
呵呵,你注册后的第一个帖子就回给了我,感谢,感谢. (1)可是我认为正因为 UDP 是无连接的,所以才难处理,因为不知道它什么时候不再通讯了啊? (2)那就象我上面说的那种情况呢?假如一个 TCP 连接,它每 2 小时才互相通讯一次,那岂不是会被认为是连接关闭了吗? (3)这下我放心了!!! |
|
7楼#
发布于:2002-08-03 10:25
1,是做nat,即使无连接的也要维护一条连接,只是没了tcp的状态变换处理
2,是的,用户就必须重新连接 3,你最好试试,试好了也告诉我一声,呵呵,我以前试过,没试通,可能没那么仔细的试,因为我们不做,没压力! |
|
8楼#
发布于:2002-08-03 10:39
to swift:
(1)这个我也明白,但是怎么才能知道 UDP 通讯已经终止了呢?它又没有 FIN 标志?(另外:做 NAT 必须维护每个通讯的状态吗?还有那些“规范”,我是菜鸟,望指教,多谢!) (2)那么试想这样一种情况:我们的 NAT 工作在动态地址池映射方式,192.168.0.3 假设被影射成了 101.102.103.104,它通讯一次之后 2 个小时才会再通讯,这时我们却认为它的连接终止了,于是撤消了映射,那么 101.102.103.104 这个地址可能又被分配给了 192.168.0.11 这个内网主机,现在外网的主机想通过 101.102.103.104 这个地址访问 192.168.0.3,但是此时 101.102.103.104 却指向 192.168.0.11,这不是乱了套了吗? (3)好的,我如果验证可行的话一定通知你,不过可能还要一段时间,因为首先我要解决这些问题啊! |
|
9楼#
发布于:2002-08-03 10:54
to SevenYears_2002:
75 秒也太短了点吧?如果我和某人在用一个基于 TCP 的文字聊天工具,我们 2 分钟(120 秒)没有互相对话,难道 OS 就把连接关闭了?我用过也写过这样的聊天工具,好象没有这种情况啊? |
|
10楼#
发布于:2002-08-04 01:25
会不会是TCP在空闲的时候自己发包测试?
我似乎记得在TDI对应每个连接又一个FiltObject,那么只要查询这个FileObject是否被关闭了不就的了?我也是听别人似乎讲过,不一定对阿. |
|
11楼#
发布于:2002-08-04 12:26
to fracker:
那么非面向连接的协议呢?比如 UDP。 在 IM 中能访问 TDI 的“FiltObject”吗? |
|
12楼#
发布于:2002-08-05 09:43
1,udp也可以象tcp的Establish状态一样处理,就是用timeout
2,我想你做nat都应该是ip+port-->ip+port吧,这样也应该没什么问题,加上port这个参数应该比较好处理了吧,就是不最,最多也是内网的机器拒收罢了!不过最好不要出现这种情况! 3,等着你告诉我呢,呵呵 :) 75S是比较短,还有tcp不会发测试包,就象telnet一样,你不动它它就不会发包! 你可以设置的长一些,1个小时或者1个半小时! |
|
13楼#
发布于:2002-08-05 09:46
它是做nat,数据包可能还到不了tdi就被转发了!
|
|
14楼#
发布于:2002-08-05 09:56
好了,好了,swift 你终于出现了,就等你出现跟你讨教了。
经过这两天的考虑我决定就用 timeout 了,现在问题就在于时间粒度的把握了,上面你说的用 1 或 1.5 个小时,这是经验值还是测试值?现有的防火墙/NAT 产品,它们的 timeout 值是多少?如知道的话望告知。 那个结果出来以后我会立刻通知你的,只是还要一段时间。 |
|
15楼#
发布于:2002-08-05 10:44
呵呵,我是瞎写的,没什么验证,你最好做一个验证,我不知道的说,:)
|
|
16楼#
发布于:2002-08-07 10:59
给分!
|
|