MooseFS源代码中的一个bug

学习分布式文件系统时,曾经downloadmoosefs的源代码,做了简单的测试,发现moose的实现效率还不错,在阅读器源代码时,发现了其封装了C socket接口,于是把相关的文件保存下来了。昨天闲着没事,想测试一下这个socket接口,在测试udp时,发现服务器接收到数据后,不能正确的向客户端返回信息。

 

阅读了代码发现问题在udpread函数上,udpread的实现如下:

 

int udpread(int sock,uint32_t addr,void *buff,uint16_t leng)

{

         if (addr>addrlen) return -1;

         if (addr==0xffffffff) { // ignore peer name

                   return recvfrom(sock,buff,leng,0,(struct sockaddr *)NULL,0);

         } else {

                   socklen_t templeng;

                   struct sockaddr tempaddr;

                   return recvfrom(sock,buff,leng,0,&tempaddr,&templeng);

 

                   if (templeng==sizeof(struct sockaddr_in)) {

                            addrtab[addr] = *((struct sockaddr_in*)&tempaddr);

                   }

         }

}

 

134个参数很容易理解,第二个参数是一个地址池的编号,这个socket实现中,将经常用到的struct sockaddr结构放到一个内存池(addrtab)中,需要该结构时,直接从内存池中取,并返回地址在地址池中的编号。

 

第二个参数addr即为地址池中一个struct sockaddr的编号,将该编号传入,udpread将另一端的地址填充到对应编号的sockaddr结构中。但此版本的udpread实现中,recvfrom执行完后就直接return了,后面的填充步骤并没有进行,我做了修改后,udp服务器运行正常。

 

本来想把这个问题reportmoosefs的作者的,下了新版的源代码(mfs-1.6.15),发现该bug已经修正,修正后的代码为:

 

int udpread(int sock,uint32_t *ip,uint16_t *port,void *buff,uint16_t leng) {

         socklen_t templeng;

         struct sockaddr tempaddr;

         struct sockaddr_in *saptr;

         int ret;

         ret = recvfrom(sock,buff,leng,0,&tempaddr,&templeng);

         if (templeng==sizeof(struct sockaddr_in)) {

                   saptr = ((struct sockaddr_in*)&tempaddr);

                   if (ip!=(void *)0) {

                            *ip = ntohl(saptr->sin_addr.s_addr);

                   }

                   if (port!=(void *)0) {

                            *port = ntohs(saptr->sin_port);

                   }

         }

         return ret;

}

 

对于网络上的资源(原理讲解,源代码),一定要抱着怀疑的态度看待,否则接受了错误的知识自己去还不知道,尽信书不如无书,自己悟到的才是最好的。

posted @ 2013-04-19 14:08  ydzhang  阅读(186)  评论(0编辑  收藏  举报