mirror of
https://github.com/zerotier/ZeroTierOne.git
synced 2025-04-07 11:17:29 +00:00
Windows build work: condition, mutex, thread, udp socket...
This commit is contained in:
parent
2ad80063ec
commit
36af3d92ec
@ -28,9 +28,57 @@
|
||||
#ifndef _ZT_CONDITION_HPP
|
||||
#define _ZT_CONDITION_HPP
|
||||
|
||||
#include "Constants.hpp"
|
||||
#include "NonCopyable.hpp"
|
||||
|
||||
#if defined(__APPLE__) || defined(__linux__) || defined(linux) || defined(__LINUX__) || defined(__linux)
|
||||
#ifdef __WINDOWS__
|
||||
|
||||
#include <Windows.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "Utils.hpp"
|
||||
|
||||
namespace ZeroTier {
|
||||
|
||||
class Condition : NonCopyable
|
||||
{
|
||||
public:
|
||||
Condition()
|
||||
throw()
|
||||
{
|
||||
_sem = CreateSemaphore(NULL,0,1,NULL);
|
||||
}
|
||||
|
||||
~Condition()
|
||||
{
|
||||
CloseHandle(_sem);
|
||||
}
|
||||
|
||||
inline void wait() const
|
||||
throw()
|
||||
{
|
||||
WaitForSingleObject(_sem,INFINITE);
|
||||
}
|
||||
|
||||
inline void wait(unsigned long ms) const
|
||||
throw()
|
||||
{
|
||||
WaitForSingleObject(_sem,(DWORD)ms);
|
||||
}
|
||||
|
||||
inline void signal() const
|
||||
throw()
|
||||
{
|
||||
ReleaseSemaphore(_sem,1,NULL);
|
||||
}
|
||||
|
||||
private:
|
||||
HANDLE _sem;
|
||||
};
|
||||
|
||||
} // namespace ZeroTier
|
||||
|
||||
#else // !__WINDOWS__
|
||||
|
||||
#include <time.h>
|
||||
#include <stdlib.h>
|
||||
@ -88,20 +136,6 @@ private:
|
||||
|
||||
} // namespace ZeroTier
|
||||
|
||||
#endif // Apple / Linux
|
||||
|
||||
#ifdef _WIN32
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <Windows.h>
|
||||
|
||||
namespace ZeroTier {
|
||||
|
||||
error need windoze;
|
||||
// On Windows this will probably be implemented via Semaphores
|
||||
|
||||
} // namespace ZeroTier
|
||||
|
||||
#endif // _WIN32
|
||||
#endif // !__WINDOWS__
|
||||
|
||||
#endif
|
||||
|
@ -28,9 +28,10 @@
|
||||
#ifndef _ZT_MUTEX_HPP
|
||||
#define _ZT_MUTEX_HPP
|
||||
|
||||
#include "Constants.hpp"
|
||||
#include "NonCopyable.hpp"
|
||||
|
||||
#if defined(__APPLE__) || defined(__linux__) || defined(linux) || defined(__LINUX__) || defined(__linux)
|
||||
#ifdef __UNIX_LIKE__
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <pthread.h>
|
||||
@ -112,7 +113,7 @@ private:
|
||||
|
||||
#endif // Apple / Linux
|
||||
|
||||
#ifdef _WIN32
|
||||
#ifdef __WINDOWS__
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <Windows.h>
|
||||
@ -157,9 +158,6 @@ public:
|
||||
(const_cast <Mutex *> (this))->unlock();
|
||||
}
|
||||
|
||||
/**
|
||||
* Uses C++ contexts and constructor/destructor to lock/unlock automatically
|
||||
*/
|
||||
class Lock : NonCopyable
|
||||
{
|
||||
public:
|
||||
|
@ -35,7 +35,57 @@
|
||||
|
||||
#ifdef __WINDOWS__
|
||||
|
||||
todo need windows;
|
||||
#include <Windows.h>
|
||||
#include <string.h>
|
||||
|
||||
namespace ZeroTier {
|
||||
|
||||
template<typename C>
|
||||
static DWORD WINAPI ___zt_threadMain(LPVOID lpParam)
|
||||
{
|
||||
try {
|
||||
((C *)lpParam)->threadMain();
|
||||
} catch ( ... ) {}
|
||||
return 0;
|
||||
}
|
||||
|
||||
class Thread
|
||||
{
|
||||
public:
|
||||
Thread()
|
||||
throw()
|
||||
{
|
||||
_th = NULL;
|
||||
}
|
||||
|
||||
template<typename C>
|
||||
static inline Thread start(C *instance)
|
||||
throw(std::runtime_error)
|
||||
{
|
||||
Thread t;
|
||||
t._th = CreateThread(NULL,0,&___zt_threadMain<C>,(LPVOID)instance,0,&t._tid);
|
||||
if (t._th == NULL)
|
||||
throw std::runtime_error("CreateThread() failed");
|
||||
return t;
|
||||
}
|
||||
|
||||
static inline void join(const Thread &t)
|
||||
{
|
||||
if (t._th != NULL)
|
||||
WaitForSingleObject(t._th,INFINITE);
|
||||
}
|
||||
|
||||
static inline void sleep(unsigned long ms)
|
||||
{
|
||||
Sleep((DWORD)ms);
|
||||
}
|
||||
|
||||
private:
|
||||
HANDLE _th;
|
||||
DWORD _tid;
|
||||
};
|
||||
|
||||
} // namespace ZeroTier
|
||||
|
||||
#else
|
||||
|
||||
|
@ -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
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -29,6 +29,8 @@
|
||||
#define _ZT_UDPSOCKET_HPP
|
||||
|
||||
#include <stdexcept>
|
||||
|
||||
#include "Constants.hpp"
|
||||
#include "Thread.hpp"
|
||||
#include "InetAddress.hpp"
|
||||
#include "Mutex.hpp"
|
||||
|
Loading…
x
Reference in New Issue
Block a user