windows-nt/Source/XPSP1/NT/net/homenet/alg/alg_icq/icqio.cpp

535 lines
11 KiB
C++
Raw Normal View History

2020-09-26 03:20:57 -05:00
#include "stdafx.h"
VOID
IcqWriteCompletionRoutine
(
ULONG ErrorCode,
ULONG BytesTransferred,
PNH_BUFFER Bufferp
)
/*++
Routine Description:
A generic Write Completion Routine.
Arguments:
none.
Return Value:
--*/
{
PCNhSock Socketp = Bufferp->Socketp;
ICQ_TRC(TM_IO, TL_DUMP, ("-- WRITE COMPLETION ROUTINE --"));
NhReleaseBuffer(Bufferp);
//Dereference Interface;
DEREF_COMPONENT( Socketp, eRefIoWrite);
DEREF_COMPONENT( g_IcqComponentReferencep, eRefIoWrite);
}
VOID
ReadServerCompletionRoutine
(
ULONG ErrorCode,
ULONG BytesTransferred,
PNH_BUFFER Bufferp
)
/*++
Routine Description:
Reads the Server Responses to Client packets
and then multiplexes this responses to the approprate client
which was given in the Context information
Arguments:
none.
Return Value:
--*/
{
PICQ_CLIENT IcqClientp = NULL;
PCNhSock Socketp = NULL;
ULONG Error = NO_ERROR;
ICQ_TRC(TM_IO, TL_ERROR, (" "));
PROFILER(TM_IO, TL_TRACE, ("> UDP-SERVER - READ "));
if(Bufferp is NULL) return;
//
// Get the Client Information
Socketp = Bufferp->Socketp;
IcqClientp = (PICQ_CLIENT)Bufferp->Context;
ASSERT(IcqClientp != NULL);
if(ErrorCode)
{
// Re-issue a read operation if it is not critical Error.
ICQ_TRC(TM_IO, TL_ERROR,
("** !! READ ERROR in Server -> Client (UDP) !! **"));
NhReleaseBuffer(Bufferp);
//ErrorOut();
}
else // we need the context information
{
//
// reissue read first
//
REF_COMPONENT( IcqClientp, eRefIoRead );
Error = Socketp->NhReadDatagramSocket(g_IcqComponentReferencep,
NULL,
ReadServerCompletionRoutine,
IcqClientp,
NULL);
if(Error)
{
ICQ_TRC(TM_IO, TL_ERROR, ("READ ERROR"));
DEREF_COMPONENT( IcqClientp, eRefIoRead );
}
// multiplex the data
Error = IcqClientp->ServerRead(Bufferp, 0, 0);
if(Error)
{
NhReleaseBuffer( Bufferp );
}
}
// DEREFERENCING
DEREF_COMPONENT( Socketp, eRefIoRead );
DEREF_COMPONENT( g_IcqComponentReferencep, eRefIoRead );
DEREF_COMPONENT( IcqClientp, eRefIoRead );
}
VOID
IcqReadClientUdpCompletionRoutine
(
ULONG ErrorCode,
ULONG BytesTransferred,
PNH_BUFFER Bufferp
)
/*++
Routine Description:
This is the READ - DISPATCHER for the UDP
Clients sending packets to the server will be caught here..
it will dispatch the packet to the appropriate ICQ client objects READER
Arguments:
none.
Return Value:
--*/
{
PCNhSock Socketp = Bufferp->Socketp;
ULONG Error = NO_ERROR;
// HANDLE DynamicRedirectHandle = (HANDLE) Bufferp->Context;
ICQ_TRC(TM_IO, TL_ERROR, (" "));
PROFILER(TM_IO, TL_TRACE,("UDP-CLIEN-READ DATA CAME from %s e(%hu)",
INET_NTOA(Bufferp->ReadAddress.sin_addr.S_un.S_addr), ErrorCode));
do
{
if(ErrorCode)
{
// Re-issue a read operation if it is not critical Error.
ICQ_TRC(TM_IO, TL_ERROR,
("** !! CLIENT~SERVER READ ERROR - Deletin all the Client Entries"));
Error = g_IcqPrxp->ReadFromClientCompletionRoutine(ErrorCode,
BytesTransferred,
Bufferp);
break;
}
else
{
// Re-issue a read operation.
Error = Socketp->NhReadDatagramSocket(g_IcqComponentReferencep,
NULL,
IcqReadClientUdpCompletionRoutine,
NULL,// DynamicRedirectHandle,
NULL);
if(Error)
{
ICQ_TRC(TM_IO, TL_ERROR,("TREAD !!> REISsUE READ ERROR "));
break;
}
g_IcqPrxp->ReadFromClientCompletionRoutine(ErrorCode,
BytesTransferred,
Bufferp);
} // else for if (ErrorCode)
} while ( FALSE );
DEREF_COMPONENT( Socketp, eRefIoRead);
DEREF_COMPONENT( g_IcqComponentReferencep, eRefIoRead);
}
//
// CLIENT - RELATED IO COMPLETION ROUTINES
//
VOID
IcqPeerConnectionCompletionRoutine
(
ULONG ErrorCode,
ULONG BytesTransferred,
PNH_BUFFER Bufferp
)
/*++
Routine Description:
Arguments:
none.
Return Value:
--*/
{
PCNhSock Socketp = NULL;
PICQ_PEER IcqPeerp = NULL;
ULONG Error;
// ASSERT(Bufferp);
Socketp = Bufferp->Socketp;
IcqPeerp = reinterpret_cast<PICQ_PEER>(Bufferp->Context);
// IcqClientp = reinterpret_cast<PICQ_CLIENT>(Bufferp->Context2);
ICQ_TRC(TM_IO, TL_TRACE, ("> IcqPeerConnectionCompletionRoutine"));
// ASSERT on all of them.
do
{
if(ErrorCode)
{
// Do - we need it?
// Delete the Shadow mapping
//
// if can't connect then Delete the existing Socket to which we have
// established connection.
//
if(IcqPeerp->MappingDirection is IcqFlagOutgoing)
{
STOP_COMPONENT(IcqPeerp->ToClientSocketp);
//DEREFERENCE_COMPONENT(IcqPeerp->ToClientSocketp);
}
else // incoming
{
STOP_COMPONENT(IcqPeerp->ToPeerSocketp);
//DEREFERENCE_COMPONENT(IcqPeerp->ToClientSocketp);
}
break;
}
else
{
ULONG srcIp;
USHORT srcPort;
Socketp->NhQueryRemoteEndpointSocket(&srcIp, &srcPort);
//
//
ICQ_TRC(TM_IO, TL_TRACE,
("Connected to - Remote end is at %s:%hu",
INET_NTOA(srcIp), htons(srcPort)));
//
// Activate The Connection
// Issue the Read Operations on both Sockets with the Peer as their
// Context
//
if(IcqPeerp->MappingDirection is IcqFlagOutgoing)
{
IcqPeerp->ToPeerSocketp = Socketp;
ICQ_TRC(TM_MSG, TL_DUMP,
("Mapping is outGoing.. this socket is to the peer"));
}
else
{
IcqPeerp->ToClientSocketp = Socketp;
}
ICQ_TRC(TM_IO, TL_TRACE, ("Issuing firstRead"));
Socketp = IcqPeerp->ToClientSocketp;
REF_COMPONENT( IcqPeerp, eRefIoRead );
Error = Socketp->NhReadStreamSocket
(
g_IcqComponentReferencep,
NULL,
ICQ_BUFFER_SIZE, // we should give a size
0,
IcqPeerReadCompletionRoutine,
IcqPeerp,
NULL
);
if(Error)
{
ErrorOut();
ICQ_TRC(TM_MSG, TL_ERROR, (" ERROR - Read failed on ToClient Sock"));
DEREF_COMPONENT( IcqPeerp, eRefIoRead );
break;
}
//
// The other read operation
//
ICQ_TRC(TM_IO, TL_TRACE, ("Issuing second Read"));
Socketp = IcqPeerp->ToPeerSocketp;
REF_COMPONENT( IcqPeerp, eRefIoRead );
Error = Socketp->NhReadStreamSocket
(
g_IcqComponentReferencep,
NULL,
ICQ_BUFFER_SIZE,
0,
IcqPeerReadCompletionRoutine,
IcqPeerp,
NULL
);
if(Error)
{
ErrorOut();
ICQ_TRC(TM_MSG, TL_ERROR, (" ERROR - Read failed on ToPeer Sock"));
STOP_COMPONENT(IcqPeerp->ToClientSocketp); // reference will be cleared later
DEREF_COMPONENT( IcqPeerp, eRefIoRead);
DEREF_COMPONENT( IcqPeerp, eRefIoRead );
break;
}
//
// Reference the ICQ_PEER twice due to two read issues
IcqPeerp->bActivated = TRUE;
}
} while (FALSE);
DEREF_COMPONENT( Bufferp->Socketp, eRefIoConnect );
DEREF_COMPONENT( IcqPeerp, eRefIoConnect);
DEREF_COMPONENT( g_IcqComponentReferencep, eRefIoConnect );
}
VOID
IcqPeerReadCompletionRoutine
(
ULONG ErrorCode,
ULONG BytesTransferred,
PNH_BUFFER Bufferp
)
/*++
Routine Description:
Reads TCP data between the peers. Within these flows there will be
a place where the Data channel is negotiated.
Arguments:
none.
Return Value:
--*/
{
PICQ_PEER IcqPeerp = NULL;
PCNhSock Socketp = NULL;
PCNhSock OtherSocketp = NULL;
ULONG Error = NO_ERROR;
// ASSeRT(Bufferp);
Socketp = Bufferp->Socketp;
IcqPeerp = reinterpret_cast<PICQ_PEER>(Bufferp->Context);
ICQ_TRC(TM_IO, TL_TRACE,
("> IcqPeerReadCompletionRoutine E:(%X) D:(%u)",
ErrorCode, BytesTransferred));
do
{
if( (ErrorCode != 0) ||
((ErrorCode== 0) && (BytesTransferred == 0))
)
{
ICQ_TRC(TM_IO, TL_ERROR, ("Stoppping the Peer SESSION"));
IcqPeerp->EndPeerSessionForClient(Socketp);
break;
}
else
{
if(BytesTransferred)
{
OtherSocketp = IcqPeerp->ToClientSocketp;
ICQ_TRC(TM_IO, TL_TRACE,
(" Regular Data from a Peer(%u)/Client(%s) Socket",
IcqPeerp->PeerUIN, // Peer-UIN
INET_NTOA(IcqPeerp->iKey1))); // Client-IP
//
// Determine which direction this Socket is from..
//
if(OtherSocketp is Socketp)
{
//
// NOTE: if it is from the ToClientSocketp then Process it
//
IcqPeerp->ProcessOutgoingPeerMessage(Bufferp->Buffer,
Bufferp->BytesTransferred);
OtherSocketp = IcqPeerp->ToPeerSocketp;
}
// then forward it to the other side by simply writing it .
Error = OtherSocketp->NhWriteStreamSocket(g_IcqComponentReferencep,
Bufferp,
BytesTransferred,
0,
IcqWriteCompletionRoutine,
NULL,
NULL);
if(Error)
{
ICQ_TRC(TM_MSG, TL_ERROR,
("Error - In writing to the other side"));
}
}
//
// Issue another Read operation
//
REF_COMPONENT( IcqPeerp, eRefIoRead );
Error = Socketp->NhReadStreamSocket(g_IcqComponentReferencep,
NULL,
ICQ_BUFFER_SIZE,
0,
IcqPeerReadCompletionRoutine,
IcqPeerp,
NULL);
if(Error)
{
DEREF_COMPONENT( IcqPeerp, eRefIoRead);
ICQ_TRC(TM_MSG, TL_ERROR, ("Peer connection no more??"));
}
}
} while (FALSE);
DEREF_COMPONENT( Socketp, eRefIoRead );
DEREF_COMPONENT( IcqPeerp, eRefIoRead );
DEREF_COMPONENT( g_IcqComponentReferencep, eRefIoRead );
} // End of *IcqPeerReadCompletionRoutine*