网络子系统54_ip协议分片重组_定位ipq

来源:互联网 发布:韦德数据统计 编辑:程序博客网 时间:2024/06/05 19:00
//为分片确定正确的ipq结构//通过5元组定位ipq,成功后,递增ipq引用计数,返回ipq//定位5元组 //1.<id, 源ip, 目的ip, l4协议> 可通过ip报文获取//2.user 通过ip_defrag给出,指出重组是由谁发起的,最常见的时IP_DEFRAG_LOCAL_DELIVER,当重组的入口分包要传递给本地时//ipq中所有分片最迟完成重组的时间为30HZ1.1 static inline struct ipq *ip_find(struct iphdr *iph, u32 user){//定位4元组__u16 id = iph->id;__u32 saddr = iph->saddr;__u32 daddr = iph->daddr;__u8 protocol = iph->protocol;//对4元组进行hashunsigned int hash = ipqhashfn(id, saddr, daddr, protocol);struct ipq *qp;read_lock(&ipfrag_lock);//选择正确的bucketfor(qp = ipq_hash[hash]; qp; qp = qp->next) {if(qp->id == id&&   qp->saddr == saddr&&   qp->daddr == daddr&&   qp->protocol == protocol &&   qp->user == user) {atomic_inc(&qp->refcnt);read_unlock(&ipfrag_lock);return qp;}}read_unlock(&ipfrag_lock);//该4元组的第一个分片,创建新的ipqreturn ip_frag_create(hash, iph, user);}//调用路径:ip_find->ip_frag_create//新ip分片到达时,根据5元组创建一个ipq1.2 static struct ipq *ip_frag_create(unsigned hash, struct iphdr *iph, u32 user){struct ipq *qp;if ((qp = frag_alloc_queue()) == NULL)//SLAB缓存goto out_nomem;//5元组qp->protocol = iph->protocol;qp->last_in = 0;qp->id = iph->id;qp->saddr = iph->saddr;qp->daddr = iph->daddr;//重组的发起者qp->user = user;//新ipq还没有任何分片与之关联qp->len = 0;qp->meat = 0;qp->fragments = NULL;qp->iif = 0;//入口设备init_timer(&qp->timer);//定时器,当一定时间范围内,重组没有完成,则释放与之关联的内存qp->timer.data = (unsigned long) qp;qp->timer.function = ip_expire;spin_lock_init(&qp->lock);atomic_set(&qp->refcnt, 1);return ip_frag_intern(hash, qp);//将ipq插入到hash表中out_nomem:NETDEBUG(if (net_ratelimit()) printk(KERN_ERR "ip_frag_create: no memory left !\n"));return NULL;}//将ipq插入到hash表中//调用路径:ip_frag_create->ip_frag_intern//函数主要任务://1.修改定时器的到期时间,在一段时间内没有接收到新的分片,则释放所有接收到的分片。//2.将ipq插入到hash表//3.将ipq插入到lru链表1.3 static struct ipq *ip_frag_intern(unsigned int hash, struct ipq *qp_in){struct ipq *qp;write_lock(&ipfrag_lock);qp = qp_in;//sysctl_ipfrag_time = 30HZif (!mod_timer(&qp->timer, jiffies + sysctl_ipfrag_time))//ipq所有封包延迟定时器atomic_inc(&qp->refcnt);//增加引用计数,表示定时器对其的引用//表示hash表对其的引用atomic_inc(&qp->refcnt);if((qp->next = ipq_hash[hash]) != NULL)qp->next->pprev = &qp->next;ipq_hash[hash] = qp;//将ipq插入到hash表中qp->pprev = &ipq_hash[hash];//将新加入的ipq加入到lru尾INIT_LIST_HEAD(&qp->lru_list);list_add_tail(&qp->lru_list, &ipq_lru_list);ip_frag_nqueues++;write_unlock(&ipfrag_lock);return qp;}//ipq中所有分片的到期时间//接收到的ip分片不能永久的存在内存中,如果在一定时间范围内,没有为其完成重组,则需要释放所有分片占用的内存//1.删除定时器//2.从hash表中unlink//3.使用分片的入口设备向发送方发送icmp消息,告诉对方过期//4.释放ipq中的所有分片,释放ipq结构1.4 static void ip_expire(unsigned long arg){struct ipq *qp = (struct ipq *) arg;spin_lock(&qp->lock);if (qp->last_in & COMPLETE)goto out;//删除定时器,从ipq hash表中unlinkipq_kill(qp);if ((qp->last_in&FIRST_IN) && qp->fragments != NULL) {struct sk_buff *head = qp->fragments;if ((head->dev = dev_get_by_index(qp->iif)) != NULL) {icmp_send(head, ICMP_TIME_EXCEEDED, ICMP_EXC_FRAGTIME, 0);//发送ICMP消息dev_put(head->dev);}}out:spin_unlock(&qp->lock);ipq_put(qp, NULL);//释放与ipq关联的所有分片,释放ipq结构}

原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 苹果8卡屏幕划不动了怎么办 苹果x卡屏幕划不动了怎么办 苹果5s解锁密码忘了怎么办 苹果6s屏幕摔碎了怎么办 苹果手机掉在水里了怎么办 乐视手机掉水里没法触屏了怎么办 乐视电视有声音但是黑屏怎么办 苹果手机微信语音有回音怎么办 苹果4s死机了没反应了怎么办 苹果手表的显示平坏了怎么办 苹果5s屏幕翘起来了怎么办 苹果手机圆点卡住屏幕不能动怎么办 苹果5s卡屏怎么也不动应该怎么办 苹果5s手机触摸屏太灵敏怎么办 苹果5s手机关机滑动失灵怎么办 苹果5s关机开机后没信号怎么办 苹果手机5s被弄关机了怎么办 华为荣耀5c换屏后触摸失灵怎么办 三星笔记本鼠标触摸板没反应怎么办 有米6x触摸屏不好使怎么办? 小米5s屏幕触摸没反应怎么办 苹果5s主屏幕设置没反应怎么办 华为畅享5s接听不灵怎么办 红米3s忘记锁屏密码怎么办 华为畅享5s手机打不开网络怎么办 苹果手机突然关机开不了机怎么办 苹果手机掉地上开不了机怎么办 oppo手机突然黑屏开不了机怎么办 苹果6s为什么开不了机怎么办 苹果手机还原出厂设置白苹果怎么办 捡到苹果6s手机怎么办才能自己用 苹果6s玩游戏卡住了怎么办 苹果6s进水换屏后指纹失灵怎么办 苹果手机6s声音按键失灵怎么办 苹果手机触屏失灵怎么办5s 苹果六摔了一下屏幕失灵怎么办 荣耀5c进水屏幕触摸屏失灵怎么办 生活玩家打不了风云蝙蝠岛怎么办啊 企鹅号在注册的时候选错领域怎么办 博士超期学信网的信息被删除怎么办 电脑账号删除后电脑开不了怎么办