主页 PC知识 网管技术 黑客帝国 安全技术 开放系统 程序设计 搜索 技术论坛

 

相关联接
 
RHU本级分类

技术开发
桌面应用
嵌入技术
问答(FAQ)
基础知识
企业应用&技巧

 
RHU阅读排行
·手把手教你如何写Makefile
·Linux下PCI设备驱动程序开发基本框架
·VSFTP+MySQL虚拟用户配置过程讲解
·如何在Linux桌面上搭建C/C++IDE开发环境
·嵌入Linux基于MiniGUI信息终端软件开发
·Linux下动态链接库技术分析和移植技巧
·Linux网络编程几个必需的网络函数介绍
·一套的实用完整Makefile参考模板
·Sniff网络基础原理和软件实现技巧详解
·Linux系统和内核初始化过程简要介绍

 
 
RHU最新文章
·几个重要的Linux操作系统 内核文件介绍
·构筑Linux防火墙之为个人用户设置防火墙
·构筑防火墙之IPtables搭建防火墙的规则
·如何使用Linux LiveCD评估系统的安全性
·磨炼Gentoo的锋芒之只要敢想 就有Gentoo
·揭秘Linux内核调试器之内幕
·用SRP建立安全的Linux Telnet服务器
·构筑Linux防火墙之什么是Linux防火墙
·Fedora core 2服务器平台安全设置揭秘
·引黑客入瓮 给Linux系统蒙上Windows面纱

 
 
RHU相关搜索









 
 
RHU广而告之

 
 
>您的位置:首页 -> Linux/Unix-> 技术开发
基于linux集群的具体模块的设计和实现

作者:RHU-TAC编辑员 来自:RHU网络采集 时间:2005-6-20 双击滚屏 收藏本页 字体:


点击 查看RHU2004全年文章


本篇是《基于linux的集群系统》实现篇的下部分。将向我们讲述各个模块的具体设计和实现。

6 ip伪装模块的分析
6.1 设计思想

ip伪装模块的主要工作是:

1.接收内部网发向外部网的所有请求。

2.内部网中的连接请求通过平衡器转发到外部网。

3.将内部网发向外部网中的所有请求的源地址隐藏,使所有请求看上去都是由平衡器发送的。

4. 建立HASH表来记录已经建立的所有连接。

5. 接收外部网对请求的回应并将其转发到内部网中的发出请求的机器上。

6.2 模块流程

(1) 内部网中的机器向外部网中的机器发送连接请求的流程。


(2) 外部网中的机器向内部网中的机器发送连接请求的流程。


6.3 结构设计

程序名 标识符 功能 源程序
建立HASH队列 ip_masq_hash 根据m{addr, port}和s{addr, port}建立两个HASH队列 ip_masq.c
从HASH队列删除表项 ip_masq_unhash 将ip_masq表项从HASH队列中删除 ip_masq.c
处理从外到内的请求 __ip_masq_in_get 处理从外到内的请求,查询HASH表,找到内部机器的ip地址及端口 ip_masq.c
处理从内到外的请求 __ip_masq_out_get 处理从内到外的请求,查询HASH表,找出源地址、端口及目标地址、端口都匹配的表项。 ip_masq.c
减少某个连接的访问计数 __ip_masq_put 将ip_masq表项的访问计数减一。 ip_masq.c
取下一伪装端口 get_next_mport 取得下一个mport。 ip_masq.c
创建新的ip_masq结构 ip_masq_new 创建一个新ip_masq结构,并分配一个新的mport ip_masq.c
从内到外请求处理的最上层函数 ip_fw_masquerade 负责从内向外请求的处理全过程。 ip_masq.c
从外到内请求处理的最上层函数 ip_fw_demasquerade 负责从外向内请求的处理全过程。 ip_masq.c

6.4 主要数据结构


struct  ip_masq{
struct  ip_masq  *m_link,  *s_link;
atomic_t   refcnt;
struct   timer_list  timer;
__u16  protocol;
__u16  sport,  dport,  mport;
__u32  saddr,  daddr,  maddr;
struct  ip_masq_seq  out_seq, in_seq;
void  *app_data;
struct  ip_masq  *control;
atomic_t  n_control;
unsigned  flags;
unsigned  timeout;
unsigned  state;
struct  ip_masq_timeout_table  *timeout_table;
}

6.5 算法及流程

(1) ip_masq_hash

格式:static ip_masq_hash(struct ip_masq *ms)

返回值:1:成功;0:失败。

处理流程:

1. 如果ms->flags 已设IP_MASQ_F_HASHED标志位,则返回0。

2.根据ms->protocol、 ms->maddr和 ms->mport产生hash->key。

3.将ms链接到hash[hash_key] 链的头位置。

4.增加ms的访问计数。

5.根据ms->protocol 、ms->sadd和ms->sport产生hash_key。

6.将ms链接到hash[hash_key] 链的头位置。

7.增加ms的访问计数。

8.ms->flags 设IP_MASQ_F_HASHED位。

9. 返回1。

(2)ip_masq_unhash

