SF# 411 459 207 663 sf是什么位置意思

我真是大明星最新章节列表_我真是大明星最新章节目录_笔趣阁
& 我真是大明星最新章节列表
世界变成一款游戏,世界背景被游戏随机修改了,幡然一新,历史与社会结构虽然变化不大,但却没有了那些我熟知的综艺节目、音乐作品、文学作品和影视作品。游戏还有商城,里面提供了一系列神奇的物品,目的就是帮助我完成游戏主线任务——让我成为世界上最伟大的明星。\n
本站提示:各位书友要是觉得《我真是大明星》还不错的话请不要忘记向您QQ群和微博里的朋友推荐哦!
&推荐阅读:、、、、、、、、、、、、、404 Not Found
The requested URL /22267 was not found on this server.毒妃在上,邪王在下 最新章节 TXT下载 全文阅读_穆丹枫新书_笔趣阁
毒妃在上,邪王在下
作者:穆丹枫分类:穿越小说状态:连载字数:2534460更新时间: 01:36:23最新章节:
“小玖玖,你逃不掉的~”将她禁锢在床,他笑的邪魅恣意。
顾惜玖懒懒一笑,反将他压在床上,满是挑衅:“我要在上面——”
堂堂杀手之王,就算穿成受气包嫡女,遭暗算送上变态渣男的床,一样玩得飞起。
训小三,虐渣男,斩断烂桃花,她在这繁华大陆畅意逍遥。
没想到那位全大陆奉为神尊的人找上门来,对她倒贴+碰瓷
“女人,剥了我摸了我就想不认账?”
作者:穆丹枫所写的《毒妃在上,邪王在下》无弹窗免费全文阅读为转载作品,章节由网友发布。无弹窗推荐地址:http://www.biqiuge.com/book/13761/
笔趣阁小说推荐阅读:、、、、、、、、、
《毒妃在上,邪王在下》最新章节列表
《毒妃在上,邪王在下》正文卷
《毒妃在上,邪王在下》所有内容均来自互联网或网友上传,笔趣阁只为原作者穆丹枫的小说进行宣传。欢迎各位书友支持穆丹枫并收藏《毒妃在上,邪王在下》最新章节。
本站所有小说为转载作品,所有章节均由网友上传,转载至本站只是为了宣传本书让更多读者欣赏,如有侵权请 联系我们,我们会尽快处理。lucasysfeng
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728
/****************************************** Name&&&&&&& : Vtun 源码详细分析* Version&&&& : 3.0.3* Date&&&&&&& : Jan. 22, 2014* Author&&&&& : lucas* Email&&&&&& : * Blog&&&&&&& : http://www.cnblogs.com/lucasysfeng/* Description : 1.Vtun是一个短小精悍的开源VPN项目,* & & & & & & & & &这里分析了其客户端和服务器的源码。* & & & & & & & 2.vtun源码可以从下面网址下载* & & & & & & & &&*****************************************/&&/*********************************************** client端代码执行基本流程分析 ************************************************//*****************************************************************原型:int main(int argc, char* argv[], char* env[]);*功能:初始化操作,确定是client端还是server端。*下一步:根据命令行参数选择执行client或者server分支,先分析client。*****************************************************************/int main(int argc,&char&*argv[],&char&*env[]){&&&& ......&&&& ......//初始化vtun结构体。&&& while(&(opt=getopt(argc,argv,"misf:P:L:t:npq"))&!= EOF )&//获取命令行参数并进行相应操作。&&& {&&&&&&&& ......&&&& }&&&& reread_config(0);&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& //读配置文件。&&& ......&&&& clear_nat_hack_flags(svr);&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& //清除另一方的nat_hack标志。&&& if(!svr)&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& //根据命令行参数进行客户端配置。&&& {&&&&&&&& ......&&&&&&&& hst = argv[optind++];&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& //vtund server [ip]的第二个参数给hst,这个参数是服务器给客户端定义的名字。&&&&&&& host = find_host(hst);&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& //hst是命令行参数,host是配置文件中的对应该参数的会话信息。&&&&&&& ......&&&& }&&&& vtun.svr_name = strdup(argv[optind]);&&&&&&&&&&&&&&&&&&& //vtund server [ip]的ip给vtun.srv_name&&& ......&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& //如果vtun结构体的一些成员没有被初试话,则赋予默认值。&&& switch( vtun.svr_type )&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& //判断vtun的类型,VTUN_STAND_ALONE VTUN_INETD.&&& {&&&&&&&& ......&&&& }&&&& if( daemon )&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& //是否要创建守护进程&&& {&&&&&&&& if( dofork && fork()&)&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& //当命令行设置为超级守护进程时不执行该操作。&&&&&&& ...&&&& }&&&& if(svr)&&&& {&&&&&&&& memset(&sa,0,sizeof(sa));&&&&&&&&&&&&&&&&&&&&&&&&&&& //挂起时读取配置文件。&&&&&&& sa.sa_handler=reread_config;&&&&&&&& sigaction(SIGHUP,&sa,NULL);&&&&&&&&& init_title(argc,argv,env,"vtund[s]: ");&&&&&&&&& if( vtun.svr_type == VTUN_STAND_ALONE )&&&&&&&&&&& write_pid();&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& //将当前pid写入文件中&&&&&&&&& server(sock);&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& //执行服务器操作&&& }&else&{&&&&&&&& init_title(argc,argv,env,"vtund[c]: ");&&&&&&&& client(host);&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& //执行客户端操作,host就是从配置文件读取出的对应命令行参数会话名的信息。&&& }&&&& ......}&&/*************************************************************原型:void client(struct vtun_host *host);*参数:host是从配置文件中读出某个会话名所包含的信息。*功能:建立socket以及bind、connect、select等,认证暨建立隧道。*下一步:认证auth_client(s,host)后再执行tunnel(host)即开启隧道。*************************************************************/void client(struct vtun_host *host)&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& //host参数是main函数中传递的配置文件中的会话信息。{&&&& ......&&&& ......&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& //结束,挂起等信号处理函数。&&& while(&(!client_term)&||&(client_term == VTUN_SIG_HUP)&)&&&& {&&&&&&&& if( reconnect &&&(client_term != VTUN_SIG_HUP)&)&{&......&}&&&&&& //重连&&&&&&& ......&&&&&&&& if( server_addr(&svr_addr, host)&&&0&)&&& continue;&&&&&&&&&&&&&&& // Set server address&&&&&&&&& &&&&&&& if( local_addr(&my_addr, host,&0)&&&0)&&& continue;&&&&&&&&&&&&&&& // Set local address&&&&& &&&&&&& if(&(s = socket(AF_INET,SOCK_STREAM,0))==-1&)&{&......&}&&&&&&& //建立socket套接字&&&&&&& opt=1;&&&&&&&& setsockopt(s, SOL_SOCKET, SO_REUSEADDR,&&opt,&sizeof(opt));&&&& // Required when client is forced to bind to specific port &&&&&&& if( bind(s,(struct sockaddr *)&my_addr,sizeof(my_addr))&){.....}//bind&&&&&&& host-&spd_in = host-&spd_out =&0;&&&&&&&& host-&flags &= VTUN_CLNT_MASK;&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& //Clear speed and flags which will be supplied by server.&&&&&&& io_init();&&&&&&&& ......&&&&&&&& if( connect_t(s,(struct sockaddr *)&&svr_addr, host-&timeout)&){.....}&&&&&&&& else&&&&&&&&& {&&&&&&&&&&&& if( auth_client(s,host))&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& //认证,也就是隧道建立过程&&&&&&&&&&& {&&&&&&&&&&&&&&&& ...&&&&&&&&&&&&&&&& client_term = tunnel(host);&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& //开启隧道,host是配置文件相应会话信息。&&&&&&&&&&&&&&& ...&&&&&&&&&&&& }&&&&&&&&&&&& else&&&&&&&&&&&& {&&&&&&&&&&&&&&&& ......&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& //认证失败&&&&&&&&&&& }&&&&&&&& }&&&&&&&& close(s);&&&&&&&& free_sopt(&host-&sopt);&&&& }//end while&&& ......}&/*****************************************************************************补充:在执行tunnel(host)前先来看看上面client函数中的connect_t函数。*原型:int connect_t(int s, struct sockaddr *svr, time_t timeout);*参数:s是client中建立的套接字描述符。*功能:与服务器建立连接。*****************************************************************************/int connect_t(int s,&struct sockaddr *svr, time_t timeout)&{#if defined(VTUN_SOCKS) && VTUN_SOCKS == 2&&&& /* Some SOCKS implementations don't support&&&&& * non blocking connect */&&&& return connect(s,svr,sizeof(struct sockaddr));#else&&& sock_flags=fcntl(s,F_GETFL);&&&& if( fcntl(s,F_SETFL,O_NONBLOCK)&&&0&)...//设置s为非阻塞?&&& if( connect(s,svr,sizeof(struct sockaddr))&&&0&&& errno != EINPROGRESS)...&&&& ......&&&& if( select(s+1,NULL,&fdset,NULL,timeout?&tv:NULL)&&&0&)&&&& {&&&&&&&& ...&&&&&&&& getsockopt(s,SOL_SOCKET,SO_ERROR,&errno,&l);//?&&& }&else&&&& errno=ETIMEDOUT;&&&&&& &&&& fcntl(s,F_SETFL,sock_flags);&&&&& ...#endif}//end connect_t&/**************************************************************************补充:在执行tunnel(host)前再来看看上面client函数中的auth_client.*原型:int auth_client(int fd, struct vtun_host *host);*参数:fd是client端创建的套接字描述符,host是配置文件中某个会话所包含的信息*功能:认证过程,也是隧道建立过程。**************************************************************************/int auth_client(int fd,&struct vtun_host *host){&&&& ......&&&& stage = ST_INIT;&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& //#define ST_INIT& 0&&& while( readn_t(fd, buf, VTUN_MESG_SIZE, vtun.timeout)&&&0&)&&&&&&& //读取服务器发来认证信息。&&& {&&&&&&&& buf[sizeof(buf)-1]='\0';&&&&&&&& switch( stage )&&&&&&&& {&&&&&&&&&&&& case ST_INIT:&&&&&&&&&&&&&&&& if(&!strncmp(buf,"VTUN",4)&)&&&&&&&&&&&&&&&& {&&&&&&&&&&&&&&&&&&&& stage = ST_HOST;&&&&&&&&&&&&&&&&&&&& print_p(fd,"HOST: %s\n",host-&host);&&&&&&&&&&& //print_p向server发送HOST:[host]。&&&&&&&&&&&&&&&&&&& continue;&&&&&&&&&&&&&&&& }&&&&&&&&&&&&&&&& break;&&&&&&&&&&&& case ST_HOST:&&&&&&&&&&&&&&&& if(&!strncmp(buf,"OK",2)&&& cs2cl(buf,chal))&&&&&&& //接收到请求发送密码信息 OK CHAL:[chal]&&&&&&&&&&&&&&& {&&&&&&&&&&&&&&&&&&&& stage = ST_CHAL;&&&&&&&&&&&&&&&&&&&& encrypt_chal(chal,host-&passwd);&&&&&&&&&&&&&&&&&&&& print_p(fd,"CHAL: %s\n", cl2cs(chal));&&&&&&&&&&& //发送配置文件中本次会话密码CHAL:[chal]&&&&&&&&&&&&&&&&&&& continue;&&&&&&&&&&&&&&&& }&&&&&&&&&&&&&&&& break;&&&&&&&&&&&& case ST_CHAL:&&& &&&&&&&&&&&&&&&& if(&!strncmp(buf,"OK",2)&&& cf2bf(buf,host)&)&&&&&&& //接收到OK FLAGS:[host]认证成功信息&&&&&&&&&&&&&&&&&&& success =&1;&&&&&&&&&&&&&&&& break;&&&&&&&& }&&&&&&&& break;&&&& }//end while&&& return success;}&/**************************************************************************原型:int tunnel(strucnt vtun_host* host);*参数:host是配置文件中某个会话所包含的信息*功能:开启隧道即初试话设备读写函数,初始化封装后发送接收所用协议。*下一步:linkfd(host);**************************************************************************/int tunnel(struct vtun_host *host){&&&& ......&&&& if&(&(host-&persist == VTUN_PERSIST_KEEPIF)&&&&(host-&loc_fd &=&0)&)&&& //接口是否已经打开&&&&&&& interface_already_open =&1;&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& &&&& if( host-&dev ){...}&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& //判断虚拟设备类型&&& if(!interface_already_open)&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& //虚拟网卡没有打开,则打开之&&& {&&&&&&&& ...&&&&&&&& switch(host-&flags & VTUN_TYPE_MASK)&&&&&&&& {&&&&&&&&&&&& ...&&&&&&&&&&&& case VTUN_TUN:&&&&&&&&&&&&&&&& if(&(fd[0]=tun_open(dev))&&&0&)&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& //打开虚拟网卡,获取描述符&&&&&&&&&&&&&&& {&&&&&&&&&&&&&&&&&&&& vtun_syslog(LOG_ERR,"Can't allocate tun device %s. %s(%d)", dev, strerror(errno), errno);&&&&&&&&&&&&&&&&&&&& return&-1;&&&&&&&&&&&&&&&& }&&&&&&&&&&&&&&&& break;&&&&&&&& }&&&&&&&& host-&loc_fd = fd[0];&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& //虚拟设备文件描述符存在host-&loc_fd中&&& }&&&& switch( host-&flags & VTUN_PROT_MASK )&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& //初始化协议,tcp还是udp&&& {&&&&&&&& ......&&&&&&&& case VTUN_UDP:&&&&&&&&&&&& if(&(opt = udp_session(host))&==&-1){.....}&&&&&&&&&&&&&&&&&&&&&&& //进行udp的socket创建等操作&&&&&&&&&&& proto_write = udp_write;&&&&&&&&&&&& proto_read = udp_read;&&&& }&&&& switch(&(pid=fork())&){...}&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& //建立子进程&&& switch( host-&flags & VTUN_TYPE_MASK )&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& //根据虚拟设备类型,选择相应虚拟设备读写方式&&& {&&&&&&&& .....&&&&&&&& case VTUN_TUN:&&&&&&&&&&&& set_title("%s tun %s", host-&host, dev);&&&&&&&&&&&& dev_read& = tun_read;&&&&&&&&&&&& dev_write = tun_write;&&&&&&&&&&&& break;&&&& }&&&& opt = linkfd(host);&&&&&&&&&&&&&&&&&&&&&&& &&&& .......}&/**************************************************************************补充:在linkfd之前,我们先来看看tunnel函数中udp_session.*原型:int udp_session(struct vtun_host *host);*参数:host是配置文件中某个会话所包含的信息。*功能:udp socket的创建、bind、connect等。**************************************************************************/int udp_session(struct vtun_host *host)&{&&&& struct sockaddr_in saddr;&&&&& short port;&&&& int s,opt;&&&& extern&int is_rmt_fd_connected;&&&&& if(&(s=socket(AF_INET,SOCK_DGRAM,0))==&-1&)&&&&& {&&&&&&& vtun_syslog(LOG_ERR,"Can't create socket");&&&&&&& return&-1;&&&& }&&&&& opt=1;&&&& setsockopt(s, SOL_SOCKET, SO_REUSEADDR,&&opt,&sizeof(opt));&&&& &&&& /* Set local address and port */&&&& local_addr(&saddr, host,&1);&&&& if( bind(s,(struct sockaddr *)&saddr,sizeof(saddr))&){&&&&&&& vtun_syslog(LOG_ERR,"Can't bind to the socket");&&&&&&& return&-1;&&&& }&&&&& opt =&sizeof(saddr);&&&& if( getsockname(s,(struct sockaddr *)&saddr,&opt)&){&&&&&&& vtun_syslog(LOG_ERR,"Can't get socket name");&&&&&&& return&-1;&&&& }&&&&& /* Write port of the new UDP socket */&&&& port = saddr.sin_port;&&&& if( write_n(host-&rmt_fd,(char&*)&port,sizeof(short))&&&0&){&&&&&&& vtun_syslog(LOG_ERR,"Can't write port number");&&&&&&& return&-1;&&&& }&&&& host-&sopt.lport = htons(port);&&&&& /* Read port of the other's end UDP socket */&&&& if( readn_t(host-&rmt_fd,&port,sizeof(short),host-&timeout)&&&0&){&&&&&&& vtun_syslog(LOG_ERR,"Can't read port number %s", strerror(errno));&&&&&&& return&-1;&&&& }&&&&& opt =&sizeof(saddr);&&&& if( getpeername(host-&rmt_fd,(struct sockaddr *)&saddr,&opt)&){&&&&&&& vtun_syslog(LOG_ERR,"Can't get peer name");&&&&&&& return&-1;&&&& }&&&&& saddr.sin_port = port;&&&&& /* if the config says to delay the UDP connection, we wait for an&&&& incoming packet and then force a connection back.& We need to&&&& put this here because we need to keep that incoming triggering&&&& packet and pass it back up the chain. */&&&&& if&(VTUN_USE_NAT_HACK(host))&&&&&&&&& is_rmt_fd_connected=0;&&&& else&&&& {&&&&&&&&& if( connect(s,(struct sockaddr *)&saddr,sizeof(saddr))&)&&&&&&&&& {&&&&&&&&&&&&& vtun_syslog(LOG_ERR,"Can't connect socket");&&&&&&&&&&&&& return&-1;&&&&&&&&& }&&&&&&&&& is_rmt_fd_connected=1;&&&& }&&&& &&&& host-&sopt.rport = htons(port);&&&&& /* Close TCP socket and replace with UDP socket */&&& &&&& close(host-&rmt_fd);&&&&& host-&rmt_fd = s;&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& //将TCP套接字替换为UDP套接字。&&&&& vtun_syslog(LOG_INFO,"UDP connection initialized");&&&& return s;}&/**************************************************************************原型:int linkfd(struct vtun_host *host);*参数:host是配置文件中某个会话所包含的信息。*功能:初始化加密解密压缩解压模块。*下一步:虚拟网卡读写以及数据的接收发送lfd_linker();**************************************************************************/int linkfd(struct vtun_host *host)&&&&&&& {&&&& ......&&&& lfd_host = host;&&&& old_prio=getpriority(PRIO_PROCESS,0);&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& //取得进程优先级&&& setpriority(PRIO_PROCESS,0,LINKFD_PRIO);&&&& ......&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& //Build modules stack加密压缩等。&&& ......&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& //结束进程等信号处理函数。&&& io_init();&&&& lfd_linker();&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& //虚拟网卡读写,封装解封以及发送。&&& ......&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& //闹钟信号等。}&/**************************************************************************原型:int lfd_linker(void)&&&& *功能:虚拟网卡读写以及数据的接收发送lfd_linker();*下一步:结束。**************************************************************************/int lfd_linker(void)&&&&&&&&&&& {&&&& int fd1 = lfd_host-&rmt_fd;&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& //fd1是网络套接字描述符,也就是最后封装发送的那个套接字描述符。&&& int fd2 = lfd_host-&loc_fd;&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& //fd2是虚拟网卡设备文件描述符。&&& ......&&&& /* Delay sending of first UDP packet over broken NAT routers&&&& because we will probably be disconnected.& Wait for the remote&&&& end to send us something first, and use that connection. */&&&& if&(!VTUN_USE_NAT_HACK(lfd_host))&&&&&&&&&&& //?&&&&&&& proto_write(fd1, buf, VTUN_ECHO_REQ);&&&& ......&&&& while(&!linker_term )&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& //while循环体从虚拟网卡读数据后发送;将接收的数据写入虚拟网卡。&&& {&&&&&&&& ......&&&&&&&& FD_ZERO(&fdset);&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& //等待数据&&&&&&& FD_SET(fd1,&&fdset);&&&&&&&& FD_SET(fd2,&&fdset);&&&&&&&& tv.tv_sec& = lfd_host-&ka_interval;&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& //非阻塞超时时间&&&&&&& tv.tv_usec =&0;&&&&&&&& if(&(len = select(maxfd,&&fdset,&NULL,&NULL,&&tv))&&&0&){...}&&& //select非阻塞监控&&&&&&& if( ka_need_verify )&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& //ka_need_verify和信号处理函数有关&&&&&&& {&&&&&&&&&&&& ...&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& //No input frames, check connection with ECHO,没输入信息,发送请求信息。&&&&&&& }&&&&&&&& if( send_a_packet )&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& //默认为0不加密&&&&&&& {&&&&&&&&&&&& ...//加密发送&&&&&&& }&&&&&&&& if( FD_ISSET(fd1,&fdset)&&& lfd_check_up()&)&&&&&&&&&&&&&&&&&&& //网络套接字fd1是否有数据到达,加解密模块是否准备就绪。&&&&&&& {&&&&&&&&&&&& ....&&&&&&&&&&&& if(&(len=proto_read(fd1, buf))&&=&0&)...&&&&&&&&&&&&&&&&&&& //接收网络中数据存到buf&&&&&&&&&&& fl = len &&~VTUN_FSIZE_MASK;&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& //获取帧标志&&&&&&&&&&& len = len & VTUN_FSIZE_MASK;&&&&&&&&&&&& if( fl )&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& // fl即frame flags帧标志&&&&&&&&&&& {&&&&&&&&&&&&&&&& ...&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& //判断是何种帧,即判断接收到数据的类型请求、应答、坏帧、关闭&。&&&&&&&&&&& }&&&&&&&&&&&& if(&(len=lfd_run_up(len,buf,&out))&==&-1&)...&&&&&&&&&&&&&&& //解密&&&&&&&&&&& if( len && dev_write(fd2,out,len)&&&0&)&&&&&&&&&&&& {&&&&&&&&&&&&&&&& ...&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& //将网络套接字fd1的数据写入虚拟网卡fd2。&&&&&&&&&&& }&&&&&&&& }&&&&&&&& if( FD_ISSET(fd2,&&fdset)&&& lfd_check_down()&)&&&&&&&&&&&&&&&&&&& //虚拟网卡中是否有数据,加解密模块是否就绪。&&&&&&& {&&&&&&&&&&&& if(&(len = dev_read(fd2, buf, VTUN_FRAME_SIZE))&&&0&)&&&&&&&&&&&& {&&&&&&&&&&&&&&&& ...&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& //读取虚拟网卡中数据&&&&&&&&&&& }&&&&&&&&&&&& if(&(len=lfd_run_down(len,buf,&out))&==&-1&)...&&&&&&&&&&&&&&& //加密&&&&&&&&&&& if( len && proto_write(fd1, out, len)&&&0&)&&&&&&&&&&&& {&&&&&&&&&&&&&&&& ...&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& //将虚拟网卡fd2中数据通过网络套接字fd1发送。&&&&&&&&&&& }&&&&&&&&&&&& ...&&&&&&&& }&&&&&&&& ...&&&&&&& &&&& }//end while&&& ...&&&& proto_write(fd1, buf, VTUN_CONN_CLOSE);&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& //通知其他终端本终端连接关闭&&& ...&&&& return&0;}&&&&/*********************************************** server端代码执行基本流程分析 ************************************************//*****************************************************************原型:int main(int argc, char* argv[], char* env[]);*功能:初始化操作,确定是client端还是server端。*下一步:根据命令行参数选择执行client或者server分支,分析server。*****************************************************************/int main(int argc,&char&*argv[],&char&*env[]){&&&& ......&&&& ......//初始化vtun结构体。&&& while(&(opt=getopt(argc,argv,"misf:P:L:t:npq"))&!= EOF )&//获取命令行参数并进行相应操作。&&& {&&&&&&&& ......&&&& }&&&& reread_config(0);&&&&&&&&&&&& //读配置文件。&&& ......&&&& clear_nat_hack_flags(svr);&&&&& //?&&& if(!svr)&&&&&&&&&&&&&&&&&&& //如果不是服务器,再根据命令行参数进行配置。&&& {&&&&&&&& ......&&&&&&&& hst = argv[optind++];&&& //vtund server [ip]的第二个参数给hst,这个参数是服务器给客户端定义的名字。&&&&&&& host = find_host(hst);& //hst是命令行参数,host是配置文件中的对应该参数的会话信息。&&&&&&& ......&&&& }&&&& vtun.svr_name = strdup(argv[optind]);//vtund server [ip]的ip给vtun.srv_name&&& ......&&&&&&&&&&&&&&&&&&&&&&& //如果vtun结构体的一些成员没有被初试话,则赋予默认值。&&& switch( vtun.svr_type )&&&&& //判断vtun的类型,VTUN_STAND_ALONE VTUN_INETD.&&& {&&&&&&&& ......&&&& }&&&& if( daemon )&&&&&&&&&&&&&&& //是否要创建守护进程&&& {&&&&&&&& if( dofork && fork()&)& &&&&&&&& ...&&&& }&&&& if(svr)&&&& {&&&&&&&& memset(&sa,0,sizeof(sa));&&&&&&&&&&&&&&& //挂起时读取配置文件。&&&&&&& sa.sa_handler=reread_config;&&&&&&&& sigaction(SIGHUP,&sa,NULL);&&&&&&&&& init_title(argc,argv,env,"vtund[s]: ");&&&&&&&&& if( vtun.svr_type == VTUN_STAND_ALONE )&&&&&&&&&&& write_pid();&&&&&&&&&&&&&&&&&&&&&&&&&&& &&&&&&&&& server(sock);&&&&&&&&&&&&&&&&&&&&&&&&&&& //执行服务器操作&&& }&else&{&&&&&&&& init_title(argc,argv,env,"vtund[c]: ");&&&&&&&& client(host);&&&&&&&&&&&&&&&&&&&&&&&&&&& //执行客户端操作,host就是从配置文件读取出的对应命令行参数会话名的信息。&&& }&&&& ......}&/*************************************************************原型:void server(int sock);*参数:sock = 0.*功能:建立socket以及bind、connect、select等,认证暨建立隧道。*下一步:根据守护进程类型选择执行listener还是connection。*************************************************************/void server(int sock)&&&&&&& {&&&& struct sigaction sa;&&&&&&&&&&&&&&& //忽略接收进程信号。&&& sa.sa_handler=SIG_IGN;&&&& sa.sa_flags=SA_NOCLDWAIT;;&&&& sigaction(SIGINT,&sa,NULL);&&&& sigaction(SIGQUIT,&sa,NULL);&&&& sigaction(SIGCHLD,&sa,NULL);&&&& sigaction(SIGPIPE,&sa,NULL);&&&& sigaction(SIGUSR1,&sa,NULL);&&&& vtun_syslog(LOG_INFO,"VTUN server ver %s (%s)", VTUN_VER, vtun.svr_type == VTUN_INETD ?&"inetd"&:&"stand"&);&&&& switch( vtun.svr_type )&&&&&&&&&&&&&&& //判断sever端的类型独立启动守护进程or超级守护进程。&&& {&&&&&&&& case VTUN_STAND_ALONE:&&&&&&&&&&& //独立启动守护进程&&&&&&&&&&& listener();&&&&&&&&&&&&&&&&&&& //开始监听&&&&&&& break;&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& //超级守护进程没有socket、bind、listen、accept过程(inetd实现该过程),而是直接读写开始。&&&&&&& case VTUN_INETD:&&&&&&&&&&&&&&& //守护进程&&&&&&&&&&& connection(sock);&&&&&&&&&&& &&&&&&&& break;&&&& }}&/*************************************************************这里分析独立守护进程时的操作。*原型:void listener(void);*功能:建立socket、bind、listen、accept、connection等。*下一步:connection。*************************************************************/void listener(void){&&&& ...&&&&&&&&&&&&&&& &&&& if( generic_addr(&my_addr,&&vtun.bind_addr)&&&0)&...&&&&&&&&&&& //设置监听地址&&& if(&(s=socket(AF_INET,SOCK_STREAM,0))==&-1&)...&&&&&&&&&&&&&&&&&&& //创建socket&&& opt=1;&&&& setsockopt(s, SOL_SOCKET, SO_REUSEADDR,&&opt,&sizeof(opt));&&&& if( bind(s,(struct sockaddr *)&my_addr,sizeof(my_addr))&)...&&& //bind&&& if( listen(s,&10)&)...&&&& ...&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& //信号处理,防止僵尸进程&&& while(&(!server_term)&||&(server_term == VTUN_SIG_HUP)&)&&&&&&& &&&& {&&&&&&&& //注意这个循环条件要和linkfd里的循环条件结合起来,这里的循环条件实际是挂起状态才执行该循环,&&&&&&& //而不是没有结束循环或者挂起状态二者满足其一执行循环!&&&&&&& if(&(s1=accept(s,(struct sockaddr *)&cl_addr,&opt))&&&0&)..&&& //accept&&&&&&& switch( fork()&)&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& //创建子进程&&&&&&& {&&&&&&&&&&&& case&0:&&&&&&&&&&&&&&&& close(s);&&&&&&&&&&&&&&&& connection(s1);&&& //和client建立连接,s1是accept返回的已连接套接字描述符(表示此次TCP三次握手连接成功)。&&&&&&&&&&&&&&& break;&&&&&&&&&&&& case&-1:&&&&&&&&&&&&&&&& vtun_syslog(LOG_ERR,&"Couldn't fork()");&&&&&&&&&&&& default:&&&&&&&&&&&&&&&& close(s1);&&&&&&&&&&&&&&&& break;&&&&&&&& }&&&& }}&/*************************************************************原型:void connection(int sock);*参数:注意这里的sock是已连接套接字描述符。*功能:建立socket、bind、listen、accept、connection等。*下一步:认证成功后开启隧道即执行tunnel。*************************************************************/void connection(int sock)&&&&&&&&&&& //sock是已连接套接字描述符,和server端监听套接字描述符不同。{&&&& if( getpeername(sock,&(struct sockaddr *)&&cl_addr,&&opt)&)...//获取client端地址&&& ...&&&& if( getsockname(sock,&(struct sockaddr *)&&my_addr,&&opt)&&&0&)...&&&& ...&&&& io_init();&&&& if(&(host=auth_server(sock))&)&&& //认证&&& {&&&&&&&& ...&&&&&&& //忽略挂起信号&&&&&&& ...&&&&&&& //设置host的一些成员&&& }&&&& tunnel(host);&&&&&&&&&&&&&&&&&&& //开启隧道。&&& ......}&/*************************************************************************补充:在开启隧道之前先来看看上面函数涉及的server端认证auth_server(sock);*原型:void connection(int sock);*参数:注意这里的sock是已连接套接字描述符。*功能:建立socket、bind、listen、accept、connection等。*************************************************************************/struct vtun_host * auth_server(int fd){&&&& ......&&&& while( readn_t(fd, buf, VTUN_MESG_SIZE, vtun.timeout)&&&0&)&&&&&&& //接收来自客户端的认证信息。&&& {&&&&&&&& ...&&&&&&&& switch( stage )&&&&&&&& {&&&&&&&&&&&& case ST_HOST:&&&&&&&&&&&&&&&& if(&!strcmp(str1,"HOST")&)&&&&&&&&&&&&&&&&&&&&&&&&&&& //接收来自client的HOST:[host]&&&&&&&&&&&&&&& {&&&&&&&&&&&&&&&&&&&& host = strdup(str2);&&&&&&&&&&&&&&&&&&&& gen_chal(chal_req);&&&&&&&&&&&&&&&&&&&& print_p(fd,"OK CHAL: %s\n", cl2cs(chal_req));&&& //发送请求发送秘密信息OK CHAL:[chal]&&&&&&&&&&&&&&&&&&& stage = ST_CHAL;&&&&&&&&&&&&&&&&&&&& continue;&&&&&&&&&&&&&&&& }&&&&&&&&&&&&&&&& break;&&&&&&&&&&&& case ST_CHAL:&&&&&&&&&&&&&&&&& if(&!strcmp(str1,"CHAL")&)&&&&&&&&&&&&&&&&&&&&&&&&&&& //接收密码&&&&&&&&&&&&&&&& {&&&&&&&&&&&&&&&&&&&&& if(&!cs2cl(str2,chal_res)&)&&&&&&&&&&&&&&&&&&&&&&&&& break;&&&&&&&&&&&&&&&&&&&&& if(&!(h = find_host(host))&)&&&&&&&&&&&&&&&&&&&&&&&&& break;&&&&&&&&&&&&&&&&&&&&& decrypt_chal(chal_res, h-&passwd);&&&&&&&&&&&&&&&&&&&&& if(&!memcmp(chal_req, chal_res, VTUN_CHAL_SIZE)&)&&& //与配置文件中密码比较&&&&&&&&&&&&&&&&&&&& {&&&&&&&&&&&&&&&&&&&&&&&& /* Auth successeful. */&&&&&&&&&&&&&&&&&&&&&&&& /* Lock host */&&&&&&&&&&&&&&&&&&&&&&&& if( lock_host(h)&&&0&)&&&&&&&&&&&&&&&&&&&&&&&& {&&&&&&&&&&&&&&&&&&&&&&&&&&&& /* Multiple connections are denied */&&&&&&&&&&&&&&&&&&&&&&&&&&&& h =&NULL;&&&&&&&&&&&&&&&&&&&&&&&&&&&& break;&&&&&&&&&&&&&&&&&&&&&&&& }&&&&&&&&&&&&&&&&&&&&&&&& print_p(fd,"OK FLAGS: %s\n", bf2cf(h));&&&&&&&&&&& //发送成功信息OK FLAGS:[host]&&&&&&&&&&&&&&&&&&&& }&&&&&&&&&&&&&&&&&&&&& else&&&&&&&&&&&&&&&&&&&&&&&&& h =&NULL;&&&&&&&&&&&&&&&& }&&&&&&&&&&&&&&&&& break;&&&&&&&& }//end switch&&&&&& break;&&&& }//end while&&& ......}&/**************************************************************************原型:int tunnel(strucnt vtun_host* host);*参数:host是配置文件中某个会话所包含的信息*功能:开启隧道即初试话设备读写函数,初始化封装后发送接收所用协议。*下一步:linkfd(host);**************************************************************************/int tunnel(struct vtun_host *host){&&&& ......&&&& ......&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& //接口是否打开&&& if( host-&dev ){...}&&&&&&&&&&&&&&&&&&&&& //判断虚拟设备类型&&& if(!interface_already_open)&&&&&&&&&&&&&&& //获取虚拟设备文件描述符&&& {&&&&&&&& ...&&&&&&&& host-&loc_fd = fd[0];&&&&&&&&&&&&&&& //虚拟设备文件描述符存在host-&loc_fd中&&& }&&&& switch( host-&flags & VTUN_PROT_MASK )&&& //初始化协议,tcp还是udp&&& {&&&&&&&& ......&&&&&&&& case VTUN_UDP:&&&&&&&&&&&& if(&(opt = udp_session(host))&==&-1){.....}&&&&&&& //进行udp的socket创建等操作&&&&&&&&&&& proto_write = udp_write;&&&&&&&&&&&& proto_read = udp_read;&&&& }&&&& switch(&(pid=fork())&){...}&&&&&&&&&&&&&&& &&&& switch( host-&flags & VTUN_TYPE_MASK )&&& //根据虚拟设备类型,选择相应虚拟设备读写方式,&&& {&&&&&&&& .....&&&&&&&& case VTUN_TUN:&&&&&&&&&&&& set_title("%s tun %s", host-&host, dev);&&&&&&&&&&&& dev_read& = tun_read;&&&&&&&&&&&& dev_write = tun_write;&&&&&&&&&&&& break;&&&& }&&&& opt = linkfd(host);&&&& .......}&/**************************************************************************原型:int linkfd(struct vtun_host *host);*参数:host是配置文件中某个会话所包含的信息*功能:初始化加密解密压缩解压模块。*下一步:虚拟网卡读写以及数据的接收发送lfd_linker();**************************************************************************/int linkfd(struct vtun_host *host)&&&&&&& //链接虚拟网卡文件描述符和封装后用于发送接收的套接字描述符。{&&&& ......&&&& lfd_host = host;&&&& old_prio=getpriority(PRIO_PROCESS,0);&&& &&&& setpriority(PRIO_PROCESS,0,LINKFD_PRIO);&&&& ......&&&&&&&&&&&&&&&&&&&&&&& //Build modules stack加密压缩等。&&& ......&&&&&&&&&&&&&&&&&&&&&&& //结束进程等信号处理函数。&&& io_init();&&&& lfd_linker();&&&&&&&&&&&&&&& //虚拟网卡读写,封装解封以及发送。&&& ......&&&&&&&&&&&&&&&&&&&&&&& //闹钟信号等。}&/**************************************************************************原型:int lfd_linker(void)&&&& *功能:虚拟网卡读写以及数据的接收发送lfd_linker();*下一步:结束。**************************************************************************/int lfd_linker(void)&&&&&&&&&&& {&&&& int fd1 = lfd_host-&rmt_fd;&&&&&&&&&&& //fd1是网络套接字描述符,也就是最后封装发送的那个套接字描述符。&&& int fd2 = lfd_host-&loc_fd;&&&&&&&&&&& //fd2是虚拟网卡设备文件描述符。&&& ......&&&& /* Delay sending of first UDP packet over broken NAT routers&&&& because we will probably be disconnected.& Wait for the remote&&&& end to send us something first, and use that connection. */&&&& if&(!VTUN_USE_NAT_HACK(lfd_host))&&&&&&&&&&& //?&&&&&&& proto_write(fd1, buf, VTUN_ECHO_REQ);&&&& ......&&&& while(&!linker_term )//while循环体从虚拟网卡读数据后发送;将接收的数据写入虚拟网卡。&&& {&&&&&&&& ......&&&&&&&& FD_ZERO(&fdset);&&&&&&&&&&&&&&&&&&&&&&& //等待数据&&&&&&& FD_SET(fd1,&&fdset);&&&&&&&& FD_SET(fd2,&&fdset);&&&&&&&& tv.tv_sec& = lfd_host-&ka_interval;&&&&&&& //非阻塞超时时间&&&&&&& tv.tv_usec =&0;&&&&&&&& if(&(len = select(maxfd,&&fdset,&NULL,&NULL,&&tv))&&&0&){...}&&& //select非阻塞监控&&&&&&& if( ka_need_verify )&&&&&&&&&&&&&&&&&&& //ka_need_verify和信号处理函数有关&&&&&&& {&&&&&&&&&&&& ...//No input frames, check connection with ECHO,没输入信息,发送请求信息。&&&&&&& }&&&&&&&& if( send_a_packet )&&&&&&&&&&&&&&&&&&&&&&& //默认为0不加密&&&&&&& {&&&&&&&&&&&& ...//加密发送&&&&&&& }&&&&&&&& if( FD_ISSET(fd1,&fdset)&&& lfd_check_up()&)&&& //网络套接字fd1是否有数据到达,加解密模块是否准备就绪。&&&&&&& {&&&&&&&&&&&& ....&&&&&&&&&&&& if(&(len=proto_read(fd1, buf))&&=&0&)...&&& //接收网络中数据存到buf&&&&&&&&&&& fl = len &&~VTUN_FSIZE_MASK;&&&&&&&&&&&&&&& //获取帧标志&&&&&&&&&&& len = len & VTUN_FSIZE_MASK;&&&&&&&&&&&& if( fl )&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& // fl即frame flags帧标志&&&&&&&&&&& {&&&&&&&&&&&&&&&& ...//判断是何种帧,即判断接收到数据的类型请求、应答、坏帧、关闭&。&&&&&&&&&&& }&&&&&&&&&&&& if(&(len=lfd_run_up(len,buf,&out))&==&-1&)...//解密&&&&&&&&&&& if( len && dev_write(fd2,out,len)&&&0&)&&&&&&&&&&&& {&&&&&&&&&&&&&&&& ...//将网络套接字fd1的数据写入虚拟网卡fd2。&&&&&&&&&&& }&&&&&&&& }&&&&&&&& if( FD_ISSET(fd2,&&fdset)&&& lfd_check_down()&)&&& //虚拟网卡中是否有数据,加解密模块是否就绪。&&&&&&& {&&&&&&&&&&&& if(&(len = dev_read(fd2, buf, VTUN_FRAME_SIZE))&&&0&)&&&&&&&&&&&& {&&&&&&&&&&&&&&&& ...//读取虚拟网卡中数据&&&&&&&&&&& }&&&&&&&&&&&& if(&(len=lfd_run_down(len,buf,&out))&==&-1&)...//加密&&&&&&&&&&& if( len && proto_write(fd1, out, len)&&&0&)&&&&&&&&&&&& {&&&&&&&&&&&&&&&& ...//将虚拟网卡fd2中数据通过网络套接字fd1发送。&&&&&&&&&&& }&&&&&&&&&&&& ...&&&&&&&& }&&&&&&&& ...&&&&&&& &&&& }//end while&&& ...&&&& proto_write(fd1, buf, VTUN_CONN_CLOSE);&&&&&&&&&&& //通知其他终端本终端连接关闭&&& ...&&&& return&0;}
阅读排行榜

我要回帖

更多关于 sf是什么游戏 的文章

 

随机推荐