25 #ifndef ZMQ_HAVE_WINDOWS
27 #include <sys/socket.h>
28 #include <arpa/inet.h>
29 #include <netinet/tcp.h>
30 #include <netinet/in.h>
33 #ifdef ZMQ_HAVE_VXWORKS
38 #ifdef ZMQ_HAVE_OPENVMS
42 zmq::ws_listener_t::ws_listener_t (io_thread_t *io_thread_,
43 socket_base_t *socket_,
46 stream_listener_base_t (io_thread_, socket_,
options_), _wss (wss_)
50 int rc = gnutls_certificate_allocate_credentials (&_tls_cred);
53 gnutls_datum_t
cert = {(
unsigned char *)
options_.wss_cert_pem.c_str (),
54 (
unsigned int)
options_.wss_cert_pem.length ()};
55 gnutls_datum_t
key = {(
unsigned char *)
options_.wss_key_pem.c_str (),
56 (
unsigned int)
options_.wss_key_pem.length ()};
57 rc = gnutls_certificate_set_x509_key_mem (_tls_cred, &
cert, &
key,
64 zmq::ws_listener_t::~ws_listener_t ()
68 gnutls_certificate_free_credentials (_tls_cred);
72 void zmq::ws_listener_t::in_event ()
74 const fd_t fd = accept ();
79 _socket->event_accept_failed (
87 _socket->event_accept_failed (
103 socket_name = zmq::get_socket_name<wss_address_t> (fd_, socket_end_);
106 socket_name = zmq::get_socket_name<ws_address_t> (fd_, socket_end_);
108 return socket_name + _address.path ();
111 int zmq::ws_listener_t::create_socket (
const char *addr_)
125 #ifdef ZMQ_HAVE_WINDOWS
131 rc = setsockopt (_s, SOL_SOCKET, SO_EXCLUSIVEADDRUSE,
132 reinterpret_cast<const char *
> (&flag),
sizeof (
int));
133 wsa_assert (rc != SOCKET_ERROR);
134 #elif defined ZMQ_HAVE_VXWORKS
136 setsockopt (_s, SOL_SOCKET, SO_REUSEADDR, (
char *) &flag,
sizeof (
int));
139 rc = setsockopt (_s, SOL_SOCKET, SO_REUSEADDR, &flag,
sizeof (
int));
144 #if defined ZMQ_HAVE_VXWORKS
145 rc = bind (_s, (sockaddr *) _address.addr (), _address.addrlen ());
149 #ifdef ZMQ_HAVE_WINDOWS
150 if (rc == SOCKET_ERROR) {
151 errno = wsa_error_to_errno (WSAGetLastError ());
160 rc = listen (_s,
options.backlog);
161 #ifdef ZMQ_HAVE_WINDOWS
162 if (rc == SOCKET_ERROR) {
163 errno = wsa_error_to_errno (WSAGetLastError ());
180 int zmq::ws_listener_t::set_local_address (
const char *addr_)
187 const int rc = _address.resolve (addr_,
true,
options.ipv6);
192 const char *delim = strrchr (addr_,
'/');
197 host_address = addr_;
200 if (create_socket (host_address.c_str ()) == -1)
218 struct sockaddr_storage ss;
219 memset (&ss, 0,
sizeof (ss));
220 #if defined ZMQ_HAVE_HPUX || defined ZMQ_HAVE_VXWORKS
221 int ss_len =
sizeof (ss);
223 socklen_t ss_len =
sizeof (ss);
225 #if defined ZMQ_HAVE_SOCK_CLOEXEC && defined HAVE_ACCEPT4
226 fd_t sock = ::accept4 (_s,
reinterpret_cast<struct sockaddr *
> (&ss),
227 &ss_len, SOCK_CLOEXEC);
230 ::accept (_s,
reinterpret_cast<struct sockaddr *
> (&ss), &ss_len);
234 #if defined ZMQ_HAVE_WINDOWS
235 const int last_error = WSAGetLastError ();
236 wsa_assert (last_error == WSAEWOULDBLOCK || last_error == WSAECONNRESET
237 || last_error == WSAEMFILE || last_error == WSAENOBUFS);
238 #elif defined ZMQ_HAVE_ANDROID
255 #ifdef ZMQ_HAVE_WINDOWS
257 wsa_assert (rc != SOCKET_ERROR);
259 int rc = ::close (
sock);
276 void zmq::ws_listener_t::create_engine (
fd_t fd_)
278 const endpoint_uri_pair_t endpoint_pair (
282 i_engine *engine =
NULL;
285 engine =
new (std::nothrow)
286 wss_engine_t (fd_,
options, endpoint_pair, _address,
false, _tls_cred,
292 engine =
new (std::nothrow)
293 ws_engine_t (fd_,
options, endpoint_pair, _address,
false);
299 io_thread_t *io_thread = choose_io_thread (
options.affinity);
303 session_base_t *session =
306 session->inc_seqnum ();
307 launch_child (session);
308 send_attach (session, engine,
false);
310 _socket->event_accepted (endpoint_pair, fd_);