10 #if !defined ZMQ_HAVE_WINDOWS
12 #include <sys/types.h>
13 #include <sys/socket.h>
16 #include <netinet/in.h>
17 #include <netinet/tcp.h>
29 static bool try_ipc_first =
true;
35 #define rmdir rmdir_utf8
36 #define unlink unlink_utf8
39 #if defined ZMQ_HAVE_OPENVMS || defined ZMQ_HAVE_VXWORKS
43 #if defined ZMQ_HAVE_VXWORKS
49 #if defined ZMQ_HAVE_EVENTFD
50 #include <sys/eventfd.h>
53 #if defined ZMQ_HAVE_OPENPGM
54 #ifdef ZMQ_HAVE_WINDOWS
55 #define __PGM_WININT_H__
62 #include <TargetConditionals.h>
65 #ifndef ZMQ_HAVE_WINDOWS
68 "TMPDIR",
"TEMPDIR",
"TMP",
79 #if defined ZMQ_HAVE_SOCK_CLOEXEC
80 type_ |= SOCK_CLOEXEC;
83 #if defined ZMQ_HAVE_WINDOWS && defined WSA_FLAG_NO_HANDLE_INHERIT
86 const fd_t s = WSASocket (domain_, type_, protocol_,
NULL, 0,
87 WSA_FLAG_OVERLAPPED | WSA_FLAG_NO_HANDLE_INHERIT);
89 const fd_t s = socket (domain_, type_, protocol_);
92 #ifdef ZMQ_HAVE_WINDOWS
93 errno = wsa_error_to_errno (WSAGetLastError ());
109 #if defined ZMQ_HAVE_WINDOWS
111 const int rc = ioctlsocket (
s_, FIONBIO, &nonblock);
112 wsa_assert (rc != SOCKET_ERROR);
113 #elif defined ZMQ_HAVE_OPENVMS || defined ZMQ_HAVE_VXWORKS
115 int rc = ioctl (
s_, FIONBIO, &nonblock);
118 int flags = fcntl (
s_, F_GETFL, 0);
121 int rc = fcntl (
s_, F_SETFL,
flags | O_NONBLOCK);
130 #if defined IPV6_V6ONLY && !defined ZMQ_HAVE_OPENBSD \
131 && !defined ZMQ_HAVE_DRAGONFLY
132 #ifdef ZMQ_HAVE_WINDOWS
137 const int rc = setsockopt (
s_, IPPROTO_IPV6, IPV6_V6ONLY,
138 reinterpret_cast<char *
> (&flag),
sizeof (flag));
139 #ifdef ZMQ_HAVE_WINDOWS
140 wsa_assert (rc != SOCKET_ERROR);
149 struct sockaddr_storage ss;
155 #ifdef ZMQ_HAVE_WINDOWS
156 const int last_error = WSAGetLastError ();
157 wsa_assert (last_error != WSANOTINITIALISED && last_error != WSAEFAULT
158 && last_error != WSAEINPROGRESS
159 && last_error != WSAENOTSOCK);
160 #elif !defined(TARGET_OS_IPHONE) || !TARGET_OS_IPHONE
170 getnameinfo (
reinterpret_cast<struct sockaddr *
> (&ss), addrlen, host,
171 sizeof host,
NULL, 0, NI_NUMERICHOST);
180 struct sockaddr_storage sa_stor;
184 return static_cast<int> (u.sa.sa_family);
189 int rc = setsockopt (
s_, IPPROTO_IP, IP_TOS,
190 reinterpret_cast<char *
> (&iptos_),
sizeof (iptos_));
192 #ifdef ZMQ_HAVE_WINDOWS
193 wsa_assert (rc != SOCKET_ERROR);
199 #if !defined(ZMQ_HAVE_WINDOWS) && defined(IPV6_TCLASS)
200 rc = setsockopt (
s_, IPPROTO_IPV6, IPV6_TCLASS,
201 reinterpret_cast<char *
> (&iptos_),
sizeof (iptos_));
213 #ifdef ZMQ_HAVE_SO_PRIORITY
215 setsockopt (
s_, SOL_SOCKET, SO_PRIORITY,
216 reinterpret_cast<char *
> (&priority_),
sizeof (priority_));
233 int rc = setsockopt (
s_, SOL_SOCKET, SO_NOSIGPIPE, &
set,
sizeof (
int));
246 #ifdef ZMQ_HAVE_SO_BINDTODEVICE
247 int rc = setsockopt (
s_, SOL_SOCKET, SO_BINDTODEVICE,
248 bound_device_.c_str (), bound_device_.length ());
266 #if defined ZMQ_HAVE_OPENPGM
272 pgm_error_t *pgm_error =
NULL;
273 const bool ok = pgm_init (&pgm_error);
277 if (pgm_error->domain == PGM_ERROR_DOMAIN_TIME
278 && (pgm_error->code == PGM_ERROR_FAILED)) {
280 pgm_error_free (pgm_error);
290 #ifdef ZMQ_HAVE_WINDOWS
294 const WORD version_requested = MAKEWORD (2, 2);
296 const int rc = WSAStartup (version_requested, &wsa_data);
299 && HIBYTE (wsa_data.wVersion) == 2);
307 #ifdef ZMQ_HAVE_WINDOWS
309 const int rc = WSACleanup ();
310 wsa_assert (rc != SOCKET_ERROR);
313 #if defined ZMQ_HAVE_OPENPGM
315 if (pgm_shutdown () != TRUE)
320 #if defined ZMQ_HAVE_WINDOWS
321 static void tune_socket (
const SOCKET socket_)
323 BOOL tcp_nodelay = 1;
325 setsockopt (socket_, IPPROTO_TCP, TCP_NODELAY,
326 reinterpret_cast<char *
> (&tcp_nodelay),
sizeof tcp_nodelay);
327 wsa_assert (rc != SOCKET_ERROR);
334 #if !defined _WIN32_WCE && !defined ZMQ_HAVE_WINDOWS_UWP
336 SECURITY_DESCRIPTOR sd;
337 SECURITY_ATTRIBUTES sa;
338 memset (&sd, 0,
sizeof sd);
339 memset (&sa, 0,
sizeof sa);
341 InitializeSecurityDescriptor (&sd, SECURITY_DESCRIPTOR_REVISION);
342 SetSecurityDescriptorDacl (&sd, TRUE, 0, FALSE);
344 sa.nLength =
sizeof (SECURITY_ATTRIBUTES);
345 sa.lpSecurityDescriptor = &sd;
360 const int event_signaler_port = 5905;
363 #if !defined _WIN32_WCE && !defined ZMQ_HAVE_WINDOWS_UWP
365 CreateEventW (&sa, FALSE, TRUE, L
"Global\\zmq-signaler-port-sync");
368 CreateEventW (
NULL, FALSE, TRUE, L
"Global\\zmq-signaler-port-sync");
370 if (sync ==
NULL && GetLastError () == ERROR_ACCESS_DENIED)
371 sync = OpenEventW (SYNCHRONIZE | EVENT_MODIFY_STATE, FALSE,
372 L
"Global\\zmq-signaler-port-sync");
374 win_assert (sync !=
NULL);
376 wchar_t mutex_name[MAX_PATH];
378 _snwprintf (mutex_name, MAX_PATH, L
"Global\\zmq-signaler-port-%d",
381 swprintf (mutex_name, MAX_PATH, L
"Global\\zmq-signaler-port-%d",
385 #if !defined _WIN32_WCE && !defined ZMQ_HAVE_WINDOWS_UWP
386 sync = CreateMutexW (&sa, FALSE, mutex_name);
388 sync = CreateMutexW (
NULL, FALSE, mutex_name);
390 if (sync ==
NULL && GetLastError () == ERROR_ACCESS_DENIED)
391 sync = OpenMutexW (SYNCHRONIZE, FALSE, mutex_name);
393 win_assert (sync !=
NULL);
398 *w_ = INVALID_SOCKET;
399 *r_ = INVALID_SOCKET;
404 wsa_assert (listener != INVALID_SOCKET);
407 BOOL so_reuseaddr = 1;
408 int rc = setsockopt (listener, SOL_SOCKET, SO_REUSEADDR,
409 reinterpret_cast<char *
> (&so_reuseaddr),
410 sizeof so_reuseaddr);
411 wsa_assert (rc != SOCKET_ERROR);
413 tune_socket (listener);
416 struct sockaddr_in addr;
417 memset (&addr, 0,
sizeof addr);
418 addr.sin_family = AF_INET;
419 addr.sin_addr.s_addr = htonl (INADDR_LOOPBACK);
424 wsa_assert (*w_ != INVALID_SOCKET);
428 const DWORD dwrc = WaitForSingleObject (sync, INFINITE);
429 zmq_assert (dwrc == WAIT_OBJECT_0 || dwrc == WAIT_ABANDONED);
433 rc = bind (listener,
reinterpret_cast<const struct sockaddr *
> (&addr),
438 int addrlen =
sizeof addr;
439 rc = getsockname (listener,
reinterpret_cast<struct sockaddr *
> (&addr),
444 if (rc != SOCKET_ERROR) {
445 rc = listen (listener, 1);
449 if (rc != SOCKET_ERROR) {
450 rc = connect (*w_,
reinterpret_cast<struct sockaddr *
> (&addr),
455 if (rc != SOCKET_ERROR) {
459 *r_ = accept (listener,
NULL,
NULL);
464 if (*r_ != INVALID_SOCKET) {
465 const size_t dummy_size =
467 unsigned char *
dummy =
468 static_cast<unsigned char *
> (malloc (dummy_size));
471 int still_to_send =
static_cast<int> (dummy_size);
472 int still_to_recv =
static_cast<int> (dummy_size);
473 while (still_to_send || still_to_recv) {
475 if (still_to_send > 0) {
478 reinterpret_cast<char *
> (
dummy + dummy_size - still_to_send),
480 wsa_assert (nbytes != SOCKET_ERROR);
481 still_to_send -= nbytes;
485 reinterpret_cast<char *
> (
dummy + dummy_size - still_to_recv),
487 wsa_assert (nbytes != SOCKET_ERROR);
488 still_to_recv -= nbytes;
495 if (*r_ == INVALID_SOCKET)
496 saved_errno = WSAGetLastError ();
500 wsa_assert (rc != SOCKET_ERROR);
506 brc = SetEvent (sync);
508 brc = ReleaseMutex (sync);
509 win_assert (brc != 0);
512 brc = CloseHandle (sync);
513 win_assert (brc != 0);
516 if (*r_ != INVALID_SOCKET) {
521 if (*w_ != INVALID_SOCKET) {
523 wsa_assert (rc != SOCKET_ERROR);
524 *w_ = INVALID_SOCKET;
527 errno = zmq::wsa_error_to_errno (saved_errno);
534 #if defined ZMQ_HAVE_EVENTFD
536 #if defined ZMQ_HAVE_EVENTFD_CLOEXEC
540 flags |= EFD_CLOEXEC;
552 #elif defined ZMQ_HAVE_WINDOWS
557 socklen_t lcladdr_len =
sizeof lcladdr;
560 SOCKET listener = INVALID_SOCKET;
565 bool ipc_fallback_on_tcpip =
true;
567 if (!zmq::try_ipc_first) {
579 rc = create_ipc_wildcard_address (dirname, filename);
582 goto error_closelistener;
586 rc =
address.resolve (filename.c_str ());
588 goto error_closelistener;
592 rc = bind (listener,
const_cast<sockaddr *
> (
address.addr ()),
595 errno = wsa_error_to_errno (WSAGetLastError ());
596 goto error_closelistener;
602 rc = listen (listener, 1);
604 errno = wsa_error_to_errno (WSAGetLastError ());
605 goto error_closelistener;
608 rc = getsockname (listener,
reinterpret_cast<struct sockaddr *
> (&lcladdr),
610 wsa_assert (rc == 0);
615 errno = wsa_error_to_errno (WSAGetLastError ());
616 goto error_closelistener;
620 rc = ::connect (*w_,
reinterpret_cast<const struct sockaddr *
> (&lcladdr),
623 errno = wsa_error_to_errno (WSAGetLastError ());
624 goto error_closeclient;
628 ipc_fallback_on_tcpip =
false;
630 *r_ = accept (listener,
NULL,
NULL);
635 wsa_assert (rc == 0);
638 if (!filename.empty ()) {
639 rc = ::unlink (filename.c_str ());
640 if ((rc == 0) && !dirname.empty ()) {
641 rc = ::rmdir (dirname.c_str ());
652 wsa_assert (rc == 0);
659 wsa_assert (rc == 0);
662 if (!filename.empty ()) {
663 rc = ::unlink (filename.c_str ());
664 if ((rc == 0) && !dirname.empty ()) {
665 rc = ::rmdir (dirname.c_str ());
672 if (ipc_fallback_on_tcpip) {
681 rc = make_fdpair_tcpip (r_, w_);
682 if (rc == 0 && zmq::try_ipc_first) {
684 zmq::try_ipc_first =
false;
687 #endif // ZMQ_HAVE_IPC
688 return make_fdpair_tcpip (r_, w_);
689 #elif defined ZMQ_HAVE_OPENVMS
697 struct sockaddr_in lcladdr;
698 memset (&lcladdr, 0,
sizeof lcladdr);
699 lcladdr.sin_family = AF_INET;
700 lcladdr.sin_addr.s_addr = htonl (INADDR_LOOPBACK);
701 lcladdr.sin_port = 0;
703 int listener =
open_socket (AF_INET, SOCK_STREAM, 0);
707 int rc = setsockopt (listener, IPPROTO_TCP, TCP_NODELAY, &on,
sizeof on);
710 rc = setsockopt (listener, IPPROTO_TCP, TCP_NODELACK, &on,
sizeof on);
713 rc = bind (listener, (
struct sockaddr *) &lcladdr,
sizeof lcladdr);
716 socklen_t lcladdr_len =
sizeof lcladdr;
718 rc = getsockname (listener, (
struct sockaddr *) &lcladdr, &lcladdr_len);
721 rc = listen (listener, 1);
727 rc = setsockopt (*w_, IPPROTO_TCP, TCP_NODELAY, &on,
sizeof on);
730 rc = setsockopt (*w_, IPPROTO_TCP, TCP_NODELACK, &on,
sizeof on);
733 rc = connect (*w_, (
struct sockaddr *) &lcladdr,
sizeof lcladdr);
736 *r_ = accept (listener,
NULL,
NULL);
742 #elif defined ZMQ_HAVE_VXWORKS
743 struct sockaddr_in lcladdr;
744 memset (&lcladdr, 0,
sizeof lcladdr);
745 lcladdr.sin_family = AF_INET;
746 lcladdr.sin_addr.s_addr = htonl (INADDR_LOOPBACK);
747 lcladdr.sin_port = 0;
749 int listener =
open_socket (AF_INET, SOCK_STREAM, 0);
754 setsockopt (listener, IPPROTO_TCP, TCP_NODELAY, (
char *) &on,
sizeof on);
757 rc = bind (listener, (
struct sockaddr *) &lcladdr,
sizeof lcladdr);
760 socklen_t lcladdr_len =
sizeof lcladdr;
762 rc = getsockname (listener, (
struct sockaddr *) &lcladdr,
763 (
int *) &lcladdr_len);
766 rc = listen (listener, 1);
772 rc = setsockopt (*w_, IPPROTO_TCP, TCP_NODELAY, (
char *) &on,
sizeof on);
775 rc = connect (*w_, (
struct sockaddr *) &lcladdr,
sizeof lcladdr);
778 *r_ = accept (listener,
NULL,
NULL);
787 int type = SOCK_STREAM;
791 #if defined ZMQ_HAVE_SOCK_CLOEXEC
792 type |= SOCK_CLOEXEC;
794 int rc = socketpair (AF_UNIX,
type, 0, sv);
812 #if defined ZMQ_HAVE_WINDOWS && !defined _WIN32_WCE \
813 && !defined ZMQ_HAVE_WINDOWS_UWP
815 const BOOL brc = SetHandleInformation (
reinterpret_cast<HANDLE> (sock_),
816 HANDLE_FLAG_INHERIT, 0);
818 #elif (!defined ZMQ_HAVE_SOCK_CLOEXEC || !defined HAVE_ACCEPT4) \
819 && defined FD_CLOEXEC
823 const int rc = fcntl (sock_, F_SETFD, FD_CLOEXEC);
832 #ifdef ZMQ_HAVE_WINDOWS
833 if (rc_ != SOCKET_ERROR) {
844 #if defined ZMQ_HAVE_HPUX || defined ZMQ_HAVE_VXWORKS
847 socklen_t
len =
sizeof err;
850 const int rc = getsockopt (
s_, SOL_SOCKET, SO_ERROR,
851 reinterpret_cast<char *
> (&
err), &
len);
855 #ifdef ZMQ_HAVE_WINDOWS
858 wsa_assert (
err == WSAECONNREFUSED ||
err == WSAECONNRESET
859 ||
err == WSAECONNABORTED ||
err == WSAEINTR
860 ||
err == WSAETIMEDOUT ||
err == WSAEHOSTUNREACH
861 ||
err == WSAENETUNREACH ||
err == WSAENETDOWN
862 ||
err == WSAENETRESET ||
err == WSAEACCES
863 ||
err == WSAEINVAL ||
err == WSAEADDRINUSE);
883 #if defined ZMQ_HAVE_WINDOWS
884 char *widechar_to_utf8 (
const wchar_t *widestring)
888 nch = WideCharToMultiByte (CP_UTF8, 0, widestring, -1, 0, 0,
NULL,
NULL);
890 utf8 = (
char *) malloc ((nch + 1) *
sizeof (char));
891 n = WideCharToMultiByte (CP_UTF8, 0, widestring, -1, utf8, nch,
NULL,
901 #if defined ZMQ_HAVE_WINDOWS
905 const errno_t rc = _wtmpnam_s (
buffer);
910 const int rc = _wmkdir (
buffer);
915 char *tmp = widechar_to_utf8 (
buffer);
921 file_ = path_ +
"/socket";
930 while (tmp_path.empty () && *tmp_env != 0) {
931 const char *
const tmpdir = getenv (*tmp_env);
935 if (tmpdir != 0 && ::stat (tmpdir, &statbuf) == 0
936 &&
S_ISDIR (statbuf.st_mode)) {
937 tmp_path.assign (tmpdir);
938 if (*(tmp_path.rbegin ()) !=
'/') {
939 tmp_path.push_back (
'/');
948 tmp_path.append (
"tmpXXXXXX");
951 std::vector<char>
buffer (tmp_path.length () + 1);
952 memcpy (&
buffer[0], tmp_path.c_str (), tmp_path.
length () + 1);
954 #if defined HAVE_MKDTEMP
961 if (mkdtemp (&
buffer[0]) == 0) {
965 path_.assign (&
buffer[0]);
966 file_ = path_ +
"/socket";
969 int fd = mkstemp (&
buffer[0]);