|
@@ -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
|
|
@@ -81,6 +93,7 @@ UdpSocket::UdpSocket(
|
|
|
#endif
|
|
|
#ifdef IPV6_MTU_DISCOVER
|
|
|
no = 0; setsockopt(_sock,IPPROTO_IPV6,IPV6_MTU_DISCOVER,&no,sizeof(no));
|
|
|
+#endif
|
|
|
#endif
|
|
|
|
|
|
struct sockaddr_in6 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,12 +116,17 @@ 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));
|
|
|
#endif
|
|
|
#ifdef IP_MTU_DISCOVER
|
|
|
no = 0; setsockopt(_sock,IPPROTO_IP,IP_MTU_DISCOVER,&no,sizeof(no));
|
|
|
+#endif
|
|
|
#endif
|
|
|
|
|
|
struct sockaddr_in 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
|
|
|
}
|
|
|
}
|
|
|
|