1/*
2 Copyright (c) 2007-2016 Contributors as noted in the AUTHORS file
3
4 This file is part of libzmq, the ZeroMQ core engine in C++.
5
6 libzmq is free software; you can redistribute it and/or modify it under
7 the terms of the GNU Lesser General Public License (LGPL) as published
8 by the Free Software Foundation; either version 3 of the License, or
9 (at your option) any later version.
10
11 As a special exception, the Contributors give you permission to link
12 this library with independent modules to produce an executable,
13 regardless of the license terms of these independent modules, and to
14 copy and distribute the resulting executable under terms of your choice,
15 provided that you also meet, for each linked independent module, the
16 terms and conditions of the license of that module. An independent
17 module is a module which is not derived from or based on this library.
18 If you modify this library, you must extend this exception to your
19 version of the library.
20
21 libzmq is distributed in the hope that it will be useful, but WITHOUT
22 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
23 FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
24 License for more details.
25
26 You should have received a copy of the GNU Lesser General Public License
27 along with this program. If not, see <http://www.gnu.org/licenses/>.
28*/
29
30#include "precompiled.hpp"
31#include "ip.hpp"
32#include "err.hpp"
33#include "macros.hpp"
34#include "config.hpp"
35#include "address.hpp"
36
37#if !defined ZMQ_HAVE_WINDOWS
38#include <fcntl.h>
39#include <sys/types.h>
40#include <sys/socket.h>
41#include <sys/stat.h>
42#include <netdb.h>
43#include <netinet/in.h>
44#include <netinet/tcp.h>
45#include <stdlib.h>
46#include <unistd.h>
47
48#include <vector>
49#else
50#include "tcp.hpp"
51#ifdef ZMQ_HAVE_IPC
52#include "ipc_address.hpp"
53#endif
54
55#include <direct.h>
56#endif
57
58#if defined ZMQ_HAVE_OPENVMS || defined ZMQ_HAVE_VXWORKS
59#include <ioctl.h>
60#endif
61
62#if defined ZMQ_HAVE_VXWORKS
63#include <unistd.h>
64#include <sockLib.h>
65#include <ioLib.h>
66#endif
67
68#if defined ZMQ_HAVE_EVENTFD
69#include <sys/eventfd.h>
70#endif
71
72#if defined ZMQ_HAVE_OPENPGM
73#ifdef ZMQ_HAVE_WINDOWS
74#define __PGM_WININT_H__
75#endif
76
77#include <pgm/pgm.h>
78#endif
79
80#ifdef __APPLE__
81#include <TargetConditionals.h>
82#endif
83
84#ifndef ZMQ_HAVE_WINDOWS
85// Acceptable temporary directory environment variables
86static const char *tmp_env_vars[] = {
87 "TMPDIR", "TEMPDIR", "TMP",
88 0 // Sentinel
89};
90#endif
91
92zmq::fd_t zmq::open_socket (int domain_, int type_, int protocol_)
93{
94 int rc;
95
96 // Setting this option result in sane behaviour when exec() functions
97 // are used. Old sockets are closed and don't block TCP ports etc.
98#if defined ZMQ_HAVE_SOCK_CLOEXEC
99 type_ |= SOCK_CLOEXEC;
100#endif
101
102#if defined ZMQ_HAVE_WINDOWS && defined WSA_FLAG_NO_HANDLE_INHERIT
103 // if supported, create socket with WSA_FLAG_NO_HANDLE_INHERIT, such that
104 // the race condition in making it non-inheritable later is avoided
105 const fd_t s =
106 WSASocket (domain_, type_, protocol_, NULL, 0,
107 WSA_FLAG_OVERLAPPED || WSA_FLAG_NO_HANDLE_INHERIT);
108#else
109 const fd_t s = socket (domain_, type_, protocol_);
110#endif
111 if (s == retired_fd) {
112#ifdef ZMQ_HAVE_WINDOWS
113 errno = wsa_error_to_errno (WSAGetLastError ());
114#endif
115 return retired_fd;
116 }
117
118 make_socket_noninheritable (s);
119
120 // Socket is not yet connected so EINVAL is not a valid networking error
121 rc = zmq::set_nosigpipe (s);
122 errno_assert (rc == 0);
123
124 return s;
125}
126
127void zmq::unblock_socket (fd_t s_)
128{
129#if defined ZMQ_HAVE_WINDOWS
130 u_long nonblock = 1;
131 int rc = ioctlsocket (s_, FIONBIO, &nonblock);
132 wsa_assert (rc != SOCKET_ERROR);
133#elif defined ZMQ_HAVE_OPENVMS || defined ZMQ_HAVE_VXWORKS
134 int nonblock = 1;
135 int rc = ioctl (s_, FIONBIO, &nonblock);
136 errno_assert (rc != -1);
137#else
138 int flags = fcntl (s_, F_GETFL, 0);
139 if (flags == -1)
140 flags = 0;
141 int rc = fcntl (s_, F_SETFL, flags | O_NONBLOCK);
142 errno_assert (rc != -1);
143#endif
144}
145
146void zmq::enable_ipv4_mapping (fd_t s_)
147{
148 LIBZMQ_UNUSED (s_);
149
150#if defined IPV6_V6ONLY && !defined ZMQ_HAVE_OPENBSD \
151 && !defined ZMQ_HAVE_DRAGONFLY
152#ifdef ZMQ_HAVE_WINDOWS
153 DWORD flag = 0;
154#else
155 int flag = 0;
156#endif
157 int rc = setsockopt (s_, IPPROTO_IPV6, IPV6_V6ONLY,
158 reinterpret_cast<char *> (&flag), sizeof (flag));
159#ifdef ZMQ_HAVE_WINDOWS
160 wsa_assert (rc != SOCKET_ERROR);
161#else
162 errno_assert (rc == 0);
163#endif
164#endif
165}
166
167int zmq::get_peer_ip_address (fd_t sockfd_, std::string &ip_addr_)
168{
169 struct sockaddr_storage ss;
170
171 zmq_socklen_t addrlen =
172 get_socket_address (sockfd_, socket_end_remote, &ss);
173
174 if (addrlen == 0) {
175#ifdef ZMQ_HAVE_WINDOWS
176 const int last_error = WSAGetLastError ();
177 wsa_assert (last_error != WSANOTINITIALISED && last_error != WSAEFAULT
178 && last_error != WSAEINPROGRESS
179 && last_error != WSAENOTSOCK);
180#elif !defined(TARGET_OS_IPHONE) || !TARGET_OS_IPHONE
181 errno_assert (errno != EBADF && errno != EFAULT && errno != ENOTSOCK);
182#else
183 errno_assert (errno != EFAULT && errno != ENOTSOCK);
184#endif
185 return 0;
186 }
187
188 char host[NI_MAXHOST];
189 int rc = getnameinfo (reinterpret_cast<struct sockaddr *> (&ss), addrlen,
190 host, sizeof host, NULL, 0, NI_NUMERICHOST);
191 if (rc != 0)
192 return 0;
193
194 ip_addr_ = host;
195
196 union
197 {
198 struct sockaddr sa;
199 struct sockaddr_storage sa_stor;
200 } u;
201
202 u.sa_stor = ss;
203 return static_cast<int> (u.sa.sa_family);
204}
205
206void zmq::set_ip_type_of_service (fd_t s_, int iptos_)
207{
208 int rc = setsockopt (s_, IPPROTO_IP, IP_TOS,
209 reinterpret_cast<char *> (&iptos_), sizeof (iptos_));
210
211#ifdef ZMQ_HAVE_WINDOWS
212 wsa_assert (rc != SOCKET_ERROR);
213#else
214 errno_assert (rc == 0);
215#endif
216
217 // Windows and Hurd do not support IPV6_TCLASS
218#if !defined(ZMQ_HAVE_WINDOWS) && defined(IPV6_TCLASS)
219 rc = setsockopt (s_, IPPROTO_IPV6, IPV6_TCLASS,
220 reinterpret_cast<char *> (&iptos_), sizeof (iptos_));
221
222 // If IPv6 is not enabled ENOPROTOOPT will be returned on Linux and
223 // EINVAL on OSX
224 if (rc == -1) {
225 errno_assert (errno == ENOPROTOOPT || errno == EINVAL);
226 }
227#endif
228}
229
230int zmq::set_nosigpipe (fd_t s_)
231{
232#ifdef SO_NOSIGPIPE
233 // Make sure that SIGPIPE signal is not generated when writing to a
234 // connection that was already closed by the peer.
235 // As per POSIX spec, EINVAL will be returned if the socket was valid but
236 // the connection has been reset by the peer. Return an error so that the
237 // socket can be closed and the connection retried if necessary.
238 int set = 1;
239 int rc = setsockopt (s_, SOL_SOCKET, SO_NOSIGPIPE, &set, sizeof (int));
240 if (rc != 0 && errno == EINVAL)
241 return -1;
242 errno_assert (rc == 0);
243#else
244 LIBZMQ_UNUSED (s_);
245#endif
246
247 return 0;
248}
249
250int zmq::bind_to_device (fd_t s_, const std::string &bound_device_)
251{
252#ifdef ZMQ_HAVE_SO_BINDTODEVICE
253 int rc = setsockopt (s_, SOL_SOCKET, SO_BINDTODEVICE,
254 bound_device_.c_str (), bound_device_.length ());
255 if (rc != 0) {
256 assert_success_or_recoverable (s_, rc);
257 return -1;
258 }
259 return 0;
260
261#else
262 LIBZMQ_UNUSED (s_);
263 LIBZMQ_UNUSED (bound_device_);
264
265 errno = ENOTSUP;
266 return -1;
267#endif
268}
269
270bool zmq::initialize_network ()
271{
272#if defined ZMQ_HAVE_OPENPGM
273
274 // Init PGM transport. Ensure threading and timer are enabled. Find PGM
275 // protocol ID. Note that if you want to use gettimeofday and sleep for
276 // openPGM timing, set environment variables PGM_TIMER to "GTOD" and
277 // PGM_SLEEP to "USLEEP".
278 pgm_error_t *pgm_error = NULL;
279 const bool ok = pgm_init (&pgm_error);
280 if (ok != TRUE) {
281 // Invalid parameters don't set pgm_error_t
282 zmq_assert (pgm_error != NULL);
283 if (pgm_error->domain == PGM_ERROR_DOMAIN_TIME
284 && (pgm_error->code == PGM_ERROR_FAILED)) {
285 // Failed to access RTC or HPET device.
286 pgm_error_free (pgm_error);
287 errno = EINVAL;
288 return false;
289 }
290
291 // PGM_ERROR_DOMAIN_ENGINE: WSAStartup errors or missing WSARecvMsg.
292 zmq_assert (false);
293 }
294#endif
295
296#ifdef ZMQ_HAVE_WINDOWS
297 // Intialise Windows sockets. Note that WSAStartup can be called multiple
298 // times given that WSACleanup will be called for each WSAStartup.
299
300 WORD version_requested = MAKEWORD (2, 2);
301 WSADATA wsa_data;
302 int rc = WSAStartup (version_requested, &wsa_data);
303 zmq_assert (rc == 0);
304 zmq_assert (LOBYTE (wsa_data.wVersion) == 2
305 && HIBYTE (wsa_data.wVersion) == 2);
306#endif
307
308 return true;
309}
310
311void zmq::shutdown_network ()
312{
313#ifdef ZMQ_HAVE_WINDOWS
314 // On Windows, uninitialise socket layer.
315 int rc = WSACleanup ();
316 wsa_assert (rc != SOCKET_ERROR);
317#endif
318
319#if defined ZMQ_HAVE_OPENPGM
320 // Shut down the OpenPGM library.
321 if (pgm_shutdown () != TRUE)
322 zmq_assert (false);
323#endif
324}
325
326#if defined ZMQ_HAVE_WINDOWS
327static void tune_socket (const SOCKET socket_)
328{
329 BOOL tcp_nodelay = 1;
330 int rc =
331 setsockopt (socket_, IPPROTO_TCP, TCP_NODELAY,
332 reinterpret_cast<char *> (&tcp_nodelay), sizeof tcp_nodelay);
333 wsa_assert (rc != SOCKET_ERROR);
334
335 zmq::tcp_tune_loopback_fast_path (socket_);
336}
337
338static int make_fdpair_tcpip (zmq::fd_t *r_, zmq::fd_t *w_)
339{
340#if !defined _WIN32_WCE && !defined ZMQ_HAVE_WINDOWS_UWP
341 // Windows CE does not manage security attributes
342 SECURITY_DESCRIPTOR sd;
343 SECURITY_ATTRIBUTES sa;
344 memset (&sd, 0, sizeof sd);
345 memset (&sa, 0, sizeof sa);
346
347 InitializeSecurityDescriptor (&sd, SECURITY_DESCRIPTOR_REVISION);
348 SetSecurityDescriptorDacl (&sd, TRUE, 0, FALSE);
349
350 sa.nLength = sizeof (SECURITY_ATTRIBUTES);
351 sa.lpSecurityDescriptor = &sd;
352#endif
353
354 // This function has to be in a system-wide critical section so that
355 // two instances of the library don't accidentally create signaler
356 // crossing the process boundary.
357 // We'll use named event object to implement the critical section.
358 // Note that if the event object already exists, the CreateEvent requests
359 // EVENT_ALL_ACCESS access right. If this fails, we try to open
360 // the event object asking for SYNCHRONIZE access only.
361 HANDLE sync = NULL;
362
363 // Create critical section only if using fixed signaler port
364 // Use problematic Event implementation for compatibility if using old port 5905.
365 // Otherwise use Mutex implementation.
366 int event_signaler_port = 5905;
367
368 if (zmq::signaler_port == event_signaler_port) {
369#if !defined _WIN32_WCE && !defined ZMQ_HAVE_WINDOWS_UWP
370 sync =
371 CreateEventW (&sa, FALSE, TRUE, L"Global\\zmq-signaler-port-sync");
372#else
373 sync =
374 CreateEventW (NULL, FALSE, TRUE, L"Global\\zmq-signaler-port-sync");
375#endif
376 if (sync == NULL && GetLastError () == ERROR_ACCESS_DENIED)
377 sync = OpenEventW (SYNCHRONIZE | EVENT_MODIFY_STATE, FALSE,
378 L"Global\\zmq-signaler-port-sync");
379
380 win_assert (sync != NULL);
381 } else if (zmq::signaler_port != 0) {
382 wchar_t mutex_name[MAX_PATH];
383#ifdef __MINGW32__
384 _snwprintf (mutex_name, MAX_PATH, L"Global\\zmq-signaler-port-%d",
385 signaler_port);
386#else
387 swprintf (mutex_name, MAX_PATH, L"Global\\zmq-signaler-port-%d",
388 zmq::signaler_port);
389#endif
390
391#if !defined _WIN32_WCE && !defined ZMQ_HAVE_WINDOWS_UWP
392 sync = CreateMutexW (&sa, FALSE, mutex_name);
393#else
394 sync = CreateMutexW (NULL, FALSE, mutex_name);
395#endif
396 if (sync == NULL && GetLastError () == ERROR_ACCESS_DENIED)
397 sync = OpenMutexW (SYNCHRONIZE, FALSE, mutex_name);
398
399 win_assert (sync != NULL);
400 }
401
402 // Windows has no 'socketpair' function. CreatePipe is no good as pipe
403 // handles cannot be polled on. Here we create the socketpair by hand.
404 *w_ = INVALID_SOCKET;
405 *r_ = INVALID_SOCKET;
406
407 // Create listening socket.
408 SOCKET listener;
409 listener = zmq::open_socket (AF_INET, SOCK_STREAM, 0);
410 wsa_assert (listener != INVALID_SOCKET);
411
412 // Set SO_REUSEADDR and TCP_NODELAY on listening socket.
413 BOOL so_reuseaddr = 1;
414 int rc = setsockopt (listener, SOL_SOCKET, SO_REUSEADDR,
415 reinterpret_cast<char *> (&so_reuseaddr),
416 sizeof so_reuseaddr);
417 wsa_assert (rc != SOCKET_ERROR);
418
419 tune_socket (listener);
420
421 // Init sockaddr to signaler port.
422 struct sockaddr_in addr;
423 memset (&addr, 0, sizeof addr);
424 addr.sin_family = AF_INET;
425 addr.sin_addr.s_addr = htonl (INADDR_LOOPBACK);
426 addr.sin_port = htons (zmq::signaler_port);
427
428 // Create the writer socket.
429 *w_ = zmq::open_socket (AF_INET, SOCK_STREAM, 0);
430 wsa_assert (*w_ != INVALID_SOCKET);
431
432 if (sync != NULL) {
433 // Enter the critical section.
434 DWORD dwrc = WaitForSingleObject (sync, INFINITE);
435 zmq_assert (dwrc == WAIT_OBJECT_0 || dwrc == WAIT_ABANDONED);
436 }
437
438 // Bind listening socket to signaler port.
439 rc = bind (listener, reinterpret_cast<const struct sockaddr *> (&addr),
440 sizeof addr);
441
442 if (rc != SOCKET_ERROR && zmq::signaler_port == 0) {
443 // Retrieve ephemeral port number
444 int addrlen = sizeof addr;
445 rc = getsockname (listener, reinterpret_cast<struct sockaddr *> (&addr),
446 &addrlen);
447 }
448
449 // Listen for incoming connections.
450 if (rc != SOCKET_ERROR) {
451 rc = listen (listener, 1);
452 }
453
454 // Connect writer to the listener.
455 if (rc != SOCKET_ERROR) {
456 rc = connect (*w_, reinterpret_cast<struct sockaddr *> (&addr),
457 sizeof addr);
458 }
459
460 // Accept connection from writer.
461 if (rc != SOCKET_ERROR) {
462 // Set TCP_NODELAY on writer socket.
463 tune_socket (*w_);
464
465 *r_ = accept (listener, NULL, NULL);
466 }
467
468 // Send/receive large chunk to work around TCP slow start
469 // This code is a workaround for #1608
470 if (*r_ != INVALID_SOCKET) {
471 size_t dummy_size =
472 1024 * 1024; // 1M to overload default receive buffer
473 unsigned char *dummy =
474 static_cast<unsigned char *> (malloc (dummy_size));
475 wsa_assert (dummy);
476
477 int still_to_send = static_cast<int> (dummy_size);
478 int still_to_recv = static_cast<int> (dummy_size);
479 while (still_to_send || still_to_recv) {
480 int nbytes;
481 if (still_to_send > 0) {
482 nbytes = ::send (
483 *w_,
484 reinterpret_cast<char *> (dummy + dummy_size - still_to_send),
485 still_to_send, 0);
486 wsa_assert (nbytes != SOCKET_ERROR);
487 still_to_send -= nbytes;
488 }
489 nbytes = ::recv (
490 *r_,
491 reinterpret_cast<char *> (dummy + dummy_size - still_to_recv),
492 still_to_recv, 0);
493 wsa_assert (nbytes != SOCKET_ERROR);
494 still_to_recv -= nbytes;
495 }
496 free (dummy);
497 }
498
499 // Save errno if error occurred in bind/listen/connect/accept.
500 int saved_errno = 0;
501 if (*r_ == INVALID_SOCKET)
502 saved_errno = WSAGetLastError ();
503
504 // We don't need the listening socket anymore. Close it.
505 rc = closesocket (listener);
506 wsa_assert (rc != SOCKET_ERROR);
507
508 if (sync != NULL) {
509 // Exit the critical section.
510 BOOL brc;
511 if (zmq::signaler_port == event_signaler_port)
512 brc = SetEvent (sync);
513 else
514 brc = ReleaseMutex (sync);
515 win_assert (brc != 0);
516
517 // Release the kernel object
518 brc = CloseHandle (sync);
519 win_assert (brc != 0);
520 }
521
522 if (*r_ != INVALID_SOCKET) {
523 zmq::make_socket_noninheritable (*r_);
524 return 0;
525 }
526 // Cleanup writer if connection failed
527 if (*w_ != INVALID_SOCKET) {
528 rc = closesocket (*w_);
529 wsa_assert (rc != SOCKET_ERROR);
530 *w_ = INVALID_SOCKET;
531 }
532 // Set errno from saved value
533 errno = zmq::wsa_error_to_errno (saved_errno);
534 return -1;
535}
536#endif
537
538int zmq::make_fdpair (fd_t *r_, fd_t *w_)
539{
540#if defined ZMQ_HAVE_EVENTFD
541 int flags = 0;
542#if defined ZMQ_HAVE_EVENTFD_CLOEXEC
543 // Setting this option result in sane behaviour when exec() functions
544 // are used. Old sockets are closed and don't block TCP ports, avoid
545 // leaks, etc.
546 flags |= EFD_CLOEXEC;
547#endif
548 fd_t fd = eventfd (0, flags);
549 if (fd == -1) {
550 errno_assert (errno == ENFILE || errno == EMFILE);
551 *w_ = *r_ = -1;
552 return -1;
553 }
554 *w_ = *r_ = fd;
555 return 0;
556
557
558#elif defined ZMQ_HAVE_WINDOWS
559#ifdef ZMQ_HAVE_IPC
560 ipc_address_t address;
561 std::string dirname, filename;
562
563 // Create a listening socket.
564 SOCKET listener = open_socket (AF_UNIX, SOCK_STREAM, 0);
565 if (listener == retired_fd) {
566 // This may happen if the library was built on a system supporting AF_UNIX, but the system running doesn't support it.
567 goto try_tcpip;
568 }
569
570 create_ipc_wildcard_address (dirname, filename);
571
572 // Initialise the address structure.
573 int rc = address.resolve (filename.c_str ());
574 if (rc != 0) {
575 goto error_closelistener;
576 }
577
578 // Bind the socket to the file path.
579 rc = bind (listener, const_cast<sockaddr *> (address.addr ()),
580 address.addrlen ());
581 if (rc != 0) {
582 errno = wsa_error_to_errno (WSAGetLastError ());
583 goto error_closelistener;
584 }
585
586 // Listen for incoming connections.
587 rc = listen (listener, 1);
588 if (rc != 0) {
589 errno = wsa_error_to_errno (WSAGetLastError ());
590 goto error_closelistener;
591 }
592
593 sockaddr_un lcladdr;
594 socklen_t lcladdr_len = sizeof lcladdr;
595
596 rc = getsockname (listener, reinterpret_cast<struct sockaddr *> (&lcladdr),
597 &lcladdr_len);
598 wsa_assert (rc != -1);
599
600 // Create the client socket.
601 *w_ = open_socket (AF_UNIX, SOCK_STREAM, 0);
602 if (*w_ == -1) {
603 errno = wsa_error_to_errno (WSAGetLastError ());
604 goto error_closelistener;
605 }
606
607 // Connect to the remote peer.
608 rc = ::connect (*w_, reinterpret_cast<const struct sockaddr *> (&lcladdr),
609 lcladdr_len);
610 if (rc == -1) {
611 goto error_closeclient;
612 }
613
614 *r_ = accept (listener, NULL, NULL);
615 errno_assert (*r_ != -1);
616
617 // Close the listener socket, we don't need it anymore.
618 rc = closesocket (listener);
619 wsa_assert (rc == 0);
620
621 return 0;
622
623error_closeclient:
624 int saved_errno = errno;
625 rc = closesocket (*w_);
626 wsa_assert (rc == 0);
627 errno = saved_errno;
628
629error_closelistener:
630 saved_errno = errno;
631 rc = closesocket (listener);
632 wsa_assert (rc == 0);
633 errno = saved_errno;
634
635 return -1;
636
637try_tcpip:
638 // try to fallback to TCP/IP
639 // TODO: maybe remember this decision permanently?
640#endif
641
642 return make_fdpair_tcpip (r_, w_);
643#elif defined ZMQ_HAVE_OPENVMS
644
645 // Whilst OpenVMS supports socketpair - it maps to AF_INET only. Further,
646 // it does not set the socket options TCP_NODELAY and TCP_NODELACK which
647 // can lead to performance problems.
648 //
649 // The bug will be fixed in V5.6 ECO4 and beyond. In the meantime, we'll
650 // create the socket pair manually.
651 struct sockaddr_in lcladdr;
652 memset (&lcladdr, 0, sizeof lcladdr);
653 lcladdr.sin_family = AF_INET;
654 lcladdr.sin_addr.s_addr = htonl (INADDR_LOOPBACK);
655 lcladdr.sin_port = 0;
656
657 int listener = open_socket (AF_INET, SOCK_STREAM, 0);
658 errno_assert (listener != -1);
659
660 int on = 1;
661 int rc = setsockopt (listener, IPPROTO_TCP, TCP_NODELAY, &on, sizeof on);
662 errno_assert (rc != -1);
663
664 rc = setsockopt (listener, IPPROTO_TCP, TCP_NODELACK, &on, sizeof on);
665 errno_assert (rc != -1);
666
667 rc = bind (listener, (struct sockaddr *) &lcladdr, sizeof lcladdr);
668 errno_assert (rc != -1);
669
670 socklen_t lcladdr_len = sizeof lcladdr;
671
672 rc = getsockname (listener, (struct sockaddr *) &lcladdr, &lcladdr_len);
673 errno_assert (rc != -1);
674
675 rc = listen (listener, 1);
676 errno_assert (rc != -1);
677
678 *w_ = open_socket (AF_INET, SOCK_STREAM, 0);
679 errno_assert (*w_ != -1);
680
681 rc = setsockopt (*w_, IPPROTO_TCP, TCP_NODELAY, &on, sizeof on);
682 errno_assert (rc != -1);
683
684 rc = setsockopt (*w_, IPPROTO_TCP, TCP_NODELACK, &on, sizeof on);
685 errno_assert (rc != -1);
686
687 rc = connect (*w_, (struct sockaddr *) &lcladdr, sizeof lcladdr);
688 errno_assert (rc != -1);
689
690 *r_ = accept (listener, NULL, NULL);
691 errno_assert (*r_ != -1);
692
693 close (listener);
694
695 return 0;
696#elif defined ZMQ_HAVE_VXWORKS
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;
702
703 int listener = open_socket (AF_INET, SOCK_STREAM, 0);
704 errno_assert (listener != -1);
705
706 int on = 1;
707 int rc =
708 setsockopt (listener, IPPROTO_TCP, TCP_NODELAY, (char *) &on, sizeof on);
709 errno_assert (rc != -1);
710
711 rc = bind (listener, (struct sockaddr *) &lcladdr, sizeof lcladdr);
712 errno_assert (rc != -1);
713
714 socklen_t lcladdr_len = sizeof lcladdr;
715
716 rc = getsockname (listener, (struct sockaddr *) &lcladdr,
717 (int *) &lcladdr_len);
718 errno_assert (rc != -1);
719
720 rc = listen (listener, 1);
721 errno_assert (rc != -1);
722
723 *w_ = open_socket (AF_INET, SOCK_STREAM, 0);
724 errno_assert (*w_ != -1);
725
726 rc = setsockopt (*w_, IPPROTO_TCP, TCP_NODELAY, (char *) &on, sizeof on);
727 errno_assert (rc != -1);
728
729 rc = connect (*w_, (struct sockaddr *) &lcladdr, sizeof lcladdr);
730 errno_assert (rc != -1);
731
732 *r_ = accept (listener, NULL, NULL);
733 errno_assert (*r_ != -1);
734
735 close (listener);
736
737 return 0;
738#else
739 // All other implementations support socketpair()
740 int sv[2];
741 int type = SOCK_STREAM;
742 // Setting this option result in sane behaviour when exec() functions
743 // are used. Old sockets are closed and don't block TCP ports, avoid
744 // leaks, etc.
745#if defined ZMQ_HAVE_SOCK_CLOEXEC
746 type |= SOCK_CLOEXEC;
747#endif
748 int rc = socketpair (AF_UNIX, type, 0, sv);
749 if (rc == -1) {
750 errno_assert (errno == ENFILE || errno == EMFILE);
751 *w_ = *r_ = -1;
752 return -1;
753 } else {
754 make_socket_noninheritable (sv[0]);
755 make_socket_noninheritable (sv[1]);
756
757 *w_ = sv[0];
758 *r_ = sv[1];
759 return 0;
760 }
761#endif
762}
763
764void zmq::make_socket_noninheritable (fd_t sock_)
765{
766#if defined ZMQ_HAVE_WINDOWS && !defined _WIN32_WCE \
767 && !defined ZMQ_HAVE_WINDOWS_UWP
768 // On Windows, preventing sockets to be inherited by child processes.
769 const BOOL brc = SetHandleInformation (reinterpret_cast<HANDLE> (sock_),
770 HANDLE_FLAG_INHERIT, 0);
771 win_assert (brc);
772#elif (!defined ZMQ_HAVE_SOCK_CLOEXEC || !defined HAVE_ACCEPT4) \
773 && defined FD_CLOEXEC
774 // If there 's no SOCK_CLOEXEC, let's try the second best option.
775 // Race condition can cause socket not to be closed (if fork happens
776 // between accept and this point).
777 const int rc = fcntl (sock_, F_SETFD, FD_CLOEXEC);
778 errno_assert (rc != -1);
779#else
780 LIBZMQ_UNUSED (sock_);
781#endif
782}
783
784void zmq::assert_success_or_recoverable (zmq::fd_t s_, int rc_)
785{
786#ifdef ZMQ_HAVE_WINDOWS
787 if (rc_ != SOCKET_ERROR) {
788 return;
789 }
790#else
791 if (rc_ != -1) {
792 return;
793 }
794#endif
795
796 // Check whether an error occurred
797 int err = 0;
798#if defined ZMQ_HAVE_HPUX || defined ZMQ_HAVE_VXWORKS
799 int len = sizeof err;
800#else
801 socklen_t len = sizeof err;
802#endif
803
804 int rc = getsockopt (s_, SOL_SOCKET, SO_ERROR,
805 reinterpret_cast<char *> (&err), &len);
806
807 // Assert if the error was caused by 0MQ bug.
808 // Networking problems are OK. No need to assert.
809#ifdef ZMQ_HAVE_WINDOWS
810 zmq_assert (rc == 0);
811 if (err != 0) {
812 wsa_assert (err == WSAECONNREFUSED || err == WSAECONNRESET
813 || err == WSAECONNABORTED || err == WSAEINTR
814 || err == WSAETIMEDOUT || err == WSAEHOSTUNREACH
815 || err == WSAENETUNREACH || err == WSAENETDOWN
816 || err == WSAENETRESET || err == WSAEACCES
817 || err == WSAEINVAL || err == WSAEADDRINUSE);
818 }
819#else
820 // Following code should handle both Berkeley-derived socket
821 // implementations and Solaris.
822 if (rc == -1)
823 err = errno;
824 if (err != 0) {
825 errno = err;
826 errno_assert (errno == ECONNREFUSED || errno == ECONNRESET
827 || errno == ECONNABORTED || errno == EINTR
828 || errno == ETIMEDOUT || errno == EHOSTUNREACH
829 || errno == ENETUNREACH || errno == ENETDOWN
830 || errno == ENETRESET || errno == EINVAL);
831 }
832#endif
833}
834
835#ifdef ZMQ_HAVE_IPC
836int zmq::create_ipc_wildcard_address (std::string &path_, std::string &file_)
837{
838#if defined ZMQ_HAVE_WINDOWS
839 char buffer[MAX_PATH];
840
841 {
842 const errno_t rc = tmpnam_s (buffer);
843 errno_assert (rc == 0);
844 }
845
846 // TODO or use CreateDirectoryA and specify permissions?
847 const int rc = _mkdir (buffer);
848 if (rc != 0) {
849 return -1;
850 }
851
852 path_.assign (buffer);
853 file_ = path_ + "/socket";
854#else
855 std::string tmp_path;
856
857 // If TMPDIR, TEMPDIR, or TMP are available and are directories, create
858 // the socket directory there.
859 const char **tmp_env = tmp_env_vars;
860 while (tmp_path.empty () && *tmp_env != 0) {
861 char *tmpdir = getenv (*tmp_env);
862 struct stat statbuf;
863
864 // Confirm it is actually a directory before trying to use
865 if (tmpdir != 0 && ::stat (tmpdir, &statbuf) == 0
866 && S_ISDIR (statbuf.st_mode)) {
867 tmp_path.assign (tmpdir);
868 if (*(tmp_path.rbegin ()) != '/') {
869 tmp_path.push_back ('/');
870 }
871 }
872
873 // Try the next environment variable
874 ++tmp_env;
875 }
876
877 // Append a directory name
878 tmp_path.append ("tmpXXXXXX");
879
880 // We need room for tmp_path + trailing NUL
881 std::vector<char> buffer (tmp_path.length () + 1);
882 strcpy (&buffer[0], tmp_path.c_str ());
883
884#if defined HAVE_MKDTEMP
885 // Create the directory. POSIX requires that mkdtemp() creates the
886 // directory with 0700 permissions, meaning the only possible race
887 // with socket creation could be the same user. However, since
888 // each socket is created in a directory created by mkdtemp(), and
889 // mkdtemp() guarantees a unique directory name, there will be no
890 // collision.
891 if (mkdtemp (&buffer[0]) == 0) {
892 return -1;
893 }
894
895 path_.assign (&buffer[0]);
896 file_ = path_ + "/socket";
897#else
898 LIBZMQ_UNUSED (path_);
899 int fd = mkstemp (&buffer[0]);
900 if (fd == -1)
901 return -1;
902 ::close (fd);
903
904 file_.assign (&buffer[0]);
905#endif
906#endif
907
908 return 0;
909}
910#endif
911