[中秋零献续集] 神州数码802.1x局域网UDP拔号软件MyNet-Gnome源代码大分析(Part4)getaccess线程内的故事
/***
* Author: cc0cc
* E-mail: cc0cc@126.com
* WebSite: http://www.54chen.com * Date: 11 01 2008
* FileName: Mythread.c
* 这个文件要从Access_Thread看起,因为在上一章节里,我们了解了 pthread_create(&getaccess,NULL,Access_Thread,NULL);创建了一个叫getaccess的线程,正是运行的Access_Thread,在Access_Thread里,将完成一系列的过程,802.1x从这里才真正开始了。
***/
#include <gnome.h>
#include <sys/select.h>
#include “Mythread.h”
#include “connect.h”
#include “support.h”
#include “interface.h”
int i=0;
typedef struct{
long tv_sec;
long tv_uec;
}timeval;
gint
keeplink(gpointer data)
{ pthread_t keeptest;
fd_set readfds;
timeval timeout={5,0};//设置超时
BYTE recvbuf[1024];
BYTE cmd;
CMD_RECORD *cmd_record;
int recvlen;
int index=0;
BYTE tmp=0;
send_keeplink_request();//这也在connect.c里,用来构造一个包含指令和验证信息的包并发给服务器
FD_ZERO(&readfds);
FD_SET(sockfd, &readfds);
if(1!=select(sockfd + 1,&readfds,NULL,NULL,&timeout))
{//超时
Acc_Keep_Link=2;
g_message(“1.keep lost,thread keeptest ok!");
pthread_create(&keeptest,NULL,Keep_Thread,NULL);
return FALSE;
}
recvlen=recvfrom(sockfd,(char *)recvbuf,sizeof(recvbuf),0,NULL,NULL);
if (recvlen==-1 ) {
Acc_Keep_Link=2;
pthread_create(&keeptest,NULL,Keep_Thread,NULL);
g_message(“2.keep lost,thread keeptest ok!");
return FALSE;
}
amt_decrypt(recvbuf,recvlen);//与认证过程大同小异
if(0==check_packet(recvbuf,recvlen))
{
Acc_Keep_Link=2;
pthread_create(&keeptest,NULL,Keep_Thread,NULL);
g_message(“3.keep lost,thread keeptest ok!");
return FALSE;
}
cmd_record=get_attr(recvbuf);
cmd=*recvbuf;
if(cmd==4) //收到send_keeplink_request对应的包
{
index=0;
tmp=0;
for (;(index<8)&&(attr_id[index]);index++) {
if (attr_id[index]==3) {
if (attr_val[8*(index+4*index)]!=1) {//发送send_keeplink_request失败
Acc_Keep_Link=2;
pthread_create(&keeptest,NULL,Keep_Thread,NULL);
g_message(“4.keep lost,thread keeptest ok!");
return FALSE;
}
}
}
//AfxGetMainWnd()->PostMessage(WM_KEEPLINK_RESULT,KEEPLINK_SUCCESSED,NULL);
g_message(“keeplink result success”);
}
else
{
Acc_Keep_Link=2;
pthread_create(&keeptest,NULL,Keep_Thread,NULL);
g_message(“5.keep lost,thread keeptest ok!");
return FALSE;
}
return TRUE;//至此 全过程结束(当然,你不是按照从上到下读着来的,而是按照我的提示来阅读的话) 未来我会逐步分析connect.c和mdd.c里的几个函数,都是加密和解密的内容,主程序本身的流程关系不大,其中还包含了linux c中使用ASM的方法,敬请关注http://hi.baidu.com/cc0cc
}
void
Link_Thread(void *arg)
{ guint send_timer;
if(Acc_Keep_Link!=1)return;
g_message(“keep thread online!");
send_timer=gtk_timeout_add(30000,keeplink,NULL);//802.1x了,每三十秒发送一个认证请求 看keeplink
} 从这里看起↓ void
Access_Thread()
{ if(Acc_Keep_Link!=0)return;//这是个全局的标,任何情况下标被修改都应当退出线程
pthread_t keeplink;//这是一个孙线程的名字,根据协议规则需要在认证通过后定时发包
int times=0;//超时次数
fd_set readfds;//这个东东不知道要去补一下网络编程,异步套接字。文件描述符集,select调用时用的 timeval timeout;//设置超时为5秒 这个timeval struct在本文件有定义
timeout.tv_sec=5;
timeout.tv_uec=0;
FD_ZERO(&readfds);
FD_SET(sockfd, &readfds);
BYTE recvbuf[1024];
BYTE cmd;
CMD_RECORD *cmd_record;
int recvlen;
int index=0;
BYTE tmp=0;
retry://这里没办法,用了个goto 看后面就知道了,大概就是超时两次就置标志位了,最后结束运行
if (times>=2) {
Acc_Keep_Link=-1;//ACCESS_FAILED_TIMEOUT;
return ;
}
send_access_request();//这是开始发送包给服务器了,将会发送用户名密码MAC等一系列的东西给远端的服务器,另一个文件中(connet.c)将专门来介绍
int rt=select(sockfd + 1,&readfds,NULL,NULL,&timeout);//等着看有没有返回
//g_message(“select id :%d”,rt);
if(1!=rt)
{//超时
g_message(“time out this”);
times++;
goto retry;
}
//有返回了!
recvlen=recvfrom(sockfd,(char *)recvbuf,sizeof(recvbuf),0,NULL,NULL);//接受返回
if (recvlen==-1) {
g_message(“recvfrom faild”);
}
amt_decrypt(recvbuf,recvlen);//将收到的recvbuf里的东西去解密 amt_decrypt是原程序中的解密算法,接收到的数据包得经过本函数解密,将在mdd.c中介绍
if(check_packet(recvbuf,recvlen)==0&×<2)//check_packet检查解密amt_decrypt完后的数据包是否符合md5摘要
{ g_message(“check_packet bad here”);
times++;
goto retry;//check_packet失败则重发数据包
}
cmd_record=get_attr(recvbuf);//取出对应的指令变成结构体链表CMD_RECORD
cmd=*recvbuf;
if(cmd==2) //收到send_access_request对应的包
{
get_spec_attr(cmd_record);//把结构体链表CMD_RECORD里的东西分进全局变量attr_yy里 马上就要用到,attr_id存了cmd指令
index=0;
tmp=0;
for (;(index<0x0A)&&(attr_id[index]!=0);index++) {
if (attr_id[index]==3) {
tmp=attr_val[8*(index+4*index)];////attr_val给每个命令40字节
}
}
if (tmp==1) {//认证成功!
//g_message(“ok”);
gtk_widget_hide_all (linkwindow);
Acc_Keep_Link=1;
pthread_create(&keeplink,NULL,Link_Thread,NULL);//认证成功了,再创建一个线程用来保持连接 这回要去看Link_Thread了
return;
}
else
{ g_message(“server_back_err”);
gtk_widget_hide_all (linkwindow);
Acc_Keep_Link=-1;
return ;
}
}
}
gint
keeptest(gpointer data)
{ pthread_t keeplink;
i++;
g_message("%d”,i);
if (i>10){Acc_Keep_Link=-1;g_message(“can’t keeplink!");return FALSE;}
fd_set readfds;
timeval timeout={5,0};//设置超时
BYTE recvbuf[1024];
BYTE cmd;
CMD_RECORD *cmd_record;
int recvlen;
int index=0;
BYTE tmp=0;
send_keeplink_request();
FD_ZERO(&readfds);
FD_SET(sockfd, &readfds);
if(1!=select(sockfd + 1,&readfds,NULL,NULL,&timeout))
{//超时
g_message(“1.keep lost,thread keeptest for once!");
return TRUE;
}
recvlen=recvfrom(sockfd,(char *)recvbuf,sizeof(recvbuf),0,NULL,NULL);
if (recvlen==-1 ) {
g_message(“2.keep lost,thread keeptest for once!");
return TRUE;
}
amt_decrypt(recvbuf,recvlen);
if(0==check_packet(recvbuf,recvlen))
{
g_message(“3.keep lost,thread keeptest for once!");
return TRUE;
}
cmd_record=get_attr(recvbuf);
cmd=*recvbuf;
if(cmd==4) //收到send_keeplink_request对应的包
{
index=0;
tmp=0;
for (;(index<8)&&(attr_id[index]);index++) {
if (attr_id[index]==3) {
if (attr_val[8*(index+4*index)]!=1) {//发送send_keeplink_request失败
g_message(“4.keep lost,thread keeptest for once!");
return TRUE;
}
}
}
g_message(“keeptest result success”);
Acc_Keep_Link=1;
pthread_create(&keeplink,NULL,Link_Thread,NULL);
return FALSE;
}
else
{
g_message(“5.keep lost,thread keeptest for once!");
return TRUE;
}
return FALSE;
}
void
Keep_Thread()
{guint send_timer;
if(Acc_Keep_Link!=2)return;
send_timer=gtk_timeout_add(10000,keeptest,NULL);
} /***
* Author: cc0cc
* E-mail: cc0cc@126.com
* WebSite: http://www.54chen.com * Date: 11 01 2008
* FileName: Mythread.c
***/
原创文章如转载,请注明:转载自五四陈科学院[http://www.54chen.com]
Posted by 54chen linux
« [中秋零献] 神州数码802.1x局域网UDP拔号软件MyNet-Gnome源代码大分析(Part3)关键逻辑 perl笔记 »