格式:static int ip_masq_unhash(struct ip_masq *ms)

返回值: 1:成功;0:失败。

处理流程:

1. 如果ms->flags未设IP_MASQ_F_HASHED位,则返回0。

2. 不然,做以下几步。

3. 根据ms->protocol、 ms->maddr和 ms->mport产生hash->key。

4.在hash[hash_key]链中找匹配的表项,将匹配项的访问计数减一,并从链表中删除此项。

5. 根据ms->protocol 、ms->sadd和 ms->sport产生hash_key。

6.在hash[hash_key]链中找匹配的表项,将匹配项的访问计数减一,并从链表中删除此项。

7. ms->flags设位~IP_MASQ_F_HASHED。

8. 返回1。

(3)__ip_masq_in_get

格式:static struct ip_masq *__ip_masq_in_get(int protocol, __u32 s_addr, __u16 s_port, __u32 d_addr, __u16 d_port)

返回值:返回一个ip_masq结构ms。

处理流程:

1. 根据 protocol 、 d_addr、 d_port产生hash_key。

2. 在hash[hash_key]链中找匹配的表项,满足: (protocol == ms->protocol && d_addr == ms->maddr && dport == ms->mport && (s_addr == ms->daddr || ms->flags & MASQ_DADDR_PASS) && (s_port == ms->dport || ms_flags & MASQ_DPORT_PASS))。

3. ms的访问计数增1。

4. 返回ms。

(4)__ip_masq_out_get

格式:static struct ip_masq *__ip_masq_out_get(int protocol , __u32 s_addr, __u16 s_port, __u32 d_addr, __u16 d_port)

返回值:返回一个ms。

处理流程:

1. 如果s_port不为0,做以下几步;不然,跳至第5步。

2. 根据 protocol 、 s_addr和s_port产生hash_key。

3. 在hash[hash_key]链中找匹配的表项,满足:(protocol == ms->protocol && s_addr == ms->saddr && sport == ms->sport && (d_addr == ms->daddr || ms->flags & MASQ_DADDR_PASS) && (d_port == ms->dport || ms_flags & MASQ_DPORT_PASS))。

4. ms的访问计数增1。

5. 返回ms。

6. 根据 protocol 、 s_add、 0产生hash_key。

7. 在hash[hash_key]链中找匹配的表项,满足:(protocol == ms->protocol && s_addr == ms->saddr && sport == ms->sport && (d_addr == ms->daddr || ms->flags & MASQ_DADDR_PASS) && (d_port == ms->dport || ms_flags & MASQ_DPORT_PASS))。

8. ms的访问计数增1。

9. 返回ms。

(5)__ip_masq_getbym

格式:static struct ip_masq *__ip_masq_getbym(int protocol, __u32 m_addr, __u16 m_port)

返回值:返回一个ms。

处理流程:

1. 根据 protocol 、m_add和 m_port产生hash_key。

2. 在hash[hash_key]链中找匹配的表项,满足:(protocol == ms->protocol && m_addr == ms->maddr && mport == ms->mport )。

3. ms的访问计数加1。

4. 返回ms。

(6)ip_masq_out_get

格式:struct ip_masq *ip_masq_out_get(int protocol, __u32 s_addr, __u16 s_port, __u32 d_addr, __u16 d_port)

返回值:返回ms。

处理流程:

1. 为__ip_masq_lock加读锁。

2. 调__ip_masq_out_get(protocol, s_addr, s_port, d_addr, d_port)返回ms。

3. 解读锁__ip_masq_lock。

4. 为ms设置超时。

5. 返回ms。

(7)ip_masq_in_get

格式:struct ip_masq_in_get(int protocol, __u32 s_addr, __u16 s_port, __u32 d_addr, __u16 d_port)

返回值:返回ms。

处理流程:

1.为__ip_masq_lock加读锁。

2.调__ip_masq_in_get(protocol, s_addr, s_port, d_addr, d_port)返回ms。

3. 解读锁__ip_masq_lock。

4. 为ms设置超时。

6. 返回ms。

(8)__ip_masq_put

格式:static __inline __void __ip_masq_put(struct ip_masq *ms)

返回值:无

处理流程:

1. 将ms的访问计数减一。

(9)get_next_mport

格式:static __u16 get_next_mport(void)

返回值:返回一个16位的端口号。

处理流程:

1. 为masq_mport_lock加旋转锁。

2. Mport = htons(masq_port ++)。

3. 如果masq_port是最后一个锁,则masq_port = 开始锁。

4. 解旋转锁masq_port_lock。

5. 返回mport。

(10)ip_masq_new

格式:struct ip_masq *ip_masq_new(int proto, __u32 maddr, __u16 mport, __u32 saddr, __u16 sport, __u32 daddr, __u16 dport, unsigned mflags)

返回值:成功:返回ms;失败:返回null。

处理流程:

1. 如果没有可用端口,返回NULL。

2. 若mflags 设IP_MASQ_F_USER位,则 prio = GFP_KERNEL;不然, prio=GFP_ATOMIC。

