www.pudn.com > VOIP(H323).rar > ooSocket.c
/*
* Copyright (C) 2004 by Objective Systems, Inc.
*
* This software is furnished under an open source license and may be
* used and copied only in accordance with the terms of this license.
* The text of the license may generally be found in the root
* directory of this installation in the LICENSE.txt file. It
* can also be viewed online at the following URL:
*
* http://www.obj-sys.com/open/license.html
*
* Any redistributions of this file including modified versions must
* maintain this copyright notice.
*
*****************************************************************************/
#include "ooSocket.h"
#if defined(_WIN32_WCE)
static int inited = 0;
#define SEND_FLAGS 0
#define SHUTDOWN_FLAGS 0
#elif defined (_WIN32)
static LPFN_SEND send;
static LPFN_SOCKET socket;
static LPFN_SETSOCKOPT setsockopt;
static LPFN_BIND bind;
static LPFN_HTONL htonl;
static LPFN_HTONS htons;
static LPFN_CONNECT connect;
static LPFN_INET_ADDR inet_addr;
static LPFN_LISTEN listen;
static LPFN_ACCEPT accept;
static LPFN_NTOHL ntohl;
static LPFN_NTOHS ntohs;
static LPFN_RECV recv;
static LPFN_SHUTDOWN shutdown;
static LPFN_SENDTO sendto;
static LPFN_INET_NTOA inet_ntoa;
static LPFN_RECVFROM recvfrom;
static LPFN_SELECT select;
static LPFN_GETHOSTNAME gethostname;
static LPFN_GETHOSTBYNAME gethostbyname;
static LPFN_WSAGETLASTERROR WSAGetLastError;
static LPFN_WSACLEANUP WSACleanup;
static LPFN_CLOSESOCKET closesocket;
static HMODULE ws32 = 0;
#define SEND_FLAGS 0
#define SHUTDOWN_FLAGS SD_BOTH
#else
#define SEND_FLAGS 0
#define SHUTDOWN_FLAGS SHUT_RDWR
#define closesocket close
#endif
int ooSocketsInit ()
{
#if defined(_WIN32_WCE)
WORD wVersionRequested;
WSADATA wsaData;
int err;
if (inited) return ASN_OK;
wVersionRequested = MAKEWORD( 1, 1 );
err = WSAStartup (wVersionRequested, &wsaData);
if ( err != 0 ) {
/* Tell the user that we could not find a usable */
/* WinSock DLL. */
return ASN_E_NOTINIT;
}
inited = 1;
#elif defined (_WIN32)
LPFN_WSASTARTUP wsaStartup = NULL;
WSADATA wsaData;
if (ws32 != 0) return ASN_OK;
// ws32 = LoadLibrary ("WSOCK32.DLL");
ws32 = LoadLibrary ("WS2_32.DLL");
if (ws32 == NULL) return ASN_E_NOTINIT;
wsaStartup = (LPFN_WSASTARTUP) GetProcAddress (ws32, "WSAStartup");
if (wsaStartup == NULL) return ASN_E_NOTINIT;
send = (LPFN_SEND) GetProcAddress (ws32, "send");
if (send == NULL) return ASN_E_NOTINIT;
socket = (LPFN_SOCKET) GetProcAddress (ws32, "socket");
if (socket == NULL) return ASN_E_NOTINIT;
setsockopt = (LPFN_SETSOCKOPT) GetProcAddress (ws32, "setsockopt");
if (setsockopt == NULL) return ASN_E_NOTINIT;
bind = (LPFN_BIND) GetProcAddress (ws32, "bind");
if (bind == NULL) return ASN_E_NOTINIT;
htonl = (LPFN_HTONL) GetProcAddress (ws32, "htonl");
if (htonl == NULL) return ASN_E_NOTINIT;
htons = (LPFN_HTONS) GetProcAddress (ws32, "htons");
if (htons == NULL) return ASN_E_NOTINIT;
connect = (LPFN_CONNECT) GetProcAddress (ws32, "connect");
if (connect == NULL) return ASN_E_NOTINIT;
listen = (LPFN_LISTEN) GetProcAddress (ws32, "listen");
if (listen == NULL) return ASN_E_NOTINIT;
accept = (LPFN_ACCEPT) GetProcAddress (ws32, "accept");
if (accept == NULL) return ASN_E_NOTINIT;
inet_addr = (LPFN_INET_ADDR) GetProcAddress (ws32, "inet_addr");
if (inet_addr == NULL) return ASN_E_NOTINIT;
ntohl = (LPFN_NTOHL) GetProcAddress (ws32, "ntohl");
if (ntohl == NULL) return ASN_E_NOTINIT;
ntohs = (LPFN_NTOHS) GetProcAddress (ws32, "ntohs");
if (ntohs == NULL) return ASN_E_NOTINIT;
recv = (LPFN_RECV) GetProcAddress (ws32, "recv");
if (recv == NULL) return ASN_E_NOTINIT;
shutdown = (LPFN_SHUTDOWN) GetProcAddress (ws32, "shutdown");
if (shutdown == NULL) return ASN_E_NOTINIT;
closesocket = (LPFN_CLOSESOCKET) GetProcAddress (ws32, "closesocket");
if (closesocket == NULL) return ASN_E_NOTINIT;
sendto = (LPFN_SENDTO) GetProcAddress (ws32, "sendto");
if (sendto == NULL) return ASN_E_NOTINIT;
inet_ntoa = (LPFN_INET_NTOA) GetProcAddress (ws32, "inet_ntoa");
if (inet_ntoa == NULL) return ASN_E_NOTINIT;
recvfrom = (LPFN_RECVFROM) GetProcAddress (ws32, "recvfrom");
if (recvfrom == NULL) return ASN_E_NOTINIT;
select = (LPFN_SELECT) GetProcAddress (ws32, "select");
if (select == NULL) return ASN_E_NOTINIT;
gethostname = (LPFN_GETHOSTNAME) GetProcAddress (ws32, "gethostname");
if (gethostname == NULL) return ASN_E_NOTINIT;
gethostbyname = (LPFN_GETHOSTBYNAME) GetProcAddress (ws32, "gethostbyname");
if (gethostbyname == NULL) return ASN_E_NOTINIT;
WSAGetLastError = (LPFN_WSAGETLASTERROR) GetProcAddress (ws32,
"WSAGetLastError");
if (WSAGetLastError == NULL) return ASN_E_NOTINIT;
WSACleanup = (LPFN_WSACLEANUP) GetProcAddress (ws32, "WSACleanup");
if (WSACleanup == NULL) return ASN_E_NOTINIT;
if (wsaStartup (MAKEWORD(1, 1), &wsaData) == -1) return ASN_E_NOTINIT;
#endif
return ASN_OK;
}
#if defined (_WIN32) || \
defined(_HP_UX) || defined(__hpux) || defined(_HPUX_SOURCE)
typedef int OOSOCKLEN;
#else
typedef size_t OOSOCKLEN;
#endif
int ooSocketCreate (OOSOCKET* psocket)
{
int on;
struct linger linger;
OOSOCKET sock = socket (AF_INET,
SOCK_STREAM,
0);
if (sock == OOSOCKET_INVALID)
{
int iEC = WSAGetLastError();
return ASN_E_INVSOCKET;
}
on = 1;
if (setsockopt (sock, SOL_SOCKET, SO_REUSEADDR,
(const char* ) &on, sizeof (on)) == -1)
return ASN_E_INVSOCKET;
linger.l_onoff = 1;
linger.l_linger = 0;
if (setsockopt (sock, SOL_SOCKET, SO_LINGER,
(const char* ) &linger, sizeof (linger)) == -1)
return ASN_E_INVSOCKET;
*psocket = sock;
return ASN_OK;
}
int ooSocketCreateUDP (OOSOCKET* psocket)
{
int on;
struct linger linger;
OOSOCKET sock = socket (AF_INET,
SOCK_DGRAM,
0);
if (sock == OOSOCKET_INVALID) return ASN_E_INVSOCKET;
on = 1;
if (setsockopt (sock, SOL_SOCKET, SO_REUSEADDR,
(const char* ) &on, sizeof (on)) == -1)
return ASN_E_INVSOCKET;
linger.l_onoff = 1;
linger.l_linger = 0;
/*if (setsockopt (sock, SOL_SOCKET, SO_LINGER,
(const char* ) &linger, sizeof (linger)) == -1)
return ASN_E_INVSOCKET;
*/
*psocket = sock;
return ASN_OK;
}
int ooSocketClose (OOSOCKET socket)
{
shutdown (socket, SHUTDOWN_FLAGS);
if (closesocket (socket) == -1)
return ASN_E_INVSOCKET;
return ASN_OK;
}
int ooSocketBind (OOSOCKET socket, OOIPADDR addr, int port)
{
struct sockaddr_in m_addr;
if (socket == OOSOCKET_INVALID) return ASN_E_INVSOCKET;
memset (&m_addr, 0, sizeof (m_addr));
m_addr.sin_family = AF_INET;
m_addr.sin_addr.s_addr = (addr == 0) ? INADDR_ANY : htonl (addr);
m_addr.sin_port = htons ((unsigned short)port);
if (bind (socket, (struct sockaddr *) (void*) &m_addr,
sizeof (m_addr)) == -1)
return ASN_E_INVSOCKET;
return ASN_OK;
}
int ooSocketListen (OOSOCKET socket, int maxConnection)
{
if (socket == OOSOCKET_INVALID) return ASN_E_INVSOCKET;
if (listen (socket, maxConnection) == -1)
return ASN_E_INVSOCKET;
return ASN_OK;
}
int ooSocketAccept (OOSOCKET socket, OOSOCKET *pNewSocket,
OOIPADDR* destAddr, int* destPort)
{
struct sockaddr_in m_addr;
OOSOCKLEN addr_length = sizeof (m_addr);
if (socket == OOSOCKET_INVALID) return ASN_E_INVSOCKET;
if (pNewSocket == 0) return ASN_E_INVPARAM;
*pNewSocket = accept (socket, (struct sockaddr *) (void*) &m_addr,
&addr_length);
if (*pNewSocket <= 0) return ASN_E_INVSOCKET;
if (destAddr != 0)
*destAddr = ntohl (m_addr.sin_addr.s_addr);
if (destPort != 0)
*destPort = ntohs (m_addr.sin_port);
return ASN_OK;
}
int ooSocketConnect (OOSOCKET socket, const char* host, int port)
{
struct sockaddr_in m_addr;
if (socket == OOSOCKET_INVALID)
{
return ASN_E_INVSOCKET;
}
memset (&m_addr, 0, sizeof (m_addr));
m_addr.sin_family = AF_INET;
m_addr.sin_port = htons ((unsigned short)port);
m_addr.sin_addr.s_addr = inet_addr (host);
if (connect (socket, (struct sockaddr *) (void*) &m_addr,
sizeof (m_addr)) == -1)
{
int nEC = WSAGetLastError();
return ASN_E_INVSOCKET;
}
return ASN_OK;
}
/*
// **Need to add check whether complete data was sent by checking the return
// **value of send and if complete data is not sent then add mechanism to
// **send remaining bytes. This will make ooSocketSend call atomic.
*/
int ooSocketSend (OOSOCKET socket, const ASN1OCTET* pdata, ASN1UINT size)
{
if (socket == OOSOCKET_INVALID) return ASN_E_INVSOCKET;
if (send (socket, (const char*) pdata, size, SEND_FLAGS) == -1)
return ASN_E_INVSOCKET;
return ASN_OK;
}
int ooSocketSendTo(OOSOCKET socket, const ASN1OCTET* pdata, ASN1UINT size,
const char* host, int port)
{
struct sockaddr_in m_addr;
if (socket == OOSOCKET_INVALID) return ASN_E_INVSOCKET;
memset (&m_addr, 0, sizeof (m_addr));
m_addr.sin_family = AF_INET;
m_addr.sin_port = htons ((unsigned short)port);
m_addr.sin_addr.s_addr = inet_addr (host);
if (sendto (socket, (const char*) pdata, size, SEND_FLAGS,
(const struct sockaddr*)&m_addr,
sizeof(m_addr)) == -1)
return ASN_E_INVSOCKET;
return ASN_OK;
}
int ooSocketRecv (OOSOCKET socket, ASN1OCTET* pbuf, ASN1UINT bufsize)
{
int len;
if (socket == OOSOCKET_INVALID) return ASN_E_INVSOCKET;
if ((len = recv (socket, (char*) pbuf, bufsize, 0)) == -1)
return ASN_E_INVSOCKET;
return len;
}
int ooSocketRecvFrom (OOSOCKET socket, ASN1OCTET* pbuf, ASN1UINT bufsize,
char * remotehost, int * remoteport)
{
struct sockaddr_in m_addr;
int len, addrlen;
if (socket == OOSOCKET_INVALID) return ASN_E_INVSOCKET;
addrlen = sizeof(struct sockaddr_in);
memset (&m_addr, 0, sizeof (m_addr));
if ((len = recvfrom (socket, (char*) pbuf, bufsize, 0,
(struct sockaddr*)&m_addr, &addrlen)) == -1)
{
int nWSAECode = WSAGetLastError();
return ASN_E_INVSOCKET;
}
if(remoteport)
*remoteport = ntohs(m_addr.sin_port);
if(remotehost)
strcpy(remotehost, inet_ntoa(m_addr.sin_addr));
return len;
}
int ooSocketSelect(int nfds, fd_set *readfds, fd_set *writefds,
fd_set *exceptfds, struct timeval * timeout)
{
int ret;
#if defined (_WIN32)
ret = select(nfds, readfds, writefds, exceptfds,
(const struct timeval *) timeout);
#else
ret = select(nfds, readfds, writefds, exceptfds, timeout);
#endif
if(ret == SOCKET_ERROR)
{
int iEC = WSAGetLastError();
}
return ret;
}
int ooGetLocalIPAddress(char * pIPAddrs)
{
int ret;
struct hostent *phost;
struct in_addr addr;
char hostname[20];
if(pIPAddrs == NULL)
return -1; /* Need to find suitable return value */
ret = gethostname(hostname, 20);
if(ret == 0)
{
phost = gethostbyname(hostname);
if(phost == NULL)
return -1; /* Need to define a return value if made part of rtsrc */
memcpy(&addr, phost->h_addr_list[0], sizeof(struct in_addr));
strcpy(pIPAddrs, inet_ntoa(addr));
}
return ASN_OK;
}
int ooSocketStrToAddr (const char* pIPAddrStr, OOIPADDR* pIPAddr)
{
int b1, b2, b3, b4;
int rv = sscanf (pIPAddrStr, "%d.%d.%d.%d", &b1, &b2, &b3, &b4);
if (rv != 4 ||
(b1 < 0 || b1 > 256) || (b2 < 0 || b2 > 256) ||
(b3 < 0 || b3 > 256) || (b4 < 0 || b4 > 256))
return ASN_E_INVPARAM;
*pIPAddr = ((b1 & 0xFF) << 24) | ((b2 & 0xFF) << 16) |
((b3 & 0xFF) << 8) | (b4 & 0xFF);
return ASN_OK;
}
int ooSocketAddrToStr (OOIPADDR ipAddr, char* pbuf, int bufsize)
{
char buf1[5], buf2[5], buf3[5], buf4[5];
int cnt = 0;
if (bufsize < 8)
return ASN_E_BUFOVFLW;
cnt += sprintf (buf1, "%d", (ipAddr >> 24) & 0xFF);
cnt += sprintf (buf2, "%d", (ipAddr >> 16) & 0xFF);
cnt += sprintf (buf3, "%d", (ipAddr >> 8) & 0xFF);
cnt += sprintf (buf4, "%d", ipAddr & 0xFF);
if (bufsize < cnt + 4)
return ASN_E_BUFOVFLW;
sprintf (pbuf, "%s.%s.%s.%s", buf1, buf2, buf3, buf4);
return ASN_OK;
}
int ooSocketsCleanup (void)
{
#ifdef _WIN32
int ret = WSACleanup();
if(ret == 0)
return ASN_OK;
else
return ret;
#endif
return ASN_OK;
}
long ooHTONL(long val)
{
return htonl(val);
}
short ooHTONS(short val)
{
return htons(val);
}