diff options
Diffstat (limited to 'node/UdpSocket.cpp')
-rw-r--r-- | node/UdpSocket.cpp | 47 |
1 files changed, 45 insertions, 2 deletions
diff --git a/node/UdpSocket.cpp b/node/UdpSocket.cpp index d1eb87d6..dfe2b11d 100644 --- a/node/UdpSocket.cpp +++ b/node/UdpSocket.cpp @@ -30,13 +30,16 @@ #include <stdlib.h> #include <fcntl.h> #include <errno.h> -#include <sys/socket.h> #include <sys/types.h> -#include <arpa/inet.h> +#include <sys/stat.h> #ifdef _WIN32 #include <Windows.h> +#include <WinSock2.h> +#include <WS2tcpip.h> #else +#include <sys/socket.h> +#include <arpa/inet.h> #include <unistd.h> #include <signal.h> #endif @@ -61,7 +64,11 @@ UdpSocket::UdpSocket( _sock(0), _v6(ipv6) { +#ifdef __WINDOWS__ + BOOL yes,no; +#else int yes,no; +#endif if ((localPort <= 0)||(localPort > 0xffff)) throw std::runtime_error("port is out of range"); @@ -71,6 +78,11 @@ UdpSocket::UdpSocket( if (_sock <= 0) throw std::runtime_error("unable to create IPv6 SOCK_DGRAM socket"); +#ifdef __WINDOWS__ + yes = TRUE; setsockopt(_sock,IPPROTO_IPV6,IPV6_V6ONLY,(const char *)&yes,sizeof(yes)); + no = FALSE; setsockopt(_sock,SOL_SOCKET,SO_REUSEADDR,(const char *)&no,sizeof(no)); + no = FALSE; setsockopt(_sock,IPPROTO_IPV6,IPV6_DONTFRAG,(const char *)&no,sizeof(no)); +#else yes = 1; setsockopt(_sock,IPPROTO_IPV6,IPV6_V6ONLY,(void *)&yes,sizeof(yes)); no = 0; setsockopt(_sock,SOL_SOCKET,SO_REUSEADDR,(void *)&no,sizeof(no)); #ifdef IP_DONTFRAG @@ -82,6 +94,7 @@ UdpSocket::UdpSocket( #ifdef IPV6_MTU_DISCOVER no = 0; setsockopt(_sock,IPPROTO_IPV6,IPV6_MTU_DISCOVER,&no,sizeof(no)); #endif +#endif struct sockaddr_in6 sin6; memset(&sin6,0,sizeof(sin6)); @@ -91,7 +104,11 @@ UdpSocket::UdpSocket( memcpy(&(sin6.sin6_addr.s6_addr),InetAddress::LO6.rawIpData(),16); else memcpy(&(sin6.sin6_addr),&in6addr_any,sizeof(struct in6_addr)); if (::bind(_sock,(const struct sockaddr *)&sin6,sizeof(sin6))) { +#ifdef __WINDOWS__ + ::closesocket(_sock); +#else ::close(_sock); +#endif throw std::runtime_error("unable to bind to port"); } } else { @@ -99,6 +116,10 @@ UdpSocket::UdpSocket( if (_sock <= 0) throw std::runtime_error("unable to create IPv4 SOCK_DGRAM socket"); +#ifdef __WINDOWS__ + no = FALSE; setsockopt(_sock,SOL_SOCKET,SO_REUSEADDR,(const char *)&no,sizeof(no)); + no = FALSE; setsockopt(_sock,IPPROTO_IP,IP_DONTFRAGMENT,(const char *)&no,sizeof(no)); +#else no = 0; setsockopt(_sock,SOL_SOCKET,SO_REUSEADDR,(void *)&no,sizeof(no)); #ifdef IP_DONTFRAG no = 0; setsockopt(_sock,IPPROTO_IP,IP_DONTFRAG,&no,sizeof(no)); @@ -106,6 +127,7 @@ UdpSocket::UdpSocket( #ifdef IP_MTU_DISCOVER no = 0; setsockopt(_sock,IPPROTO_IP,IP_MTU_DISCOVER,&no,sizeof(no)); #endif +#endif struct sockaddr_in sin; memset(&sin,0,sizeof(sin)); @@ -115,7 +137,11 @@ UdpSocket::UdpSocket( memcpy(&(sin.sin_addr.s_addr),InetAddress::LO4.rawIpData(),4); else sin.sin_addr.s_addr = INADDR_ANY; if (::bind(_sock,(const struct sockaddr *)&sin,sizeof(sin))) { +#ifdef __WINDOWS__ + ::closesocket(_sock); +#else ::close(_sock); +#endif throw std::runtime_error("unable to bind to port"); } } @@ -128,8 +154,13 @@ UdpSocket::~UdpSocket() int s = _sock; _sock = 0; if (s > 0) { +#ifdef __WINDOWS__ + ::shutdown(s,SD_BOTH); + ::closesocket(s); +#else ::shutdown(s,SHUT_RDWR); ::close(s); +#endif } Thread::join(_thread); } @@ -141,13 +172,25 @@ bool UdpSocket::send(const InetAddress &to,const void *data,unsigned int len,int if (to.isV6()) { if (!_v6) return false; +#ifdef __WINDOWS__ + DWORD hltmp = (DWORD)hopLimit; + setsockopt(_sock,IPPROTO_IPV6,IPV6_UNICAST_HOPS,(const char *)&hltmp,sizeof(hltmp)); + return ((int)sendto(_sock,(const char *)data,len,0,to.saddr(),to.saddrLen()) == (int)len); +#else setsockopt(_sock,IPPROTO_IPV6,IPV6_UNICAST_HOPS,&hopLimit,sizeof(hopLimit)); return ((int)sendto(_sock,data,len,0,to.saddr(),to.saddrLen()) == (int)len); +#endif } else { if (_v6) return false; +#ifdef __WINDOWS__ + DWORD hltmp = (DWORD)hopLimit; + setsockopt(_sock,IPPROTO_IP,IP_TTL,(const char *)&hltmp,sizeof(hltmp)); + return ((int)sendto(_sock,(const char *)data,len,0,to.saddr(),to.saddrLen()) == (int)len); +#else setsockopt(_sock,IPPROTO_IP,IP_TTL,&hopLimit,sizeof(hopLimit)); return ((int)sendto(_sock,data,len,0,to.saddr(),to.saddrLen()) == (int)len); +#endif } } |