Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Fix for Windows

  • Loading branch information...
commit ef52d4a20ab205b2775387078b077f74c5a549c7 1 parent 455749c
@jselbie authored
View
2  HISTORY
@@ -17,5 +17,5 @@ Version 1.2.2 - Fixed regression with regards to compiling with 32-bit clang++
Version 1.2.3 - Globally disable SIGPIPE
-
+Version 1.2.4 - Fix a socket bug unique to Windows.
View
4 README
@@ -1,6 +1,6 @@
STUNTMAN - An open source STUN server
-Version 1.2.3
-March 15, 2013
+Version 1.2.4
+April 24, 2013
---------------------------------------------------------
View
174 resources/README
@@ -1,174 +0,0 @@
-STUNTMAN - An open source STUN server
-Version 1.2.3
-March 15, 2013
----------------------------------------------------------
-
-
-Features:
-
- Compliant with the latest RFCs including 5389, 5769, and 5780. Also includes
- backwards compatibility for RFC 3489.
-
- Supports both UDP and TCP on both IPv4 and IPv6.
-
- Client test app provided.
-
- Stun server can operate in "full" mode as well as "basic" mode. Basic mode
- configures the server to listen on one port and respond to STUN binding
- requests. Full mode configures the service to listen on two different IP
- address interfaces (if available) and provide NAT behavior and filtering
- detection support for clients.
-
- Support for running a full mode STUN service on an Amazon EC2 instance. Run
- "stunserver --help" for visit www.stunprotocol.org on how to configure this
- mode.
-
- Open source Apache license. See LICENSE file fore more details.
----------------------------------------------------------
-
-
-Known issues:
-
- TLS mode has yet to be implemented.
-
- Server does not honor the stun padding attribute. If someone really wants
- this support, let me know and I will consider adding it.
-
- By default, the stun server operates in an open mode without performing
- authentication. All the code for authentication, challenge-response, message
- hashing, and message integrity attributes are fully coded. HMAC/SHA1/MD5
- hashing code for generating and validating the message integrity attribute
- has been implemented and tested. However, the code for validating a username
- or looking up a password is outside the scope of this release. Instead,
- hooks are provided for implementors to write their own code to validate a
- username, fetch a password, and allow/deny a request. Details of writing
- your own authentication provider code are described in the file
- "server/sampleauthprovider.h".
-
- Dependency checking is not implemented in the Makefile. So if you need to
- recompile, I recommend "make clean" from the root to preceed any subsequent
- "make" call.
-
- If you run an instance of stunserver locally, you may observe that
- "stunclient localhost" may not successfully work. This is because the server
- is not listening on the loopback adapter when running in full mode. The
- workaround is to specify the actual IP address that the server is listening
- on. Type "ifconfig" to discover your IP address (e.g. 10.11.12.13) followed
- by "stunclient 10.11.12.13"
----------------------------------------------------------
-
-
-Testing:
-
- Fedora 15 with gcc/g++ 4.6.0
- Fedora 17 with gcc/g++ 4.72
- Ubuntu 11 with gcc/g++ 4.5.2
- Ubuntu 12 with gcc/g++ 4.6.3
- Ubuntu 12 with clang/clang++ 3.0
- 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++)
- MacOS Lion (with Clang compiler)
- FreeBSD 9.0 with gcc/g++ 4.2.1
- Solaris 11 with gcc/g++ 4.5.2
-
- Parsing code has been fuzz tested with zzuf. http://caca.zoy.org/wiki/zzuf
----------------------------------------------------------
-
-
-Prerequisites before compiling and running.
-
- The short summary is that you need a C++ compiler (g++ preferred or
- clang++), GNU make, Boost header files, and the OpenSSL development files in
- order to compile the code. Below are the set of package installer commands
- that you can type from the command line to get the tools and libraries you
- need.
-
- Debian/Ubuntu/Mint
- sudo apt-get install g++
- sudo apt-get install make
- sudo apt-get install libboost-dev # For Boost
- sudo apt-get install libssl-dev # For OpenSSL
-
- RedHat/Fedora and EC2 Amazon Linux AMI
- sudo yum groupinstall "Development Tools" # For g++, make, et. al.
- sudo yum install boost-devel # For Boost
- sudo yum install openssl-devel # For OpenSSL
-
- Solaris and Mac
- OpenSSL is already installed.
-
- Install Boost locally as per instructions below, then uncomment and edit
- the top line of the common.inc file.
-
- Manual Boost install
- The compiled Boost runtime is not necessary. Just obtaining and unpacking
- the Boost source code distribution from www.boost.org will suffice. If you
- do not have the adminstrative privaleges to install the Boost distribution
- into a standard system include path, you may uncomment and edit the top
- line of the common.inc file for the BOOST_INCLUDE variable. The common.inc
- file is in the same folder as this README file.
-
- Manual OpenSSL install
- You can obtain the OpenSSL development files and runtime from
- www.openssl.org. On most systems with development tools already installed,
- OpenSSL include files are already installed in the standard include path.
- If this is not the case, you can uncomment and edit the common.inc file to
- have the OPENSSL_INCLUDE variable defined.
-
- Other prerequisites
- pthreads and perl. I've never come across a system where this wasn't
- already pre-installed.
-
----------------------------------------------------------
-
-
-Compiling and running
-
- Got Boost and OpenSSL taken care of as described above? Good. Just type
- "make" (or "gmake" on some systems). There will be three resulting binaries
- in the root of the source code package produced.
-
- stuntestcode - This is the unit test code. I highly recommend you run this
- program first. When run, you'll see a series of lines being printed in
- regards to different code paths being tested. If you see any line that ends
- in "FAIL", we likely have a bug. Please contact me immediately if you see
- this.
-
- stunserver - this is the server binary. Run "./stunserver --help" for
- details on running this program. Running this program without any command
- line arguments defaults to listening on port 3478 on all adapters.
-
- stunclient - this is the client test binary. Run "./stunclient --help" for
- details on running this program. Example: "./stunclient stun.selbie.com"
----------------------------------------------------------
-
-
-Firewall
-
- Don't forget to configure your firewall to allow traffic for the local ports
- the stunserver will be listening on!
-
----------------------------------------------------------
-
-
-Feature roadmap (the features I want to implement in a subsequent release)
-
- Cleanup Makefile and add "configure" and autotools support
-
- Finish Windows port and able to run as a Windows service
-
- Scale across more than one CPU (for multi-core and multi-proc machines). The
- threading code has already been written, just needs some finish work.
-
- TLS support
-
----------------------------------------------------------
-
-
-Contact the author
-
- John Selbie
- john@selbie.com
-
-
View
4 resources/readme.src
@@ -1,6 +1,6 @@
STUNTMAN - An open source STUN server
-Version 1.2.3
-March 15, 2013
+Version 1.2.4
+April 24, 2013
---------------------------------------------------------
View
15 server/stunsocketthread.cpp
@@ -169,7 +169,20 @@ HRESULT CStunSocketThread::SignalForStop(bool fPostMessages)
ASSERT(_socks[index] != NULL);
- ::CSocketAddress addr(_socks[index]->GetLocalAddress());
+ CSocketAddress addr(_socks[index]->GetLocalAddress());
+
+
+ // If no specific adapter was binded to, IP will be 0.0.0.0
+ // Linux evidently treats 0.0.0.0 IP as loopback (and works)
+ // On Windows you can't send to 0.0.0.0. sendto will fail - switch to sending to localhost
+ if (addr.IsIPAddressZero())
+ {
+ CSocketAddress addrLocal;
+ CSocketAddress::GetLocalHost(addr.GetFamily(), &addrLocal);
+ addrLocal.SetPort(addr.GetPort());
+ addr = addrLocal;
+ }
+
::sendto(_socks[index]->GetSocketHandle(), &data, 1, 0, addr.GetSockAddr(), addr.GetSockAddrLength());
}
}
View
37 stuncore/socketaddress.cpp
@@ -66,12 +66,12 @@ CSocketAddress::CSocketAddress(const sockaddr_in& addr4)
_address.addr4 = addr4;
}
-CSocketAddress::CSocketAddress(uint32_t ip, uint16_t port)
+CSocketAddress::CSocketAddress(uint32_t ipHostByteOrder, uint16_t port)
{
sockaddr_in addr = {};
addr.sin_family = AF_INET;
addr.sin_port = htons(port);
- addr.sin_addr.s_addr = htonl(ip);
+ addr.sin_addr.s_addr = htonl(ipHostByteOrder);
_address.addr4 = addr;
}
@@ -333,3 +333,36 @@ HRESULT CSocketAddress::ToStringBuffer(char* pszAddrBytes, size_t length) const
+HRESULT CSocketAddress::GetLocalHost(uint16_t family, CSocketAddress* pAddr)
+{
+
+ if ( ((family != AF_INET) && (family != AF_INET6)) ||
+ (pAddr == NULL))
+ {
+ ASSERT(false);
+ return E_FAIL;
+ }
+
+ if (family == AF_INET)
+ {
+ uint32_t ip = 0x7f000001; // 127.0.0.1 in host byte order
+ *pAddr = CSocketAddress(ip, 0);
+ }
+ else
+ {
+ sockaddr_in6 addr6;
+ COMPILE_TIME_ASSERT(sizeof(addr6.sin6_addr) == 16);
+
+ // ::1
+ uint8_t ip6[16] = {};
+ ip6[15] = 1;
+
+
+ addr6.sin6_family = AF_INET6;
+ memcpy(&addr6.sin6_addr, ip6, 16);
+ *pAddr = CSocketAddress(addr6);
+ }
+
+ return S_OK;
+}
+
View
6 stuncore/socketaddress.h
@@ -45,7 +45,9 @@ class CSocketAddress
CSocketAddress(const sockaddr_in& addr);
CSocketAddress(const sockaddr_in6& addr6);
- CSocketAddress(uint32_t ip, uint16_t port);
+
+ // both IP and PORT are passed in HOST BYTE ORDER
+ CSocketAddress(uint32_t ipHostByteOrder, uint16_t port);
uint16_t GetPort() const;
@@ -73,6 +75,8 @@ class CSocketAddress
void ToString(std::string* pStr) const;
HRESULT ToStringBuffer(char* pszAddrBytes, size_t length) const;
+
+ static HRESULT GetLocalHost(uint16_t family, CSocketAddress* pAddr);
};
Please sign in to comment.
Something went wrong with that request. Please try again.