forked from LosaDev/ls-2019-source
266 lines
6.8 KiB
C++
266 lines
6.8 KiB
C++
|
|
|
|
#include "../stdafx.h"
|
|
|
|
#include "ioPortalHelp.h"
|
|
#include "ioUDPSocket.h"
|
|
#include "Packet.h"
|
|
#include "NetworkSecurity.h"
|
|
|
|
#define SIO_UDP_CONNRESET _WSAIOW(IOC_VENDOR,12)
|
|
|
|
|
|
ioUDPSocket::ioUDPSocket()
|
|
{
|
|
m_Socket = INVALID_SOCKET;
|
|
m_hWnd = 0;
|
|
m_WndMsg = 0;
|
|
m_pNS = NULL;
|
|
|
|
ClearIPInfo();
|
|
}
|
|
|
|
ioUDPSocket::~ioUDPSocket()
|
|
{
|
|
CloseUDP();
|
|
}
|
|
|
|
void ioUDPSocket::ClearIPInfo()
|
|
{
|
|
memset( m_RecentRcvIP, 0, sizeof(m_RecentRcvIP) );
|
|
m_iRecentRcvPort = 0;
|
|
m_iMainPort = 0;
|
|
|
|
memset( m_PreRecentRcvIP, 0, sizeof(m_PreRecentRcvIP) );
|
|
m_iPreRecentRcvPort = 0;
|
|
|
|
memset( m_szMyIP, 0, sizeof(m_szMyIP) );
|
|
}
|
|
|
|
bool ioUDPSocket::InitUDP( HWND hWnd, UINT uMsg, int iPort )
|
|
{
|
|
ClearIPInfo();
|
|
|
|
m_Socket = socket( AF_INET, SOCK_DGRAM, 0 );
|
|
if( m_Socket == INVALID_SOCKET )
|
|
{
|
|
DebugMBox(__FILE__,__LINE__,NULL,"ioUDPSocket::InitUDP - socket setting error");
|
|
return false;
|
|
}
|
|
|
|
DWORD dwBytesReturned = 0;
|
|
BOOL bNewBehavior = FALSE;
|
|
DWORD status;
|
|
status = WSAIoctl( m_Socket, SIO_UDP_CONNRESET, &bNewBehavior, sizeof( dwBytesReturned ), NULL, 0, &dwBytesReturned, NULL, NULL );
|
|
if( status == SOCKET_ERROR )
|
|
{
|
|
LOG.PrintTimeAndLog( 0, "ioUDPSocket::InitUDP Opt None SIO_UDP_CONNRESET : %d", WSAGetLastError() );
|
|
}
|
|
|
|
m_hWnd = hWnd;
|
|
m_WndMsg = uMsg;
|
|
|
|
SOCKADDR_IN kLocalSockIn;
|
|
memset( &kLocalSockIn, 0, sizeof(kLocalSockIn) );
|
|
kLocalSockIn.sin_family = AF_INET;
|
|
kLocalSockIn.sin_addr.s_addr = htonl( INADDR_ANY );
|
|
kLocalSockIn.sin_port = htons( iPort );
|
|
m_iMainPort = iPort;
|
|
|
|
if( bind( m_Socket, (LPSOCKADDR)&kLocalSockIn, sizeof(kLocalSockIn) ) == SOCKET_ERROR )
|
|
{
|
|
DebugMBox(__FILE__,__LINE__,NULL, "ioUDPSocket::InitUDP - bind setting error" );
|
|
return false;
|
|
}
|
|
|
|
int iMaxSize = MAX_BUFFER * 8;
|
|
setsockopt( m_Socket, SOL_SOCKET, SO_SNDBUF, (const char *)&iMaxSize, sizeof(iMaxSize));
|
|
setsockopt( m_Socket, SOL_SOCKET, SO_RCVBUF, (const char *)&iMaxSize, sizeof(iMaxSize));
|
|
|
|
// BOOL is_flag = TRUE;
|
|
// setsockopt(m_socket_object, SOL_SOCKET, SO_KEEPALIVE , (const char *)&is_flag, sizeof(is_flag));
|
|
|
|
// BOOL no_nagle = TRUE;
|
|
// setsockopt(m_socket_object, IPPROTO_TCP, TCP_NODELAY, (const char *)&no_nagle, sizeof(no_nagle));
|
|
|
|
if( WSAAsyncSelect( m_Socket, hWnd, uMsg, FD_READ) > 0 )
|
|
{
|
|
DebugMBox(__FILE__,__LINE__,NULL,"ioUDPSocket::InitUDP - WSAAsyncSelect error");
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
void ioUDPSocket::SetNS( NetworkSecurity *pNS )
|
|
{
|
|
m_pNS = pNS;
|
|
}
|
|
|
|
void ioUDPSocket::CloseUDP()
|
|
{
|
|
if( m_Socket != INVALID_SOCKET )
|
|
{
|
|
closesocket( m_Socket );
|
|
m_Socket = INVALID_SOCKET;
|
|
}
|
|
}
|
|
|
|
void ioUDPSocket::RcvPeerInfo( char *iip, int iPort )
|
|
{
|
|
//¿ÜºÎ ó¸®.
|
|
}
|
|
|
|
bool ioUDPSocket::EvaluateSocket( WPARAM wParam, LPARAM lParam )
|
|
{
|
|
if( WSAGETSELECTEVENT( lParam ) == FD_READ )
|
|
return RecvLoop( wParam );
|
|
|
|
return true;
|
|
}
|
|
|
|
bool ioUDPSocket::SendLoop( const char *szIP, int iPort, CPacket &rkPacket )
|
|
{
|
|
SOCKADDR_IN server_sin;
|
|
server_sin.sin_family = AF_INET;
|
|
server_sin.sin_addr.s_addr = inet_addr( szIP );
|
|
server_sin.sin_port = htons( iPort );
|
|
|
|
int server_sin_len = sizeof( server_sin );
|
|
|
|
if( m_pNS )
|
|
m_pNS->PrepareMsg( rkPacket );
|
|
|
|
int iSendSize = sendto( m_Socket, rkPacket.GetBuffer(), rkPacket.GetBufferSize(), 0, (struct sockaddr FAR *)&server_sin, server_sin_len );
|
|
if( iSendSize == 0 )
|
|
{
|
|
LOG.PrintTimeAndLog( 0, "ioUDPSocket::SendLoop(%s:%d) : SizeZero( %d ) PacketType:%d", szIP, iPort, WSAGetLastError(), rkPacket.GetPacketID() );
|
|
ioPortalHelp::CheckSocketError(__FILE__, __LINE__);
|
|
}
|
|
else if( iSendSize == SOCKET_ERROR )
|
|
{
|
|
LOG.PrintTimeAndLog( 0, "ioUDPSocket::SendLoop(%s:%d) : SocketError( %d ) PacketType:%d", szIP, iPort, WSAGetLastError(), rkPacket.GetPacketID() );
|
|
ioPortalHelp::CheckSocketError(__FILE__, __LINE__);
|
|
}
|
|
|
|
if( m_pNS )
|
|
m_pNS->CompletionMsg( rkPacket );
|
|
|
|
return true;
|
|
}
|
|
|
|
bool ioUDPSocket::RecvLoop( SOCKET cSocket )
|
|
{
|
|
int iRecvSize;
|
|
|
|
SOCKADDR_IN kPeerSockIn;
|
|
int iPeerSockInSize = sizeof(kPeerSockIn);
|
|
|
|
iRecvSize = recvfrom( cSocket,
|
|
m_szRcvBuf,
|
|
MAX_BUFFER,
|
|
0,
|
|
(struct sockaddr FAR *)&kPeerSockIn,
|
|
&iPeerSockInSize );
|
|
|
|
if( iRecvSize > 0 )
|
|
{
|
|
wsprintf( m_RecentRcvIP, "%d.%d.%d.%d", kPeerSockIn.sin_addr.s_net,
|
|
kPeerSockIn.sin_addr.s_host,
|
|
kPeerSockIn.sin_addr.s_lh,
|
|
kPeerSockIn.sin_addr.s_impno );
|
|
|
|
m_iRecentRcvPort = ntohs(kPeerSockIn.sin_port);
|
|
|
|
CPacket kPacket( m_szRcvBuf, iRecvSize );
|
|
if( kPacket.IsValidPacket() && kPacket.GetBufferSize() == iRecvSize )
|
|
{
|
|
RcvPeerInfo( m_RecentRcvIP, m_iRecentRcvPort );
|
|
if( CheckNS( kPacket ) == false ) return false;
|
|
|
|
ProcessPacket( kPacket, m_RecentRcvIP, m_iRecentRcvPort );
|
|
return true;
|
|
}
|
|
else
|
|
{
|
|
LOG.PrintTimeAndLog( 0, "ioUDPSocket::RecvLoop - Packet Error" );
|
|
LOG.PrintTimeAndLog( 0, "ioUDPSocket::RecvLoop - Valid(%d), BufSize:(%d), ID(%d), RecvSize(%d)",
|
|
kPacket.IsValidPacket(), kPacket.GetBufferSize(),
|
|
kPacket.GetPacketID(), iRecvSize );
|
|
ioPortalHelp::CheckSocketError( __FILE__, __LINE__ );
|
|
return false;
|
|
}
|
|
}
|
|
else if( iRecvSize == 0 )
|
|
{
|
|
LOG.PrintTimeAndLog( 0, "ioUDPSocket::RecvLoop - UDP Socket Graceful Close");
|
|
ioPortalHelp::CheckSocketError(__FILE__, __LINE__);
|
|
return false;
|
|
}
|
|
else if( iRecvSize==SOCKET_ERROR )
|
|
{
|
|
int iWSAError = WSAGetLastError();
|
|
if( iWSAError != WSAEWOULDBLOCK )
|
|
{
|
|
LOG.PrintTimeAndLog( 0, "ioUDPSocket::RecvLoop - UDP Socket SOCKET_ERROR(%d)", iWSAError );
|
|
ioPortalHelp::CheckSocketError(__FILE__, __LINE__);
|
|
return false;
|
|
}
|
|
}
|
|
|
|
LOG.PrintTimeAndLog( 0, "ioUDPSocket::RecvLoop - Except Unknown Error" );
|
|
ioPortalHelp::CheckSocketError( __FILE__, __LINE__ );
|
|
|
|
return false;
|
|
}
|
|
|
|
bool ioUDPSocket::CheckNS( CPacket &rkPacket )
|
|
{
|
|
if( !m_pNS ) return true;
|
|
|
|
if( !m_pNS->UpdateReceiveCount() )
|
|
return false;
|
|
|
|
if( !m_pNS->IsCheckSum( rkPacket ) )
|
|
return false;
|
|
|
|
if( !m_pNS->CheckState( rkPacket ) )
|
|
return false;
|
|
|
|
return true;
|
|
}
|
|
|
|
void ioUDPSocket::SocketErrorMsg( const char *szError )
|
|
{
|
|
if( szError )
|
|
{
|
|
LOG.PrintTimeAndLog( 0, "%s:%d - %s", m_RecentRcvIP, m_iRecentRcvPort, szError );
|
|
}
|
|
}
|
|
|
|
void ioUDPSocket::GetRecentIPPort( char *szIP, int &iPort )
|
|
{
|
|
strcpy( szIP, m_RecentRcvIP );
|
|
iPort = m_iRecentRcvPort;
|
|
}
|
|
|
|
const char* ioUDPSocket::GetMyIP()
|
|
{
|
|
char szHost[MAX_PATH];
|
|
gethostname( szHost, MAX_PATH );
|
|
|
|
HOSTENT *pHost = gethostbyname( szHost );
|
|
if( !pHost )
|
|
{
|
|
sprintf(m_szMyIP, "%d.%d.%d.%d", 127,0,0,1);
|
|
}
|
|
else
|
|
{
|
|
sprintf(m_szMyIP, "%d.%d.%d.%d", (BYTE)pHost->h_addr_list[0][0],
|
|
(BYTE)pHost->h_addr_list[0][1],
|
|
(BYTE)pHost->h_addr_list[0][2],
|
|
(BYTE)pHost->h_addr_list[0][3]);
|
|
}
|
|
|
|
return m_szMyIP;
|
|
} |