You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
503 lines
13 KiB
503 lines
13 KiB
/************************************************************************
|
|
* *
|
|
* INTEL CORPORATION PROPRIETARY INFORMATION *
|
|
* *
|
|
* This software is supplied under the terms of a license *
|
|
* agreement or non-disclosure agreement with Intel Corporation *
|
|
* and may not be copied or disclosed except in accordance *
|
|
* with the terms of that agreement. *
|
|
* *
|
|
* Copyright (C) 1997 Intel Corp. All Rights Reserved *
|
|
* *
|
|
* $Archive: S:\sturgeon\src\gki\vcs\gksocket.cpv $
|
|
* *
|
|
* $Revision: 1.5 $
|
|
* $Date: 28 Feb 1997 15:46:24 $
|
|
* *
|
|
* $Author: CHULME $
|
|
* *
|
|
* $Log: S:\sturgeon\src\gki\vcs\gksocket.cpv $
|
|
//
|
|
// Rev 1.5 28 Feb 1997 15:46:24 CHULME
|
|
// Check additional return value on recvfrom for a closed socket
|
|
//
|
|
// Rev 1.4 17 Jan 1997 09:02:28 CHULME
|
|
// Changed reg.h to gkreg.h to avoid name conflict with inc directory
|
|
//
|
|
// Rev 1.3 10 Jan 1997 16:15:48 CHULME
|
|
// Removed MFC dependency
|
|
//
|
|
// Rev 1.2 18 Dec 1996 14:23:30 CHULME
|
|
// Changed discovery to send broadcast and multicast GRQs - debug only disable
|
|
//
|
|
// Rev 1.1 22 Nov 1996 14:56:04 CHULME
|
|
// Added detection of LastError = 0 for treatment on socket close
|
|
*************************************************************************/
|
|
|
|
// gksocket.cpp : Provides the implementation for the CGKSocket class
|
|
//
|
|
|
|
#include <precomp.h>
|
|
|
|
#define IP_MULTICAST_TTL 3 /* set/get IP multicast timetolive */
|
|
|
|
#include "dspider.h"
|
|
#include "dgkilit.h"
|
|
#include "DGKIPROT.H"
|
|
#include "GATEKPR.H"
|
|
#include "gksocket.h"
|
|
#include "GKREG.H"
|
|
#include "h225asn.h"
|
|
#include "coder.hpp"
|
|
#include "dgkiext.h"
|
|
|
|
#if (defined(_DEBUG) || defined(PCS_COMPLIANCE))
|
|
// INTEROP
|
|
#include "interop.h"
|
|
#include "rasplog.h"
|
|
extern LPInteropLogger RasLogger;
|
|
#endif
|
|
|
|
#ifdef _DEBUG
|
|
#undef THIS_FILE
|
|
static char THIS_FILE[] = __FILE__;
|
|
#endif
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// CGKSocket construction
|
|
|
|
CGKSocket::CGKSocket()
|
|
{
|
|
#ifdef _DEBUG
|
|
char szGKDebug[80];
|
|
#endif
|
|
|
|
SPIDER_TRACE(SP_CONDES, "CGKSocket::CGKSocket()\n", 0);
|
|
|
|
m_hSocket = INVALID_SOCKET;
|
|
m_nLastErr = 0;
|
|
m_nAddrFam = 0;
|
|
m_usPort = 0;
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// CGKSocket destruction
|
|
|
|
CGKSocket::~CGKSocket()
|
|
{
|
|
#ifdef _DEBUG
|
|
char szGKDebug[80];
|
|
#endif
|
|
|
|
SPIDER_TRACE(SP_CONDES, "CGKSocket::~CGKSocket()\n", 0);
|
|
|
|
if (m_hSocket != INVALID_SOCKET)
|
|
Close();
|
|
}
|
|
|
|
int
|
|
CGKSocket::Create(int nAddrFam, unsigned short usPort)
|
|
{
|
|
// ABSTRACT: Creates the socket for the supplied address family (transport)
|
|
// and binds it to the specified port. This function returns 0
|
|
// if successful, else it will return the winsock comm error code.
|
|
// AUTHOR: Colin Hulme
|
|
|
|
int nRet, nLen;
|
|
SOCKADDR_IN sAddrIn;
|
|
#ifdef _DEBUG
|
|
char szGKDebug[80];
|
|
#endif
|
|
|
|
|
|
SPIDER_TRACE(SP_FUNC, "CGKSocket::Create(nAddrFam, %X)\n", usPort);
|
|
|
|
// Create a socket for the supplied address family
|
|
SPIDER_TRACE(SP_WSOCK, "socket(%X, SOCK_DGRAM, 0)\n", nAddrFam);
|
|
if ((m_hSocket = socket(nAddrFam, SOCK_DGRAM, 0)) == INVALID_SOCKET)
|
|
{
|
|
m_nLastErr = WSAGetLastError(); // Get winsock error code
|
|
SpiderWSErrDecode(m_nLastErr); // Debug print of error decode
|
|
return (m_nLastErr);
|
|
}
|
|
m_nAddrFam = nAddrFam;
|
|
|
|
// Bind socket to a local address
|
|
switch (nAddrFam)
|
|
{
|
|
case PF_INET:
|
|
sAddrIn.sin_family = AF_INET;
|
|
break;
|
|
case PF_IPX:
|
|
sAddrIn.sin_family = AF_IPX;
|
|
break;
|
|
}
|
|
sAddrIn.sin_addr.s_addr = htonl(INADDR_ANY);
|
|
sAddrIn.sin_port = htons(usPort);
|
|
SPIDER_TRACE(SP_WSOCK, "bind(%X, &sAddrIn, sizeof(sAddrIn))\n", m_hSocket);
|
|
nRet = bind(m_hSocket, (LPSOCKADDR)&sAddrIn, sizeof(sAddrIn));
|
|
if (nRet != 0)
|
|
{
|
|
m_nLastErr = WSAGetLastError();
|
|
SpiderWSErrDecode(m_nLastErr);
|
|
Close(); // Close the socket
|
|
return (m_nLastErr);
|
|
}
|
|
|
|
// Get dynamic port number - not actually guaranteed til after connect
|
|
SPIDER_TRACE(SP_WSOCK, "getsockname(%X, (LPSOCKADDR)&sAddrIn, sizeof(sAddrIn))\n", m_hSocket);
|
|
nLen = sizeof(sAddrIn);
|
|
nRet = getsockname(m_hSocket, (LPSOCKADDR)&sAddrIn, &nLen);
|
|
if (nRet == SOCKET_ERROR)
|
|
{
|
|
m_nLastErr = WSAGetLastError();
|
|
SpiderWSErrDecode(m_nLastErr);
|
|
Close(); // Close the socket
|
|
return (SOCKET_ERROR);
|
|
}
|
|
SPIDER_DEBUG(sAddrIn.sin_port);
|
|
m_usPort = ntohs(sAddrIn.sin_port);
|
|
|
|
return (0);
|
|
}
|
|
|
|
int
|
|
CGKSocket::Connect(PSOCKADDR_IN pAddr)
|
|
{
|
|
// ABSTRACT: This simulates a connect. It simply stores the relevant
|
|
// information in a member variable that will be used by the
|
|
// Send and Receive member functions.
|
|
// AUTHOR: Colin Hulme
|
|
|
|
m_sAddrIn = *pAddr;
|
|
m_sAddrIn.sin_family = AF_INET;
|
|
m_sAddrIn.sin_port = htons(GKIP_RAS_PORT);
|
|
|
|
return (0);
|
|
}
|
|
|
|
int
|
|
CGKSocket::Send(char *pBuffer, int nLen)
|
|
{
|
|
// ABSTRACT: This function will send a datagram on the connected socket.
|
|
// AUTHOR: Colin Hulme
|
|
|
|
int nRet;
|
|
#ifdef _DEBUG
|
|
char szGKDebug[80];
|
|
#endif
|
|
|
|
SPIDER_TRACE(SP_FUNC, "CGKSocket::Send(pBuffer, %X)\n", nLen);
|
|
|
|
SPIDER_TRACE(SP_WSOCK, "sendto(%X, pBuffer, nLen, 0, &m_sAddrIn, sizeof(m_sAddrIn))\n", m_hSocket);
|
|
#ifdef _DEBUG
|
|
//INTEROP
|
|
if (dwGKIDLLFlags & SP_LOGGER)
|
|
InteropOutput((LPInteropLogger)RasLogger,
|
|
(BYTE FAR *)pBuffer,
|
|
nLen,
|
|
RASLOG_SENT_PDU);
|
|
#endif
|
|
#ifdef PCS_COMPLIANCE
|
|
//INTEROP
|
|
InteropOutput((LPInteropLogger)RasLogger,
|
|
(BYTE FAR *)pBuffer,
|
|
nLen,
|
|
RASLOG_SENT_PDU);
|
|
#endif
|
|
nRet = sendto(m_hSocket, pBuffer, nLen, 0, (LPSOCKADDR)&m_sAddrIn, sizeof(m_sAddrIn));
|
|
SPIDER_DEBUG(nRet);
|
|
if (nRet == SOCKET_ERROR)
|
|
{
|
|
m_nLastErr = WSAGetLastError();
|
|
SpiderWSErrDecode(m_nLastErr);
|
|
Close(); // Close the socket
|
|
return (SOCKET_ERROR);
|
|
}
|
|
|
|
return (nRet);
|
|
}
|
|
|
|
int
|
|
CGKSocket::SendTo(char *pBuffer, int nLen, const struct sockaddr FAR * to, int tolen)
|
|
{
|
|
// ABSTRACT: This function will send a datagram on the connected socket.
|
|
// AUTHOR: Colin Hulme
|
|
|
|
int nRet;
|
|
#ifdef _DEBUG
|
|
char szGKDebug[80];
|
|
#endif
|
|
|
|
SPIDER_TRACE(SP_FUNC, "CGKSocket::SendTo(pBuffer, %X, to, tolen)\n", nLen);
|
|
|
|
SPIDER_TRACE(SP_WSOCK, "sendto(%X, pBuffer, nLen, 0, to, tolen)\n", m_hSocket);
|
|
#ifdef _DEBUG
|
|
//INTEROP
|
|
if (dwGKIDLLFlags & SP_LOGGER)
|
|
InteropOutput((LPInteropLogger)RasLogger,
|
|
(BYTE FAR *)pBuffer,
|
|
nLen,
|
|
RASLOG_SENT_PDU);
|
|
#endif
|
|
#ifdef PCS_COMPLIANCE
|
|
//INTEROP
|
|
InteropOutput((LPInteropLogger)RasLogger,
|
|
(BYTE FAR *)pBuffer,
|
|
nLen,
|
|
RASLOG_SENT_PDU);
|
|
#endif
|
|
nRet = sendto(m_hSocket, pBuffer, nLen, 0, to, tolen);
|
|
SPIDER_DEBUG(nRet);
|
|
if (nRet == SOCKET_ERROR)
|
|
{
|
|
m_nLastErr = WSAGetLastError();
|
|
SpiderWSErrDecode(m_nLastErr);
|
|
Close(); // Close the socket
|
|
return (SOCKET_ERROR);
|
|
}
|
|
|
|
return (nRet);
|
|
}
|
|
|
|
int
|
|
CGKSocket::Receive(char *pBuffer, int nLen)
|
|
{
|
|
// ABSTRACT: This function will post a receive for an incoming datagram.
|
|
// AUTHOR: Colin Hulme
|
|
|
|
int nRet;
|
|
#ifdef _DEBUG
|
|
char szGKDebug[80];
|
|
#endif
|
|
|
|
SPIDER_TRACE(SP_FUNC, "CGKSocket::Receive(pBuffer, %X)\n", nLen);
|
|
|
|
SPIDER_TRACE(SP_WSOCK, "recvfrom(%X, pBuffer, nLen, 0, 0, 0)\n", m_hSocket);
|
|
nRet = recvfrom(m_hSocket, pBuffer, nLen, 0, 0, 0);
|
|
SPIDER_DEBUG(nRet);
|
|
if (nRet == SOCKET_ERROR)
|
|
{
|
|
m_nLastErr = WSAGetLastError();
|
|
if ((m_nLastErr == 2) || (m_nLastErr == 0) || (m_nLastErr == WSAEINVAL)) // Weird return values seen
|
|
m_nLastErr = WSAEINTR; // occasionally when socket closed
|
|
SpiderWSErrDecode(m_nLastErr);
|
|
if (m_nLastErr != WSAEINTR)
|
|
Close(); // Close the socket
|
|
return (SOCKET_ERROR);
|
|
}
|
|
|
|
#ifdef _DEBUG
|
|
//INTEROP
|
|
if (dwGKIDLLFlags & SP_LOGGER)
|
|
InteropOutput((LPInteropLogger)RasLogger,
|
|
(BYTE FAR *)pBuffer,
|
|
nLen,
|
|
RASLOG_RECEIVED_PDU);
|
|
#endif
|
|
#ifdef PCS_COMPLIANCE
|
|
//INTEROP
|
|
InteropOutput((LPInteropLogger)RasLogger,
|
|
(BYTE FAR *)pBuffer,
|
|
nLen,
|
|
RASLOG_RECEIVED_PDU);
|
|
#endif
|
|
|
|
return (nRet);
|
|
}
|
|
|
|
int
|
|
CGKSocket::SendBroadcast(char *pBuffer, int nLen)
|
|
{
|
|
// ABSTRACT: This function will send a datagram to the broadcast address
|
|
// and to the multicast address. In the case of a debug build,
|
|
// a registry setting can be used to disable the multicast
|
|
// transmission. Both transmissions will always occur in the
|
|
// release build.
|
|
// AUTHOR: Colin Hulme
|
|
|
|
int nRet, nValue;
|
|
struct sockaddr_in sAddrIn;
|
|
#ifdef _DEBUG
|
|
char szGKDebug[80];
|
|
#endif
|
|
|
|
SPIDER_TRACE(SP_FUNC, "CGKSocket::SendBroadcast(pBuffer, %X)\n", nLen);
|
|
ASSERT(g_pGatekeeper);
|
|
if(g_pGatekeeper == NULL)
|
|
return SOCKET_ERROR;
|
|
|
|
// Setup family and port information
|
|
switch (m_nAddrFam)
|
|
{
|
|
case PF_INET:
|
|
sAddrIn.sin_family = AF_INET;
|
|
sAddrIn.sin_port = htons(GKIP_DISC_PORT);
|
|
break;
|
|
case PF_IPX:
|
|
sAddrIn.sin_family = AF_IPX;
|
|
sAddrIn.sin_port = htons(GKIPX_DISC_PORT);
|
|
break;
|
|
}
|
|
|
|
// ================= SEND BROADCAST ===================
|
|
//if ((nValue = (int)Gatekeeper.GetMCastTTL()) == 0)
|
|
// Set socket options to allow broadcasting on this socket
|
|
nValue = 1; // TRUE - for setting BOOLEAN
|
|
SPIDER_TRACE(SP_WSOCK, "setsockopt(%X, SOL_SOCKET, SO_BROADCAST, &nValue, sizeof(nValue))\n", m_hSocket);
|
|
nRet = setsockopt(m_hSocket, SOL_SOCKET, SO_BROADCAST, (const char *)&nValue, sizeof(nValue));
|
|
// TBD - Don't know if SOL_SOCKET is going to work for other transports
|
|
if (nRet == SOCKET_ERROR)
|
|
{
|
|
m_nLastErr = WSAGetLastError();
|
|
SpiderWSErrDecode(m_nLastErr);
|
|
Close(); // Close the socket
|
|
return (SOCKET_ERROR);
|
|
}
|
|
sAddrIn.sin_addr.s_addr = htonl(INADDR_BROADCAST);
|
|
|
|
SPIDER_TRACE(SP_WSOCK, "sendto(%X, pBuffer, nLen, 0, (LPSOCKADDR)&sAddrIn, sizeof(sAddrIn))\n", m_hSocket);
|
|
#ifdef _DEBUG
|
|
//INTEROP
|
|
if (dwGKIDLLFlags & SP_LOGGER)
|
|
InteropOutput((LPInteropLogger)RasLogger,
|
|
(BYTE FAR *)pBuffer,
|
|
nLen,
|
|
RASLOG_SENT_PDU);
|
|
#endif
|
|
#ifdef PCS_COMPLIANCE
|
|
//INTEROP
|
|
InteropOutput((LPInteropLogger)RasLogger,
|
|
(BYTE FAR *)pBuffer,
|
|
nLen,
|
|
RASLOG_SENT_PDU);
|
|
#endif
|
|
nRet = sendto(m_hSocket, pBuffer, nLen, 0, (LPSOCKADDR)&sAddrIn, sizeof(sAddrIn));
|
|
SPIDER_DEBUG(nRet);
|
|
if (nRet == SOCKET_ERROR)
|
|
{
|
|
m_nLastErr = WSAGetLastError();
|
|
SpiderWSErrDecode(m_nLastErr);
|
|
Close(); // Close the socket
|
|
return (SOCKET_ERROR);
|
|
}
|
|
|
|
#ifdef _DEBUG
|
|
if ((nValue = (int)g_pGatekeeper->GetMCastTTL()) != 0)
|
|
{ // debug only conditional for avoiding sending multicast
|
|
#endif
|
|
// ================= SEND MULTICAST ===================
|
|
// Set socket options for multicast time to live
|
|
nValue = 16; //FMN
|
|
SPIDER_TRACE(SP_WSOCK, "setsockopt(%X, IPPROTO_IP, IP_MULTICAST_TTL, &nValue, sizeof(nValue))\n", m_hSocket);
|
|
nRet = setsockopt(m_hSocket, IPPROTO_IP, IP_MULTICAST_TTL,
|
|
(const char *)&nValue, sizeof(nValue));
|
|
// TBD - IP specific - handle IPX case with broadcast?
|
|
if (nRet == SOCKET_ERROR)
|
|
{
|
|
m_nLastErr = WSAGetLastError();
|
|
SpiderWSErrDecode(m_nLastErr);
|
|
Close(); // Close the socket
|
|
return (SOCKET_ERROR);
|
|
}
|
|
sAddrIn.sin_addr.s_addr = inet_addr(GKIP_DISC_MCADDR);
|
|
|
|
SPIDER_TRACE(SP_WSOCK, "sendto(%X, pBuffer, nLen, 0, (LPSOCKADDR)&sAddrIn, sizeof(sAddrIn))\n", m_hSocket);
|
|
#ifdef _DEBUG
|
|
//INTEROP
|
|
if (dwGKIDLLFlags & SP_LOGGER)
|
|
InteropOutput((LPInteropLogger)RasLogger,
|
|
(BYTE FAR *)pBuffer,
|
|
nLen,
|
|
RASLOG_SENT_PDU);
|
|
#endif
|
|
#ifdef PCS_COMPLIANCE
|
|
//INTEROP
|
|
InteropOutput((LPInteropLogger)RasLogger,
|
|
(BYTE FAR *)pBuffer,
|
|
nLen,
|
|
RASLOG_SENT_PDU);
|
|
#endif
|
|
nRet = sendto(m_hSocket, pBuffer, nLen, 0, (LPSOCKADDR)&sAddrIn, sizeof(sAddrIn));
|
|
SPIDER_DEBUG(nRet);
|
|
if (nRet == SOCKET_ERROR)
|
|
{
|
|
m_nLastErr = WSAGetLastError();
|
|
SpiderWSErrDecode(m_nLastErr);
|
|
Close(); // Close the socket
|
|
return (SOCKET_ERROR);
|
|
}
|
|
#ifdef _DEBUG
|
|
} // End debug only conditional for avoiding sending multicast
|
|
#endif
|
|
|
|
return (nRet);
|
|
}
|
|
|
|
int
|
|
CGKSocket::ReceiveFrom(char *pBuffer, int nLen)
|
|
{
|
|
// ABSTRACT: This function will post a receivefrom looking for a GCF or GRJ
|
|
// AUTHOR: Colin Hulme
|
|
|
|
int nRet;
|
|
#ifdef _DEBUG
|
|
char szGKDebug[80];
|
|
#endif
|
|
|
|
SPIDER_TRACE(SP_FUNC, "CGKSocket::ReceiveFrom(pBuffer, %X)\n", nLen);
|
|
|
|
SPIDER_TRACE(SP_WSOCK, "recvfrom(%X, pBuffer, nLen, 0, 0, 0)\n", m_hSocket);
|
|
nRet = recvfrom(m_hSocket, pBuffer, nLen, 0, 0, 0);
|
|
SPIDER_DEBUG(nRet);
|
|
if (nRet == SOCKET_ERROR)
|
|
{
|
|
m_nLastErr = WSAGetLastError();
|
|
if ((m_nLastErr == 2) || (m_nLastErr == 0)) // Weird return values seen
|
|
m_nLastErr = WSAEINTR; // occasionally when socket closed
|
|
SpiderWSErrDecode(m_nLastErr);
|
|
if (m_nLastErr != WSAEINTR)
|
|
Close(); // Close the socket
|
|
return (SOCKET_ERROR);
|
|
}
|
|
|
|
#ifdef _DEBUG
|
|
//INTEROP
|
|
if (dwGKIDLLFlags & SP_LOGGER)
|
|
InteropOutput((LPInteropLogger)RasLogger,
|
|
(BYTE FAR *)pBuffer,
|
|
nLen,
|
|
RASLOG_RECEIVED_PDU);
|
|
#endif
|
|
#ifdef PCS_COMPLIANCE
|
|
//INTEROP
|
|
InteropOutput((LPInteropLogger)RasLogger,
|
|
(BYTE FAR *)pBuffer,
|
|
nLen,
|
|
RASLOG_RECEIVED_PDU);
|
|
#endif
|
|
|
|
return (nRet);
|
|
}
|
|
|
|
int
|
|
CGKSocket::Close(void)
|
|
{
|
|
// ABSTRACT: This function will close the socket
|
|
// AUTHOR: Colin Hulme
|
|
|
|
int nRet;
|
|
#ifdef _DEBUG
|
|
char szGKDebug[80];
|
|
#endif
|
|
|
|
SPIDER_TRACE(SP_FUNC, "CGKSocket::Close()\n", 0);
|
|
|
|
// Close the socket
|
|
SPIDER_TRACE(SP_WSOCK, "closesocket(%X)\n", m_hSocket);
|
|
nRet = closesocket(m_hSocket);
|
|
m_hSocket = INVALID_SOCKET;
|
|
|
|
return (0);
|
|
}
|
|
|