📄 gap_b3.cpp
字号:
/*
gcc -Wall -g `libnet-config --defines` gap.c -o gap `libnet-config --libs` -pthread -lpcap
gcc -DDEBUG -Wall -g `libnet-config --defines` gap.c -o gap `libnet-config --libs` -pthread -lpcap
*/
/*-------------------------------------------------------------
04-04-21 每次发送超时时,都发送一个ack.防止ack丢失
--------------------------------------------------------------*/
#include "stdafx.h"
#include "gap_b3.h"
#define LIBNET_ERRBUF_SIZE 0x100
//#define dbg_log 0
void dbg_log( char *fmt, ... )
{
va_list arg;
char line[ 2048 ];
va_start( arg, fmt );
vsnprintf( line, sizeof( line ), fmt, arg );
va_end( arg );
//dbg_log( "%s\n", line);
OutputDebugString(line);
}
void do_kill( HANDLE thread_id )
{
if( thread_id != recv_id )
{
dbg_log( "cancle recv thread\n");
TerminateThread (recv_id,0 );
}
if( thread_id != send_id )
{
dbg_log( "cancle send thread\n");
TerminateThread (send_id ,0);
}
if( thread_id != output_id )
{
dbg_log( "cancle output thread\n");
TerminateThread (output_id,0 );
}
if( thread_id != input_id )
{
dbg_log( "cancle input thread\n");
TerminateThread (input_id ,0);
}
dbg_log( "exit my thread\n");
}
void init_param()
{
GLBSTATE = BEGIN;
srand( time( 0 ) );
input_in = input_queue;
input_out = input_queue;
output_in = output_queue;
output_out = output_queue;
output_acked = output_queue;
ack = 0;
sentack = 0;
acked = 0;
sentid =0;
my_window = QUEUE_LEN;
opp_window = QUEUE_LEN;
sentwindow = QUEUE_LEN;
counter = 1;
waitinginput = 0;
waitingoutput = 0;
waitingsend = 0;
hellonum = 0;
resendpackets = 0;
memset( output_queue, '\0', sizeof( output_queue ) );
memset( input_queue, '\0', sizeof( input_queue ) );
InitializeCriticalSection(&lock_mywd);
InitializeCriticalSection(&lock_output);
InitializeCriticalSection(&lock_oppwd);
InitializeCriticalSection(&lock_send);
InitializeCriticalSection(&lock_input);
input_ok=CreateEvent(NULL,TRUE,FALSE,"input_ok");
output_ok=CreateEvent(NULL,TRUE,FALSE,"output_ok");
send_ok=CreateEvent(NULL,TRUE,FALSE,"send_ok");
}
void get_flag( char *buf, int len )
{
unsigned short int s ;
char *p;
unsigned short int random;
int m_len;
random = ( unsigned short int )rand();
p = buf + 2;
*(unsigned short int *)p = random;
m_len = len;
s = ( random - SOURCE ) ^ SOURCE;
p += 2;
while( m_len > 1 )
{
s = *( unsigned short int *) p ^ s;
p += 2 ;
m_len -= 2;
}
if( m_len == 1 )
s = *p ^ s;
*(unsigned short int *)buf = s ^ PASSWORD;
return;
}
void hand( pcap_t* handle)
{
Frame frame;
dbg_log( "enter hand\n");
for( ; GLBSTATE != FINISH || hellonum != 0;)
{
if( ( GLBSTATE & RECVRSP ) == 0 )
{
memset( ( char *)&frame, '\0', sizeof( Frame ) );
frame.sign = HELLO;
frame.no = myno;
get_flag( ( char *)&frame, HEAD_LEN - FLAG_LEN );
while( pcap_sendpacket( handle,
(BYTE*)&frame, MIN_LEN ) != 0 )Sleep( 10 );
GLBSTATE = GLBSTATE | SENDHELLO;
dbg_log( "send hello ok\n");
}
if( hellonum > 0 )
{
memset( ( char *)&frame, '\0', sizeof( Frame ) );
frame.sign = RSP;
frame.no = myno;
get_flag( ( char *)&frame, HEAD_LEN - FLAG_LEN );
while( pcap_sendpacket( handle,
(BYTE*)&frame, MIN_LEN ) != 0 )Sleep( 10 );
GLBSTATE = GLBSTATE | SENDRSP;
dbg_log( "send rsp ok\n");
hellonum --;
}
Sleep( 500 );
}
}
void Input_Thread( LPARAM lParam )
{
int size;
unsigned short int id;
dbg_log( "enter cycle\n");
for( ; ; )
{
id = *(unsigned short int *)output_in->frame.id;
if( output_in -> state == EMPTY )
{
/* have empty place in output queue */
memset( ( char *)&output_in->frame, '\0', sizeof( Frame ) );
ReadFile( inputfd, output_in->frame.data, DATA_LEN,(LPDWORD)&size,NULL ); /* 填充数据 */
if( size < 0 )
{
dbg_log( "read file error or end of file!!!!!!\n" );
break;
}
if( size ==0 )
{
output_in->frame.cFlag = 1;
size = 100;
}
dbg_log( "read a packet, size: %d id= %d\n", size, counter);
output_in -> state = NOSEND;
output_in -> times = 0;
*( unsigned short int *)output_in -> frame.id = counter++;
*( unsigned short int *)output_in -> frame.length = size;
output_in++;
if( output_in == output_queue + QUEUE_LEN )output_in = output_queue;
if( waitingsend == 1 )
{
EnterCriticalSection( &lock_send );
SetEvent(send_ok );
LeaveCriticalSection( &lock_send );
}
} /* if */
else
//Sleep( 2000 );
{
EnterCriticalSection( &lock_input );
waitinginput = 1;
if( WaitForSingleObject(input_ok, TIMEOUT*1000) ==WAIT_TIMEOUT)
{
dbg_log( "input timeout. continue!\n");
LeaveCriticalSection( &lock_input );
waitinginput = 0;
continue;
}
ResetEvent(input_ok);
dbg_log( "have input message!\n");
LeaveCriticalSection( &lock_input );
waitinginput = 0;
continue;
}
}
//EndSend();
}
void GetNetcardName(pcap_if_t *d,char* netchardsource )
{
pcap_addr_t *a;
for(a=d->addresses;a;a=a->next) {
//printf("\tAddress Family: #%d\n",a->addr->sa_family);
switch(a->addr->sa_family)
{
case AF_INET:
/*printf("\tAddress Family Name: AF_INET\n");*/
if (a->addr){
_tcscpy(netchardsource,d->name);
}
break;
default:
break;
}
}
}
pcap_t* GetOpenLink(){
pcap_if_t *alldevs;
pcap_if_t *d;
pcap_t* fp;
char errbuf[PCAP_ERRBUF_SIZE+1];
char netchardsource [1024];
if (pcap_findalldevs_ex("rpcap://", NULL, &alldevs, errbuf) == -1)
{
MessageBox(NULL,"WinPCap程序加载失败,请重新运行安装程序安装WinPCap","提示",MB_OK|MB_ICONSTOP);
return NULL ;
}
for(d=alldevs;d;d=d->next)
{
GetNetcardName(d,netchardsource);
}
if ( (fp= pcap_open(netchardsource/*"\\Device\\NPF_{8065DF3F-B15B-4EE1-BFEF-0A8893E9DABE}"*/, // name of the device
256, // portion of the packet to capture (only the first 100 bytes)
PCAP_OPENFLAG_PROMISCUOUS, // promiscuous mode
1, // read timeout
NULL, // authentication on the remote machine
errbuf // error buffer
) ) == NULL)
{
ATLTRACE("\nUnable to open the adapter. %s is not supported by WinPcap\n",netchardsource);
return NULL;
}
return fp;
}
void Send_Thread( LPARAM lParam )
{
char err_buf[ LIBNET_ERRBUF_SIZE ];
unsigned short int packet_len, id, ackedtmp;
Frame *frm, ackframe;
int times;
Queue *tmp;
int i;
pcap_t* Lib_Handle=GetOpenLink();
if( Lib_Handle == NULL )
{
//EndSend();
dbg_log( "libnet_open_link_interface: %s\n", err_buf );
return;
}
/* do hand */
hand( Lib_Handle);
Sleep( 1000 );
if( GLBSTATE == FINISH ) GLBSTATE = RUNNING;
dbg_log( " -----------------init ok, start------------------------------ \n");
for( ; ; )
{
ackedtmp = acked + 1;
if( ackedtmp != 0 || output_acked != output_queue )
{
for( i = 0; i < QUEUE_LEN; i ++ )
{
dbg_log( " acked:%d id:%d \n", ackedtmp, *(unsigned short int *)output_acked->frame.id);
if( (output_acked == output_out) && output_acked->state != SENT )
break;
else if( *(unsigned short int *)output_acked->frame.id == ackedtmp )
break;
else if( *(unsigned short int *)output_acked->frame.id ==
(unsigned short)( ackedtmp - 1 ) )
{
output_acked->state = EMPTY;
output_acked ++;
if( output_acked == output_queue + QUEUE_LEN )
output_acked = output_queue;
if( waitinginput == 1 )
{
EnterCriticalSection( &lock_input );
SetEvent(input_ok );
LeaveCriticalSection( &lock_input );
}
break;
}
else
{
output_acked->state = EMPTY;
output_acked ++;
if( output_acked == output_queue + QUEUE_LEN )
output_acked = output_queue;
if( waitinginput == 1 )
{
EnterCriticalSection( &lock_input );
SetEvent(input_ok );
LeaveCriticalSection( &lock_input );
}
}
}
}
if( output_out -> state == NOSEND && opp_window > MIN_WINDOW )
{
frm = &output_out -> frame;
packet_len = HEAD_LEN + *( unsigned short int *)frm -> length;
if( packet_len < MIN_LEN )packet_len = MIN_LEN;
frm -> window = my_window;
*( unsigned short int *)frm -> ack = ack;
frm -> no = myno;
times = 0;
get_flag( ( char *)frm, HEAD_LEN - FLAG_LEN );
while( times < 3 )
{
if( pcap_sendpacket( Lib_Handle,
( BYTE * )frm, packet_len) == 0 )
break;
Sleep( 10 );
times ++;
}
if( times == 3 )
{
dbg_log( "send a packet three times, failed. restart now!\n" );
do_kill( send_id );
}
dbg_log( "sendpacket my_window:%d id:%d ack:%d length:%d sign:%d opp_window:%d\n",
frm -> window, *( unsigned short int *)frm -> id, *( unsigned short int *)frm -> ack,
*( unsigned short int *)frm -> length, frm -> sign, opp_window - 1);
sentid = *( unsigned short int *)frm -> id;
EnterCriticalSection( &lock_oppwd );
opp_window --;
LeaveCriticalSection( &lock_oppwd );
output_out -> state = SENT;
EnterCriticalSection( &lock_output );
output_out++;
if( output_out == output_queue + QUEUE_LEN )output_out = output_queue;
LeaveCriticalSection( &lock_output );
sentack = ack;
sentwindow = my_window;
}
else if( sentack != ack || sentwindow != my_window )
{
/* send ack and window only */
memset( ( char *)&ackframe, '\0', sizeof( Frame ) );
*( unsigned short int *)ackframe.id = 0;
ackframe.window = my_window;
*( unsigned short int *)ackframe.ack = ack;
*( unsigned short int *)ackframe.length = 0;
ackframe.no = myno;
get_flag( ( char *)&ackframe, HEAD_LEN - FLAG_LEN );
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -