Commit 25b3d600 authored by John Selbie's avatar John Selbie

BSD fixes and other stuff

parent 79c8dd28
StunServer version 1.1.0
January 22, 2012
STUNK - An open source STUN server
Version 1.1.0
February 1, 2012
---------------------------------------------------------
......@@ -60,6 +61,7 @@ Testing:
Amazon AWS with gcc/g++ 4.4
MacOS Snow Leopard (will not compile on earlier versions without updating to
a newer version of gcc/g++)
FreeBSD 9.0 with gcc/g++ 4.2.1
Parsing code has been fuzz tested with zzuf. http://caca.zoy.org/wiki/zzuf
---------------------------------------------------------
......@@ -67,17 +69,18 @@ Testing:
Prerequisites before compiling and running.
perl. Just have any old version installed. It is needed for one particular
build script.
Boost header files. (Actual boost runtime not required) www.boost.org (sudo
yum install boost-devel)
OpenSSL development files and runtime. www.boost.org (sudo yum install
OpenSSL development files and runtime. www.openssl.org (sudo yum install
openssl-devel)
pthreads header and libs (I haven't seen a distribution where this wasn't
already installed)
perl. Only needed if you rebuild the content in the resources directory.
Otherwise, not needed.
---------------------------------------------------------
......
......@@ -298,7 +298,9 @@ uint32_t CPoll::ToNativeFlags(uint32_t eventflags)
if (eventflags & IPOLLING_READ) result |= POLLIN;
if (eventflags & IPOLLING_WRITE) result |= POLLOUT;
#ifdef POLLRDHUP
if (eventflags & IPOLLING_RDHUP) result |= POLLRDHUP;
#endif
if (eventflags & IPOLLING_HUP) result |= POLLHUP;
if (eventflags & IPOLLING_PRI) result |= POLLPRI;
if (eventflags & IPOLLING_ERROR) result |= POLLERR;
......@@ -313,7 +315,9 @@ uint32_t CPoll::FromNativeFlags(uint32_t eventflags)
if (eventflags & POLLIN) result |= IPOLLING_READ;
if (eventflags & POLLOUT) result |= IPOLLING_WRITE;
#ifdef POLLRDHUP
if (eventflags & POLLRDHUP) result |= IPOLLING_RDHUP;
#endif
if (eventflags & POLLHUP) result |= IPOLLING_HUP;
if (eventflags & POLLPRI) result |= IPOLLING_PRI;
if (eventflags & POLLERR) result |= IPOLLING_ERROR;
......@@ -369,7 +373,10 @@ Cleanup:
HRESULT CPoll::Remove(int fd)
{
size_t* pPos = NULL;
// See notes below why pPos is declared volatile. Gets around a compiler bug
volatile size_t* pPos = NULL;
size_t size = _fds.size();
size_t pos;
HRESULT hr = S_OK;
......@@ -394,7 +401,13 @@ HRESULT CPoll::Remove(int fd)
{
_fds[pos] = _fds[size-1];
pPos = _hashtable.Lookup(_fds[pos].fd);
ASSERT(pPos);
ASSERT(pPos != NULL);
// If the volatile declaration above was not made, this block of code
// gets over-optimized on older GCC compilers (g++ 4.2.1 on BSD) with with -O2
// The following line would essentially not get executed.
// There are multiple workarounds, but "volatile" seems to work.
*pPos = pos;
}
......
......@@ -132,8 +132,9 @@ ssize_t recvfromex(int sockfd, void* buf, size_t len, int flags, CSocketAddress*
GetLocalPortNumberFromSocket(sockfd, pDstAddr);
break;
}
#endif
#elif defined(IP_RECVDSTADDR)
#ifdef IP_RECVDSTADDR
// This code path for MacOSX and likely BSD as well
if ((pCmsg->cmsg_level == IPPROTO_IP) && (pCmsg->cmsg_type==IP_RECVDSTADDR) && CMSG_DATA(pCmsg))
{
......@@ -144,10 +145,6 @@ ssize_t recvfromex(int sockfd, void* buf, size_t len, int flags, CSocketAddress*
GetLocalPortNumberFromSocket(sockfd, pDstAddr);
break;
}
#else
{
int fail[-1]; // set a compile time assert if there's no option
}
#endif
}
}
......
......@@ -106,32 +106,92 @@ void CStunSocket::SetRole(SocketRole role)
_role = role;
}
HRESULT CStunSocket::EnablePktInfoOption(bool fEnable)
// About the "packet info option"
// What we are trying to do is enable the socket to be able to provide the "destination address"
// for packets we receive. However, Linux, BSD, and MacOS all differ in what the
// socket option is. And it differs even differently between IPV4 and IPV6 across these operating systems.
// So we have the "try one or the other" implementation based on what's DEFINED
// On some operating systems, there's only one option defined. Other's have both, but only one works!
// So we have to try them both
HRESULT CStunSocket::EnablePktInfoImpl(int level, int option1, int option2, bool fEnable)
{
HRESULT hr = S_OK;
int enable = fEnable?1:0;
int ret;
int ret = -1;
int family = _addrlocal.GetFamily();
int level = (family==AF_INET) ? IPPROTO_IP : IPPROTO_IPV6;
ChkIfA((option1 == -1) && (option2 == -1), E_FAIL);
if (option1 != -1)
{
ret = setsockopt(_sock, level, option1, &enable, sizeof(enable));
}
if ((ret < 0) && (option2 != -1))
{
enable = fEnable?1:0;
ret = setsockopt(_sock, level, option2, &enable, sizeof(enable));
}
ChkIfA(ret < 0, ERRNOHR);
Cleanup:
return hr;
}
// if you change the ifdef's below, make sure you it's matched with the same logic in recvfromex.cpp
HRESULT CStunSocket::EnablePktInfo_IPV4(bool fEnable)
{
int level = IPPROTO_IP;
int option1 = -1;
int option2 = -1;
#ifdef IP_PKTINFO
int option = (family==AF_INET) ? IP_PKTINFO : IPV6_RECVPKTINFO;
#elif defined(IP_RECVDSTADDR)
int option = (family==AF_INET) ? IP_RECVDSTADDR : IPV6_PKTINFO;
#else
int fail[-1]; // set a compile time assert
option1 = IP_PKTINFO;
#endif
#ifdef IP_RECVDSTADDR
option2 = IP_RECVDSTADDR;
#endif
return EnablePktInfoImpl(level, option1, option2, fEnable);
}
ret = ::setsockopt(_sock, level, option, &enable, sizeof(enable));
HRESULT CStunSocket::EnablePktInfo_IPV6(bool fEnable)
{
int level = IPPROTO_IPV6;
int option1 = -1;
int option2 = -1;
// Linux documentation (man ipv6) says you are supposed to set IPV6_PKTINFO as the option
// Yet, it's really IPV6_RECVPKTINFO. Other operating systems might expect IPV6_PKTINFO.
// We'll cross that bridge, when we get to it.
// todo - we should write a unit test that tests the packet info behavior
ASSERT(ret == 0);
#ifdef IPV6_RECVPKTINFO
option1 = IPV6_RECVPKTINFO;
#endif
return (ret == 0) ? S_OK : ERRNOHR;
#ifdef IPV6_PKTINFO
option2 = IPV6_PKTINFO;
#endif
return EnablePktInfoImpl(level, option1, option2, fEnable);
}
HRESULT CStunSocket::EnablePktInfoOption(bool fEnable)
{
int family = _addrlocal.GetFamily();
HRESULT hr;
if (family == AF_INET)
{
hr = EnablePktInfo_IPV4(fEnable);
}
else
{
hr = EnablePktInfo_IPV6(fEnable);
}
return hr;
}
HRESULT CStunSocket::SetNonBlocking(bool fEnable)
......
......@@ -34,6 +34,10 @@ private:
void Reset();
HRESULT EnablePktInfoImpl(int level, int option1, int option2, bool fEnable);
HRESULT EnablePktInfo_IPV4(bool fEnable);
HRESULT EnablePktInfo_IPV6(bool fEnable);
public:
CStunSocket();
......
......@@ -19,7 +19,7 @@ textres: stunserver.txtcode stunserver_lite.txtcode stunclient.txtcode stunclien
manpages: stunserver.1 stunclient.1
README:
README: readme.src
../stuntestcode --pp < readme.src > README
clean:
......
StunServer version 1.1.0
January 22, 2012
STUNK - An open source STUN server
Version 1.1.0
February 1, 2012
---------------------------------------------------------
......@@ -60,6 +61,7 @@ Testing:
Amazon AWS with gcc/g++ 4.4
MacOS Snow Leopard (will not compile on earlier versions without updating to
a newer version of gcc/g++)
FreeBSD 9.0 with gcc/g++ 4.2.1
Parsing code has been fuzz tested with zzuf. http://caca.zoy.org/wiki/zzuf
---------------------------------------------------------
......@@ -67,17 +69,18 @@ Testing:
Prerequisites before compiling and running.
perl. Just have any old version installed. It is needed for one particular
build script.
Boost header files. (Actual boost runtime not required) www.boost.org (sudo
yum install boost-devel)
OpenSSL development files and runtime. www.boost.org (sudo yum install
OpenSSL development files and runtime. www.openssl.org (sudo yum install
openssl-devel)
pthreads header and libs (I haven't seen a distribution where this wasn't
already installed)
perl. Only needed if you rebuild the content in the resources directory.
Otherwise, not needed.
---------------------------------------------------------
......
StunServer version 1.1.0
January 22, 2012
STUNK - An open source STUN server
Version 1.1.0
February 1, 2012
---------------------------------------------------------
......@@ -37,6 +38,7 @@ Testing:
Ubuntu 11 with gcc/g++ 4.5.2
Amazon AWS with gcc/g++ 4.4
MacOS Snow Leopard (will not compile on earlier versions without updating to a newer version of gcc/g++)
FreeBSD 9.0 with gcc/g++ 4.2.1
Parsing code has been fuzz tested with zzuf. http://caca.zoy.org/wiki/zzuf
---------------------------------------------------------
......@@ -44,13 +46,14 @@ Testing:
Prerequisites before compiling and running.
perl. Just have any old version installed. It is needed for one particular build script.
Boost header files. (Actual boost runtime not required) www.boost.org (sudo yum install boost-devel)
OpenSSL development files and runtime. www.boost.org (sudo yum install openssl-devel)
OpenSSL development files and runtime. www.openssl.org (sudo yum install openssl-devel)
pthreads header and libs (I haven't seen a distribution where this wasn't already installed)
perl. Only needed if you rebuild the content in the resources directory. Otherwise, not needed.
---------------------------------------------------------
......
......@@ -59,7 +59,18 @@ void LogHR(uint16_t level, HRESULT hr)
msg[0] = '\0';
int err = (int)(HRESULT_CODE(hr));
#ifdef _GNU_SOURCE
pMsg = strerror_r(err, msg, ARRAYSIZE(msg));
#else
{
int result = strerror_r(err, msg, ARRAYSIZE(msg));
if (result == -1)
{
sprintf(msg, "%d", err);
}
pMsg = msg;
}
#endif
if (pMsg)
{
......
......@@ -17,7 +17,6 @@
#ifndef TEST_FAST_HASH_H
#define TEST_FAST_HASH_H
#include "commonincludes.h"
#include "fasthash.h"
#include "unittest.h"
......
......@@ -28,6 +28,7 @@ HRESULT CTestPolling::Run()
_polltype = IPOLLING_TYPE_POLL;
ChkA(Test1());
ChkA(Test2());
ChkA(Test3());
Cleanup:
return hr;
}
......@@ -350,3 +351,36 @@ HRESULT CTestPolling::Test2()
Cleanup:
return hr;
}
HRESULT CTestPolling::Test3()
{
HRESULT hr = S_OK;
HRESULT hrResult;
PollEvent event;
const size_t c_maxSockets = 10;
ChkA(TestInit(c_maxSockets, 0));
ChkA(_spPolling->Add(3, IPOLLING_READ));
ChkA(_spPolling->Remove(3));
ChkA(_spPolling->Add(5, IPOLLING_READ));
ChkA(_spPolling->Add(7, IPOLLING_READ));
ChkA(_spPolling->Add(9, IPOLLING_READ));
ChkA(_spPolling->Remove(5));
ChkA(_spPolling->Add(11, IPOLLING_READ));
ChkA(_spPolling->Add(13, IPOLLING_READ));
ChkA(_spPolling->Remove(7));
ChkA(_spPolling->Add(15, IPOLLING_READ));
ChkA(_spPolling->Add(17, IPOLLING_READ));
ChkA(_spPolling->Add(19, IPOLLING_READ));
ChkA(_spPolling->Remove(11));
ChkA(_spPolling->Add(21, IPOLLING_READ));
ChkA(_spPolling->Add(23, IPOLLING_READ));
ChkA(_spPolling->Add(25, IPOLLING_READ));
ChkA(_spPolling->Add(27, IPOLLING_READ));
ChkA(_spPolling->Remove(13));
Cleanup:
return hr;
}
\ No newline at end of file
......@@ -32,6 +32,7 @@ public:
HRESULT Test1();
HRESULT Test2();
HRESULT Test3();
HRESULT Run();
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment