/*- * Copyright 2005-2007 Guram Dukashvili * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ //--------------------------------------------------------------------------- #ifndef _scktintf_H_ #define _scktintf_H_ //--------------------------------------------------------------------------- namespace ksock { //--------------------------------------------------------------------------- ///////////////////////////////////////////////////////////////////////////// //--------------------------------------------------------------------------- class API { friend void ksys::initialize(int,char **); friend void ksys::cleanup(); public: #if defined(__WIN32__) || defined(__WIN64__) #ifdef USE_STATIC_SOCKET_LIBRARY int WSAGetLastError(void){ return ::WSAGetLastError(); } void WSASetLastError(int iError){ ::WSASetLastError(iError); } int WSAStartup(WORD wVersionRequested,LPWSADATA lpWSAData){ return ::WSAStartup(wVersionRequested,lpWSAData); } int WSACleanup(void){ return ::WSACleanup(); } int WSAAsyncSelect(SOCKET s, HWND hWnd, unsigned int wMsg, long lEvent){ return ::WSAAsyncSelect(s,hWnd,wMsg,lEvent); } SOCKET socket(int domain, int type, int protocol){ return ::socket(domain,type,protocol); } int closesocket(SOCKET s){ return ::closesocket(s); } int shutdown(SOCKET s, int how){ return ::shutdown(s,how); } int bind(SOCKET s, const struct sockaddr FAR * name, socklen_t namelen){ return ::bind(s,name,namelen); } int listen(SOCKET s, int backlog){ return ::listen(s,backlog); } SOCKET accept(SOCKET s, struct sockaddr FAR * addr, socklen_t FAR * addrlen){ return ::accept(s,addr,addrlen); } int recv(SOCKET s, char FAR * buf, int len, int flags){ return ::recv(s,buf,len,flags); } int recvfrom(SOCKET s, char FAR * buf, int len, int flags, struct sockaddr FAR * from, socklen_t FAR * fromlen){ return ::recvfrom(s,buf,len,flags,from,fromlen); } int send(SOCKET s, const char FAR * buf, int len, int flags){ return ::send(s,buf,len,flags); } int sendto(SOCKET s, const char FAR * buf, int len, int flags, const struct sockaddr FAR * to, socklen_t tolen){ return ::sendto(s,buf,len,flags,to,tolen); } int getsockopt(SOCKET s, int level, int optname, char FAR * optval, socklen_t FAR * optlen){ return ::getsockopt(s,level,optname,optval,optlen); } int setsockopt(SOCKET s, int level, int optname, const char FAR * optval, socklen_t optlen){ return ::setsockopt(s,level,optname,optval,optlen); } int connect(SOCKET s,const struct sockaddr FAR * name,socklen_t namelen){ return ::connect(s,name,namelen); } u_long htonl(u_long hostlong){ return ::htonl(hostlong); } u_long ntohl(u_long netlong){ return ::ntohl(netlong); } u_short htons(u_short hostshort){ return ::htons(hostshort); } u_short ntohs(u_short netshort){ return ::ntohs(netshort); } char FAR * inet_ntoa(struct in_addr in){ return ::inet_ntoa(in); } unsigned long inet_addr(const char FAR * cp){ return ::inet_addr(cp); } int WSARecv( SOCKET s, LPWSABUF lpBuffers, DWORD dwBufferCount, LPDWORD lpNumberOfBytesRecvd, LPDWORD lpFlags, LPWSAOVERLAPPED lpOverlapped, LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionROUTINE) { return ::WSARecv( s,lpBuffers,dwBufferCount,lpNumberOfBytesRecvd,lpFlags,lpOverlapped,lpCompletionROUTINE ); } int WSASend( SOCKET s, LPWSABUF lpBuffers, DWORD dwBufferCount, LPDWORD lpNumberOfBytesSent, DWORD dwFlags, LPWSAOVERLAPPED lpOverlapped, LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionROUTINE) { return ::WSASend( s,lpBuffers,dwBufferCount,lpNumberOfBytesSent,dwFlags,lpOverlapped,lpCompletionROUTINE ); } SOCKET WSASocketA(int af, int type, int protocol, LPWSAPROTOCOL_INFOA lpProtocolInfo, GROUP g, DWORD dwFlags){ return ::WSASocketA(af,type,protocol,lpProtocolInfo,g,dwFlags); } SOCKET WSASocketW(int af, int type, int protocol,LPWSAPROTOCOL_INFOW lpProtocolInfo, GROUP g, DWORD dwFlags){ return ::WSASocketW(af,type,protocol,lpProtocolInfo,g,dwFlags); } BOOL WSAGetOverlappedResult(SOCKET s,LPWSAOVERLAPPED lpOverlapped, LPDWORD lpcbTransfer,BOOL fWait,LPDWORD lpdwFlags){ return ::WSAGetOverlappedResult(s,lpOverlapped,lpcbTransfer,fWait,lpdwFlags); } struct hostent * gethostbyname(const char * name){ return ::gethostbyname(name); } struct hostent * gethostbyaddr(const char FAR * addr,int len,int type) { return ::gethostbyaddr(addr,len,type); } int gethostname(char * name,int namelen) { return ::gethostname(name,namelen); } int WSAEventSelect(SOCKET s, WSAEVENT hEventObject,long lNetworkEvents){ return ::WSAEventSelect(s,hEventObject,lNetworkEvents); } int WSAEnumNetworkEvents(SOCKET s, WSAEVENT hEventObject,LPWSANETWORKEVENTS lpNetworkEvents){ return ::WSAEnumNetworkEvents(s,hEventObject,lpNetworkEvents); } HANDLE WSAAsyncGetHostByName(HWND hWnd,unsigned int wMsg,const char * name,char * buf,int buflen){ return WSAAsyncGetHostByName(hWnd,wMsg,name,buf,buflen); } int getaddrinfo(const char FAR * nodename,const char FAR * servname,const struct addrinfo FAR * hints,struct addrinfo FAR * FAR * res) { return ::getaddrinfo(nodename,servname,hints,res); } int GetAddrInfoA(const char FAR * nodename,const char FAR * servname,const struct addrinfo FAR * hints,struct addrinfo FAR * FAR * res) { return ::getaddrinfo(nodename,servname,hints,res); } int GetAddrInfoW(PCWSTR pNodeName,PCWSTR pServiceName,const ADDRINFOW * pHints,PADDRINFOW * ppResult) { return ::GetAddrInfoW(pNodeName,pServiceName,pHints,ppResult); } void freeaddrinfo(LPADDRINFO pAddrInfo){ ::freeaddrinfo(pAddrInfo); } void FreeAddrInfoA(LPADDRINFO pAddrInfo){ ::freeaddrinfo(pAddrInfo); } void FreeAddrInfoW(PADDRINFOW pAddrInfo) { return ::FreeAddrInfoW(pAddrInfo); } int getnameinfo(const struct sockaddr FAR * sa,socklen_t salen,char FAR * host,DWORD hostlen,char FAR * serv,DWORD servlen,int flags) { return ::getnameinfo(sa,salen,host,hostlen,serv,servlen,flags); } int GetNameInfoA(const struct sockaddr FAR * sa,socklen_t salen,char FAR * host,DWORD hostlen,char FAR * serv,DWORD servlen,int flags) { return ::getnameinfo(sa,salen,host,hostlen,serv,servlen,flags); } INT GetNameInfoW(const SOCKADDR * pSockaddr,socklen_t SockaddrLength,PWCHAR pNodeBuffer,DWORD NodeBufferSize,PWCHAR pServiceBuffer,DWORD ServiceBufferSize,INT Flags) { return ::GetNameInfoW(pSockaddr,SockaddrLength,pNodeBuffer,NodeBufferSize,pServiceBuffer,ServiceBufferSize,Flags); } int getsockname(SOCKET s,struct sockaddr * name,int * namelen) { return ::getsockname(SOCKET s,name,namelen); } int getpeername(SOCKET s,struct sockaddr* name,int* namelen) { return ::getpeername(s,name,namelen); } #else #if _MSC_VER #pragma warning(push,3) #endif struct { union { int (WSAAPI * WSAGetLastError)(void); void * p_WSAGetLastError; }; union { void (WSAAPI * WSASetLastError)(int iError); void * p_WSASetLastError; }; union { int (WSAAPI * WSAStartup)(WORD wVersionRequested, LPWSADATA lpWSAData); void * p_WSAStartup; }; union { int (WSAAPI * WSACleanup)(void); void * p_WSACleanup; }; union { int (WSAAPI * WSAAsyncSelect)(SOCKET s, HWND hWnd, unsigned int wMsg, long lEvent); void * p_WSAAsyncSelect; }; union { SOCKET (WSAAPI * socket)(int domain, int type, int protocol); void * p_socket; }; union { int (WSAAPI * closesocket)(SOCKET s); void * p_closesocket; }; union { int (WSAAPI * shutdown)(SOCKET s, int how); void * p_shutdown; }; union { int (WSAAPI * bind)(SOCKET s, const struct sockaddr FAR * name, socklen_t namelen); void * p_bind; }; union { int (WSAAPI * listen)(SOCKET s, int backlog); void * p_listen; }; union { SOCKET (WSAAPI * accept)(SOCKET s, struct sockaddr FAR * addr, socklen_t FAR * addrlen); void * p_accept; }; union { int (WSAAPI * recv)(SOCKET s, char FAR * buf, int len, int flags); void * p_recv; }; union { int (WSAAPI * recvfrom)(SOCKET s, char FAR * buf, int len, int flags, struct sockaddr FAR * from, socklen_t FAR * fromlen); void * p_recvfrom; }; union { int (WSAAPI * send)(SOCKET s, const char FAR * buf, int len,int flags); void * p_send; }; union { int (WSAAPI * sendto)(SOCKET s, const char FAR * buf, int len, int flags, const struct sockaddr FAR * to, socklen_t tolen); void * p_sendto; }; union { int (WSAAPI * getsockopt)(SOCKET s, int level, int optname, char FAR * optval, socklen_t FAR * optlen); void * p_getsockopt; }; union { int (WSAAPI * setsockopt)(SOCKET s, int level, int optname, const char FAR * optval, socklen_t optlen); void * p_setsockopt; }; union { int (WSAAPI * connect)(SOCKET s, const struct sockaddr FAR * name, socklen_t namelen); void * p_connect; }; union { u_long (WSAAPI * htonl)(u_long hostlong); void * p_htonl; }; union { u_long (WSAAPI * ntohl)(u_long netlong); void * p_ntohl; }; union { u_short (WSAAPI * htons)(u_short hostshort); void * p_htons; }; union { u_short (WSAAPI * ntohs)(u_short netshort); void * p_ntohs; }; union { char FAR * (WSAAPI * inet_ntoa)(struct in_addr in); void * p_inet_ntoa; }; union { unsigned long (WSAAPI * inet_addr)(const char FAR * cp); void * p_inet_addr; }; union { int (WSAAPI * WSARecv)( SOCKET s, LPWSABUF lpBuffers, DWORD dwBufferCount, LPDWORD lpNumberOfBytesRecvd, LPDWORD lpFlags, LPWSAOVERLAPPED lpOverlapped, LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionROUTINE); void * p_WSARecv; }; union { int (WSAAPI * WSASend)( SOCKET s, LPWSABUF lpBuffers, DWORD dwBufferCount, LPDWORD lpNumberOfBytesSent, DWORD dwFlags, LPWSAOVERLAPPED lpOverlapped, LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionROUTINE); void * p_WSASend; }; union { SOCKET (WSAAPI * WSASocketA)( int af, int type, int protocol, LPWSAPROTOCOL_INFOA lpProtocolInfo, GROUP g, DWORD dwFlags); void * p_WSASocketA; }; union { SOCKET (WSAAPI * WSASocketW)( int af, int type, int protocol, LPWSAPROTOCOL_INFOW lpProtocolInfo, GROUP g, DWORD dwFlags); void * p_WSASocketW; }; union { BOOL (WSAAPI * WSAGetOverlappedResult)( SOCKET s, LPWSAOVERLAPPED lpOverlapped, LPDWORD lpcbTransfer, BOOL fWait, LPDWORD lpdwFlags); void * p_WSAGetOverlappedResult; }; union { struct hostent * (WSAAPI * gethostbyname)(const char * name); void * p_gethostbyname; }; union { struct hostent * (WSAAPI * gethostbyaddr)(const char FAR * addr,int len,int type); void * p_gethostbyaddr; }; union { int (WSAAPI * gethostname)(char * name,int namelen); void * p_gethostname; }; union { int (WSAAPI * WSAEventSelect)(SOCKET s, WSAEVENT hEventObject,long lNetworkEvents); void * p_WSAEventSelect; }; union { int (WSAAPI * WSAEnumNetworkEvents)(SOCKET s,WSAEVENT hEventObject,LPWSANETWORKEVENTS lpNetworkEvents); }; union { HANDLE (WSAAPI * WSAAsyncGetHostByName)( HWND hWnd, unsigned int wMsg, const char * name, char * buf, int buflen ); void * p_WSAAsyncGetHostByName; }; union { int (WSAAPI * getsockname)(SOCKET s,struct sockaddr * name,int * namelen); void * p_getsockname; }; union { int (WSAAPI * getpeername)(SOCKET s,struct sockaddr* name,int* namelen); void * p_getpeername; }; union { int (WSAAPI * getaddrinfo)( const char FAR * nodename, const char FAR * servname, const struct addrinfo FAR * hints, struct addrinfo FAR * FAR * res ); void * p_getaddrinfo; }; union { void (WSAAPI * freeaddrinfo)(LPADDRINFO pAddrInfo); void * p_freeaddrinfo; }; union { int (WSAAPI * getnameinfo)( const struct sockaddr FAR * sa, socklen_t salen, char FAR * host, DWORD hostlen, char FAR * serv, DWORD servlen, int flags ); void * p_getnameinfo; }; union { int (WSAAPI * GetAddrInfoW)( PCWSTR pNodeName, PCWSTR pServiceName, const ADDRINFOW * pHints, PADDRINFOW * ppResult ); void * p_GetAddrInfoW; }; union { void (WSAAPI * FreeAddrInfoW)(PADDRINFOW pAddrInfo); void * p_FreeAddrInfoW; }; union { INT (WSAAPI * GetNameInfoW)( const SOCKADDR * pSockaddr, socklen_t SockaddrLength, PWCHAR pNodeBuffer, DWORD NodeBufferSize, PWCHAR pServiceBuffer, DWORD ServiceBufferSize, INT Flags ); void * p_GetNameInfoW; }; }; #if _MSC_VER #pragma warning(pop) #endif #endif void open(); void close(); #else int socket(int domain, int type, int protocol) { return ::socket(domain, type, protocol); } int closesocket(int s) { return ::close(s); } int shutdown(int s, int how) { return ::shutdown(s, how); } int bind(int s, const struct sockaddr * name, int namelen) { return ::bind(s, name, namelen); } int listen(int s, int backlog) { return ::listen(s, backlog); } int accept(int s, struct sockaddr * addr, socklen_t * addrlen) { return ::accept(s, addr, addrlen); } int recv(int s, char * buf, int len, int flags) { return ::recv(s, buf, len, flags); } int recvfrom(int s, char * buf, int len, int flags, struct sockaddr * from, socklen_t * fromlen) { return ::recvfrom(s, buf, len, flags, from, fromlen); } int send(int s, const char * buf, int len, int flags) { return ::send(s, buf, len, flags); } int sendto(int s, const char * buf, int len, int flags, const struct sockaddr * to, socklen_t tolen) { return ::sendto(s, buf, len, flags, to, tolen); } int getsockopt(int s, int level, int optname, char * optval, socklen_t * optlen) { return ::getsockopt(s, level, optname, optval, optlen); } int setsockopt(int s, int level, int optname, const char * optval, socklen_t optlen) { return ::setsockopt(s, level, optname, optval, optlen); } int connect(int s, const struct sockaddr * name, int namelen) { return ::connect(s, name, namelen); } #undef htonl uint32_t htonl(uint32_t hostlong) { return ::htonl(hostlong); } #undef ntohl uint32_t ntohl(uint32_t netlong) { return ::ntohl(netlong); } #undef htons uint16_t htons(uint16_t hostshort) { return ::htons(hostshort); } #undef ntohs uint16_t ntohs(uint16_t netshort) { return ::ntohs(netshort); } char * inet_ntoa(struct in_addr in) { return ::inet_ntoa(in); } in_addr_t inet_addr(const char * cp) { return ::inet_addr(cp); } struct hostent * gethostbyname(const char * name) { return ::gethostbyname(name); } int getnameinfo(const struct sockaddr *sa, socklen_t salen, char *host, size_t hostlen, char *serv, size_t servlen, int flags) { return ::getnameinfo(sa,salen,host,hostlen,serv,servlen,flags); } int getaddrinfo(const char *hostname, const char *servname,const struct addrinfo *hints, struct addrinfo **res) { return ::getaddrinfo(hostname,servname,hints,res); } void freeaddrinfo(struct addrinfo *ai) { ::freeaddrinfo(ai); } int getsockname(int s,struct sockaddr * name,socklen_t * namelen) { return ::getsockname(s,name,namelen); } int getpeername(int s, struct sockaddr * name,socklen_t * namelen) { return ::getpeername(s,name,namelen); } int gethostname(char *name, size_t namelen) { return ::gethostname(name,namelen); } void open() { } void close() { } #endif static ksys::InterlockedMutex & mutex(); protected: #if defined(__WIN32__) || defined(__WIN64__) static WSADATA wsaData_; static HINSTANCE handle_; static uintptr_t count_; static const char * const symbols_[]; #endif static uint8_t mutex_[]; private: void initialize(); void cleanup(); }; //--------------------------------------------------------------------------- inline ksys::InterlockedMutex & API::mutex() { return *reinterpret_cast< ksys::InterlockedMutex *>(mutex_); } //--------------------------------------------------------------------------- #if defined(__WIN32__) || defined(__WIN64__) //--------------------------------------------------------------------------- ///////////////////////////////////////////////////////////////////////////// //--------------------------------------------------------------------------- class APIEx { friend class API; public: #ifdef USE_STATIC_SOCKET_LIBRARY BOOL AcceptEx( SOCKET sListenSocket, SOCKET sAcceptSocket, PVOID lpOutputBuffer, DWORD dwReceiveDataLength, DWORD dwLocalAddressLength, DWORD dwRemoteAddressLength, LPDWORD lpdwBytesReceived, LPOVERLAPPED lpOverlapped) { return ::AcceptEx( sListenSocket,sAcceptSocket,lpOutputBuffer,dwReceiveDataLength,dwLocalAddressLength, dwRemoteAddressLength,lpdwBytesReceived,lpOverlapped ); } VOID GetAcceptExSockaddrs( PVOID lpOutputBuffer, DWORD dwReceiveDataLength, DWORD dwLocalAddressLength, DWORD dwRemoteAddressLength, LPSOCKADDR * LocalSockaddr, LPINT LocalSockaddrLength, LPSOCKADDR * RemoteSockaddr, LPINT RemoteSockaddrLength) { return ::GetAcceptExSockaddrs( lpOutputBuffer,dwReceiveDataLength,dwLocalAddressLength,dwRemoteAddressLength, LocalSockaddr,LocalSockaddrLength,RemoteSockaddr,RemoteSockaddrLength ); } #else #if _MSC_VER #pragma warning(push,3) #endif union { struct { union { BOOL (WSAAPI * AcceptEx)(SOCKET sListenSocket, SOCKET sAcceptSocket, PVOID lpOutputBuffer, DWORD dwReceiveDataLength, DWORD dwLocalAddressLength, DWORD dwRemoteAddressLength, LPDWORD lpdwBytesReceived, LPOVERLAPPED lpOverlapped); void * p_AcceptEx; }; union { VOID (WSAAPI * GetAcceptExSockaddrs)( PVOID lpOutputBuffer, DWORD dwReceiveDataLength, DWORD dwLocalAddressLength, DWORD dwRemoteAddressLength, LPSOCKADDR * LocalSockaddr, LPINT LocalSockaddrLength, LPSOCKADDR * RemoteSockaddr, LPINT RemoteSockaddrLength); void * p_GetAcceptExSockaddrs; }; }; }; #if _MSC_VER #pragma warning(pop) #endif protected: static const char * const symbols_[]; static HINSTANCE handle_; #endif private: }; //--------------------------------------------------------------------------- extern APIEx apiEx; //--------------------------------------------------------------------------- ///////////////////////////////////////////////////////////////////////////// //--------------------------------------------------------------------------- class IPHLPAPI { friend class API; public: #if _MSC_VER #pragma warning(push,3) #endif struct { union { DWORD (WINAPI * GetAdaptersAddresses)( ULONG Family, DWORD Flags, PVOID Reserved, PIP_ADAPTER_ADDRESSES pAdapterAddresses, PULONG pOutBufLen ); void * p_GetAdaptersAddresses; }; union { DWORD (WINAPI * GetAdaptersInfo)(PIP_ADAPTER_INFO pAdapterInfo,PULONG pOutBufLen); void * p_GetAdaptersInfo; }; }; #if _MSC_VER #pragma warning(pop) #endif protected: static const char * const symbols_[]; static HINSTANCE handle_; private: }; //--------------------------------------------------------------------------- extern IPHLPAPI iphlpapi; //--------------------------------------------------------------------------- ///////////////////////////////////////////////////////////////////////////// //--------------------------------------------------------------------------- class WSHIP6API { friend class API; public: #if _MSC_VER #pragma warning(push,3) #endif struct { union { int (WSAAPI * GetAddrInfoA)( const char FAR * nodename, const char FAR * servname, const struct addrinfo FAR * hints, struct addrinfo FAR * FAR * res ); void * p_getaddrinfo; }; union { void (WSAAPI * FreeAddrInfoA)(LPADDRINFO pAddrInfo); void * p_freeaddrinfo; }; union { int (WSAAPI * GetNameInfoA)( const struct sockaddr FAR * sa, socklen_t salen, char FAR * host, DWORD hostlen, char FAR * serv, DWORD servlen, int flags ); void * p_getnameinfo; }; }; #if _MSC_VER #pragma warning(pop) #endif protected: static const char * const symbols_[]; static HINSTANCE handle_; private: }; //--------------------------------------------------------------------------- extern WSHIP6API wship6api; //--------------------------------------------------------------------------- #endif //--------------------------------------------------------------------------- extern API api; //--------------------------------------------------------------------------- ////////////////////////////////////////////////////////////////////////////// //--------------------------------------------------------------------------- class APIAutoInitializer { public: ~APIAutoInitializer() { api.close(); } APIAutoInitializer() { api.open(); } }; //--------------------------------------------------------------------------- } // namespace ksock //--------------------------------------------------------------------------- #endif /* _scktintf_H_ */ //---------------------------------------------------------------------------