12#include <sys/resource.h>
18#define RESIPROCATE_SUBSYSTEM Subsystem::TRANSPORT
24 unsigned long noBlock = 1;
25 int errNoBlock = ioctlsocket( fd, FIONBIO , &noBlock );
26 if ( errNoBlock != 0 )
31 int flags = fcntl( fd, F_GETFL, 0);
32 int errNoBlock = fcntl(fd, F_SETFL,
flags | O_NONBLOCK );
33 if ( errNoBlock != 0 )
46 unsigned long noBlock = 0;
47 int errNoBlock = ioctlsocket( fd, FIONBIO , &noBlock );
48 if ( errNoBlock != 0 )
53 int flags = fcntl( fd, F_GETFL, 0);
54 int errNoBlock = fcntl(fd, F_SETFL,
flags & ~O_NONBLOCK );
55 if ( errNoBlock != 0 )
68#ifdef REQUIRE_SO_NOSIGPIPE
70 if ( ::setsockopt ( fd, SOL_SOCKET, SO_NOSIGPIPE, (
const char*)&on,
sizeof(on)) )
73 ErrLog (<<
"Couldn't set sockoption SO_NOSIGPIPE: " <<
strError(e));
91 WORD wVersionRequested = MAKEWORD( 2, 2 );
95 err = WSAStartup( wVersionRequested, &wsaData );
110 if ( LOBYTE( wsaData.wVersion ) != 2 ||
111 HIBYTE( wsaData.wVersion ) != 2 )
130 return closesocket(fd);
137 int ret = ::close(fd);
140 InfoLog (<<
"Failed to shutdown socket " << fd <<
" : " <<
strError(errno));
151 int errNumSize =
sizeof(errNum);
152 getsockopt(fd, SOL_SOCKET, SO_ERROR, (
char *)&errNum, (socklen_t *)&errNumSize);
169 if (getrlimit(RLIMIT_NOFILE, &lim) < 0)
174 if (lim.rlim_cur==RLIM_INFINITY || targetFds < lim.rlim_cur)
179 int euid = geteuid();
180 if (lim.rlim_max==RLIM_INFINITY || targetFds < lim.rlim_max)
182 lim.rlim_cur=targetFds;
188 CritLog(<<
"Attempting to increase number of fds when not root. This probably wont work");
190 lim.rlim_cur=targetFds;
191 lim.rlim_max=targetFds;
194 if (setrlimit(RLIMIT_NOFILE, &lim) < 0)
196 CritLog(<<
"setrlimit(NOFILE)=(c="<<lim.rlim_cur<<
",m="<<lim.rlim_max
197 <<
",uid="<<euid<<
") failed: " <<
strError(errno));
218 int wbuflen = buflen;
220 if (::setsockopt (fd, SOL_SOCKET, SO_RCVBUF, &wbuflen,
sizeof(wbuflen)) == -1)
222 if (::setsockopt (fd, SOL_SOCKET, SO_RCVBUF, (
const char*)&wbuflen,
sizeof(wbuflen)) == -1)
229 unsigned optlen =
sizeof(rbuflen);
230 if (getsockopt(fd, SOL_SOCKET, SO_RCVBUF, (
char *)&rbuflen, (socklen_t *)&optlen) == -1)
235 if (rbuflen < buflen)
250 int lastgoodset = 0, lastgoodget=0;
253 for (; ; trylen /= 2)
257 ErrLog(<<
"setsockopt(SO_RCVBUF) failed");
262 lastgoodset = trylen;
269 unsigned step = trylen/10;
270 for ( ; trylen<goal; trylen+=step)
276 lastgoodset = trylen;
279 if (lastgoodset < goal)
281 ErrLog(<<
"setsockopt(SO_RCVBUF) goal "<<goal<<
" not met (set="
282 <<lastgoodset<<
",get="<<lastgoodget<<
")");
286 InfoLog(<<
"setsockopt(SO_RCVBUF) goal "<<goal<<
" met (set="
287 <<lastgoodset<<
",get="<<lastgoodget<<
")");
294 const bool isV6 = (version ==
V6);
295 const int level = isV6 ? IPPROTO_IPV6 : IPPROTO_IP;
296 const int option = isV6 ? IPV6_TCLASS : IP_TOS;
297 const char* optionName = isV6 ?
"IPV6_TCLASS" :
"IP_TOS";
301 if (dscp < 0 || dscp > 63)
303 ErrLog(<<
"DSCP class " << dscp <<
" out of range 0..63 on fd " << fd);
307 const int tos = dscp << 2;
309 if (::setsockopt(fd, level, option, (
const char *)&tos,
sizeof(tos)) == -1)
314 StackLog(<<
"setsockopt(" << optionName <<
", " << tos <<
") failed on fd " << fd
324 const bool isV6 = (version ==
V6);
325 const int level = isV6 ? IPPROTO_IPV6 : IPPROTO_IP;
326 const int option = isV6 ? IPV6_TCLASS : IP_TOS;
329 socklen_t optlen =
sizeof(tos);
330 if (::getsockopt(fd, level, option, (
char *)&tos, &optlen) == -1)
334 StackLog(<<
"getsockopt(" << (isV6 ?
"IPV6_TCLASS" :
"IP_TOS")
335 <<
") failed on fd " << fd <<
": error " << e);
346 return (tos < 0) ? -1 : (tos >> 2);
#define resip_assert(x)
This file needs to work for both C and C++ code.
static int trySetRcvBuf(Socket fd, int buflen)
Some OSs (Linux in particular) silently ignore requests to set too big and do not return an error cod...
Handles cross-platform sockets compatibility.
static const struct nv flags[]
This file is used to handle compatibility fixes/tweaks so reSIProcate can function on multiple platfo...
dcm! – add UnusedChecking(_enum) below;
bool makeSocketBlocking(Socket fd)
int getSocketError(Socket fd)
int getSocketDscp(Socket fd, IpVersion version)
The DSCP class of {fd}, which is getSocketTos() without the ECN bits.
int increaseLimitFds(unsigned int targetFds)
Returns negative on error, or number of (positive) allowed fds.
bool configureConnectedSocket(Socket fd)
void initNetwork()
set up network - does nothing in unix but needed for windows
int closeSocket(Socket fd)
int setSocketDscp(Socket fd, int dscp, IpVersion version)
Sets the DSCP class of {fd}, in the IPv4 ToS byte or the IPv6 traffic class, and reads it back.
int setSocketRcvBufLen(Socket fd, int buflen)
std::string strError(int err)
int getSocketTos(Socket fd, IpVersion version)
Reads the IPv4 ToS byte, or the IPv6 traffic class, of {fd}.
IpVersion
An enumeration of IP versions.
bool makeSocketNonBlocking(Socket fd)