3. 为ms分配空间,若失败,返回NULL。

4. MOD_INC_USE_CONUNT。

5. 清空ms。

6. 初始化ms->timer。

7. ms->timer.data = (unsigned long)ms;

ms->timer.function = masq_expire;

ms->protocol = proto;

ms->saddr = saddr;

ms->sport = sport;

ms->daddr = daddr;

ms->dport = dport;

ms->flags = NULL;

ms->app_data = NULL;

ms->control = NULL;

设ms->n_control 为0;

设ms->refcnt 为0;

ms->maddr = maddr;

ms->flags设IP_MASQ_F_NO_REPLY位。

8. 如果((协议不是TCP 和UDP)|| mport),ms的伪装端口设为mport。调用__ip_masq_in_get取得ms。

9. 如果没有匹配的ms,则ms->flags设 IP_MASQ_F_MPORT位;增加伪装端口计数;将ms加入HASH队列;调用ip_masq_bind_app(ms);ms的访问计数加一;为ms的IP_MASQ_S_NONE状态设置超时;返回ms。

10. 如果有匹配项,则调用__ip_masq_put(mst)使访问计数减一;释放ms; MOD_DEC_USE_COUNT;返回NULL。

11. 调用mport = get_next_mport()来找一个可用的端口。

12. 赋值 ms->mport = mport。

13. 调用ip_masq_bind_app(ms)。

14. 设n_fails为0。

15.ms的访问计数增一。

16.为ms的IP_MASQ_S_NONE设置超时。

17.返回ms。

(11)ip_fw_masquerade

格式:int ip_masquerade(struct sk_buff **skb_p, __u32 maddr)

返回值:成功:返回大于0的数;失败:返回-1。

处理流程:

1. 先做一些有关校验和的检查。

2. 调用ip_masq_out_get_iph看入口是否已经存在。

3. 如果入口存在的话,将老的ms从HASH表中删除,将ms->maddr替换为maddr,并将新的ms结构加入HASH队列。

4. 如果没有定义源端口,做以下几步:将老的ms从HASH表中删除,设置ms->sport =h.portp[0],即设置ms的源端口为TCP头中的源端口,将新的ms加入HASH表。

5. 如果定义了IP_MASQ_F_DLOOSE,ms->dport = h .port[1]; ms->daddr = iph->daddr。

6. 如果入口不存在则创建一个新的ms。

7. 将IP头的源地址替换为平衡器的ip地址。

8. 将TCP头的源端口替换为ms的伪装端口。

9. 做一些有关校验和的操作。

10. ms的访问计数减一。

11. 返回0。

(12)ip_fw_demasquerade

格式: int ip_fw_demasquerade(struct sk_buff **skb_p)

返回值:成功:返回1;失败:返回-1。

处理流程:

1. 取得sk_buff中的数据取的起始地址。

2. 取得数据区的大小。

3. 取得针对协议的偏移量。

4. Maddr = iph->daddr。

5.察看协议类型,如果是ICMP,则调用ip_fw_demasq_icmp;如果是TCP,什么也不做;如果是UDP协议,则首先确认端口号在BEGIN 和END之间,然后对校验和进行一定的操作。

6. 看现有表中是否有匹配项,返回ms。

7.如果有匹配项,设置标识位~IP_MASQ_F_NO_REPLY;如果定义了非严格路由,则ms->dport = h.portp[0], ms->daddr = iph_saddr。

8. 如果定义了IP_MASQ_F_NO_DPORT,则标识位设~IP_MASQ_F_DPORT, ms的目的端口设为TCP头中的源端口。

9.如果定义了IP_MASQ_F_NO_DADDR,ms的标识位设~IP_MASQ_F_NO_DADDR,ms的目标地址设为IP头的源地址。

10. 调用masq_skb_cow复制一个skb。

[本文共有 2 页,当前是第 1 页] <<上一页 下一页>>



OVER

[1] [2] 页 RedHyphone.Union 投稿邮箱
[特别声明]:
本站文章大多搜索转载自网络中,如果侵犯了您的权利,请告之我们。本站将立即删除。
本站所有转载文章言论不代表本站观点,本站所提供的摄影照片,插画,设计作品,如需使用,请与原作者联系,版权归原作者所有。
查看评论】【向上滚屏】【关闭窗口】【 打印
-相关文章
  • openSUSE 11.1 Final - 正式发布
  • [视频]Opera Mini 4.2 正式版发布
  • dll注入系统进程(开源代码)
  • 认知盲区 解惑双网卡双线路DNS解析
  • FlashFXP 简体中文版 3.7.5 Build 1303 Beta[烈火]
  • -文章评论 (关闭)
    ·还没有相关的评论!

    网上大名:
    红旋风网络技术联盟 RHUTech.Union
     
    Copyright © 2000-2007 RedHyphone.Union All Rights Reserved. 红旋风联盟版权所有.皖ICP备05011033号
    中国红旋风网络技术联盟 | www.RedHyphone.net
    Mailto:Redhyphone@gamil.com