130 lines
4.1 KiB
C++
130 lines
4.1 KiB
C++
// socket API wrappers
|
|
|
|
#ifndef __PRONET_H__
|
|
#define __PRONET_H__
|
|
|
|
#ifdef __NT__
|
|
# pragma pack(push)
|
|
# include <winsock2.h> // may change structure packing?!
|
|
# pragma pack(pop)
|
|
#else // __NT__
|
|
# include <errno.h>
|
|
# include <sys/socket.h>
|
|
# include <sys/select.h>
|
|
#endif
|
|
|
|
#ifdef __NT__
|
|
#pragma comment(lib, "WS2_32.lib")
|
|
#endif
|
|
|
|
/*! \file pronet.h
|
|
|
|
\brief Network related functions
|
|
|
|
Each of the following functions work just like their C standard equivalent, only
|
|
they are safer and system independent.
|
|
*/
|
|
|
|
//---------------------------------------------------------------------------
|
|
#ifdef __NT__
|
|
# define SIG_SAFE_CALL(expr) return expr
|
|
# define SOCKLEN_T int
|
|
# define SOCKBUF_T char *
|
|
#else
|
|
# define SIG_SAFE_CALL(expr) \
|
|
do \
|
|
{ \
|
|
long rc = expr; \
|
|
if ( rc != -1 || errno != EINTR ) \
|
|
return rc; \
|
|
} \
|
|
while ( true )
|
|
# define SOCKLEN_T socklen_t
|
|
# define SOCKBUF_T void *
|
|
#endif
|
|
|
|
//---------------------------------------------------------------------------
|
|
inline ssize_t qsendto(int socket, const SOCKBUF_T buf, size_t size, int flags, const struct sockaddr *dest_addr, SOCKLEN_T addrlen)
|
|
{
|
|
SIG_SAFE_CALL(::sendto(socket, buf, size, flags, dest_addr, addrlen));
|
|
}
|
|
|
|
//---------------------------------------------------------------------------
|
|
inline ssize_t qrecvfrom(int socket, SOCKBUF_T buf, size_t size, int flags, struct sockaddr *src_addr, SOCKLEN_T *addrlen)
|
|
{
|
|
SIG_SAFE_CALL(::recvfrom(socket, buf, size, flags, src_addr, addrlen));
|
|
}
|
|
|
|
//---------------------------------------------------------------------------
|
|
inline ssize_t qsend(int socket, const void *buf, size_t size)
|
|
{
|
|
#ifdef __NT__
|
|
return qsendto(socket, (SOCKBUF_T)buf, size, 0, NULL, 0);
|
|
#else
|
|
SIG_SAFE_CALL(::send(socket, buf, size, 0));
|
|
#endif
|
|
}
|
|
|
|
//---------------------------------------------------------------------------
|
|
inline ssize_t qrecv(int socket, void *buf, size_t size)
|
|
{
|
|
#ifdef __NT__
|
|
return qrecvfrom(socket, (SOCKBUF_T)buf, size, 0, NULL, NULL);
|
|
#else
|
|
SIG_SAFE_CALL(::recv(socket, buf, size, 0));
|
|
#endif
|
|
}
|
|
|
|
//---------------------------------------------------------------------------
|
|
inline int qselect(int nflds, fd_set *rds, fd_set *wds, fd_set *eds, struct timeval *timeout)
|
|
{
|
|
SIG_SAFE_CALL(::select(nflds, rds, wds, eds, timeout));
|
|
}
|
|
|
|
//---------------------------------------------------------------------------
|
|
// Prevent using of the socket functions directly
|
|
// (compiler diagnostics: call of overloaded ... is ambiguous)
|
|
namespace DONT_USE_FUNCS
|
|
{
|
|
inline ssize_t sendto(int, const SOCKBUF_T, size_t, int, const struct sockaddr *, SOCKLEN_T) { return 0; }
|
|
inline ssize_t recvfrom(int, SOCKBUF_T, size_t, int, struct sockaddr *, SOCKLEN_T *) { return 0; }
|
|
inline ssize_t send(int, const SOCKBUF_T, size_t, int) { return 0; }
|
|
inline ssize_t recv(int, SOCKBUF_T, size_t, int) { return 0; }
|
|
inline int select(int, fd_set *, fd_set *, fd_set *, struct timeval *) { return 0; }
|
|
}
|
|
using namespace DONT_USE_FUNCS;
|
|
|
|
//-------------------------------------------------------------------------
|
|
/// Get the IPv4 or IPv6 address corresponding to the given host.
|
|
///
|
|
/// \param out should be of type 'sockaddr_in' or 'sockaddr_in6', depending
|
|
/// on the value of 'family'.
|
|
/// \param name the host name.
|
|
/// \param family either AF_INET or AF_INET6.
|
|
/// \param port a port number, or 0 for none.
|
|
/// \return true on success, false otherwise
|
|
idaman bool ida_export qhost2addr_(
|
|
void *out,
|
|
const char *name,
|
|
ushort family,
|
|
ushort port = 0);
|
|
|
|
//-------------------------------------------------------------------------
|
|
inline bool qhost2addr(struct sockaddr_in *out, const char *name, ushort port = 0)
|
|
{
|
|
return qhost2addr_(out, name, AF_INET, port);
|
|
}
|
|
|
|
//-------------------------------------------------------------------------
|
|
inline bool qhost2addr(struct sockaddr_in6 *out, const char *name, ushort port = 0)
|
|
{
|
|
return qhost2addr_(out, name, AF_INET6, port);
|
|
}
|
|
|
|
|
|
#undef SIG_SAFE_CALL
|
|
#undef SOCKLEN_T
|
|
#undef SOCKBUF_T
|
|
|
|
#endif // __PRONET_H__
|