vmci_listener.cpp
Go to the documentation of this file.
1 /* SPDX-License-Identifier: MPL-2.0 */
2 
3 #include "precompiled.hpp"
4 
5 #include "vmci_listener.hpp"
6 
7 #if defined ZMQ_HAVE_VMCI
8 
9 #include <new>
10 
11 //#include "stream_engine.hpp"
12 #include "vmci_address.hpp"
13 #include "io_thread.hpp"
14 #include "session_base.hpp"
15 #include "config.hpp"
16 #include "err.hpp"
17 #include "ip.hpp"
18 #include "socket_base.hpp"
19 #include "vmci.hpp"
20 
21 #if defined ZMQ_HAVE_WINDOWS
22 #include "windows.hpp"
23 #else
24 #include <unistd.h>
25 #include <fcntl.h>
26 #endif
27 
28 zmq::vmci_listener_t::vmci_listener_t (io_thread_t *io_thread_,
29  socket_base_t *socket_,
30  const options_t &options_) :
31  stream_listener_base_t (io_thread_, socket_, options_)
32 {
33 }
34 
35 void zmq::vmci_listener_t::in_event ()
36 {
37  fd_t fd = accept ();
38 
39  // If connection was reset by the peer in the meantime, just ignore it.
40  if (fd == retired_fd) {
41  _socket->event_accept_failed (
43  return;
44  }
45 
46  tune_vmci_buffer_size (this->get_ctx (), fd, options.vmci_buffer_size,
47  options.vmci_buffer_min_size,
48  options.vmci_buffer_max_size);
49 
50  if (options.vmci_connect_timeout > 0) {
51 #if defined ZMQ_HAVE_WINDOWS
52  tune_vmci_connect_timeout (this->get_ctx (), fd,
53  options.vmci_connect_timeout);
54 #else
55  struct timeval timeout = {0, options.vmci_connect_timeout * 1000};
56  tune_vmci_connect_timeout (this->get_ctx (), fd, timeout);
57 #endif
58  }
59 
60  // Create the engine object for this connection.
61  create_engine (fd);
62 }
63 
66  socket_end_t socket_end_) const
67 {
68  struct sockaddr_storage ss;
69  const zmq_socklen_t sl = get_socket_address (fd_, socket_end_, &ss);
70  if (sl == 0) {
71  return std::string ();
72  }
73 
74  const vmci_address_t addr (reinterpret_cast<struct sockaddr *> (&ss), sl,
75  this->get_ctx ());
76  std::string address_string;
77  addr.to_string (address_string);
78  return address_string;
79 }
80 
81 int zmq::vmci_listener_t::set_local_address (const char *addr_)
82 {
83  // Create addr on stack for auto-cleanup
84  std::string addr (addr_);
85 
86  // Initialise the address structure.
87  vmci_address_t address (this->get_ctx ());
88  int rc = address.resolve (addr.c_str ());
89  if (rc != 0)
90  return -1;
91 
92  // Create a listening socket.
93  _s =
94  open_socket (this->get_ctx ()->get_vmci_socket_family (), SOCK_STREAM, 0);
95 #ifdef ZMQ_HAVE_WINDOWS
96  if (s == INVALID_SOCKET) {
97  errno = wsa_error_to_errno (WSAGetLastError ());
98  return -1;
99  }
100 #if !defined _WIN32_WCE
101  // On Windows, preventing sockets to be inherited by child processes.
102  BOOL brc = SetHandleInformation ((HANDLE) _s, HANDLE_FLAG_INHERIT, 0);
103  win_assert (brc);
104 #endif
105 #else
106  if (_s == -1)
107  return -1;
108 #endif
109 
110  address.to_string (_endpoint);
111 
112  // Bind the socket.
113  rc = bind (_s, address.addr (), address.addrlen ());
114 #ifdef ZMQ_HAVE_WINDOWS
115  if (rc == SOCKET_ERROR) {
116  errno = wsa_error_to_errno (WSAGetLastError ());
117  goto error;
118  }
119 #else
120  if (rc != 0)
121  goto error;
122 #endif
123 
124  // Listen for incoming connections.
125  rc = listen (_s, options.backlog);
126 #ifdef ZMQ_HAVE_WINDOWS
127  if (rc == SOCKET_ERROR) {
128  errno = wsa_error_to_errno (WSAGetLastError ());
129  goto error;
130  }
131 #else
132  if (rc != 0)
133  goto error;
134 #endif
135 
136  _socket->event_listening (make_unconnected_bind_endpoint_pair (_endpoint),
137  _s);
138  return 0;
139 
140 error:
141  int err = errno;
142  close ();
143  errno = err;
144  return -1;
145 }
146 
147 zmq::fd_t zmq::vmci_listener_t::accept ()
148 {
149  // Accept one connection and deal with different failure modes.
150  // The situation where connection cannot be accepted due to insufficient
151  // resources is considered valid and treated by ignoring the connection.
152  zmq_assert (_s != retired_fd);
153  fd_t sock = ::accept (_s, NULL, NULL);
154 
155 #ifdef ZMQ_HAVE_WINDOWS
156  if (sock == INVALID_SOCKET) {
157  wsa_assert (WSAGetLastError () == WSAEWOULDBLOCK
158  || WSAGetLastError () == WSAECONNRESET
159  || WSAGetLastError () == WSAEMFILE
160  || WSAGetLastError () == WSAENOBUFS);
161  return retired_fd;
162  }
163 #if !defined _WIN32_WCE
164  // On Windows, preventing sockets to be inherited by child processes.
165  BOOL brc = SetHandleInformation ((HANDLE) sock, HANDLE_FLAG_INHERIT, 0);
166  win_assert (brc);
167 #endif
168 #else
169  if (sock == -1) {
170  errno_assert (errno == EAGAIN || errno == EWOULDBLOCK || errno == EINTR
171  || errno == ECONNABORTED || errno == EPROTO
172  || errno == ENOBUFS || errno == ENOMEM || errno == EMFILE
173  || errno == ENFILE);
174  return retired_fd;
175  }
176 #endif
177 
178  // Race condition can cause socket not to be closed (if fork happens
179  // between accept and this point).
180 #ifdef FD_CLOEXEC
181  int rc = fcntl (sock, F_SETFD, FD_CLOEXEC);
182  errno_assert (rc != -1);
183 #endif
184 
185  return sock;
186 }
187 
188 #endif
zmq::get_socket_name
std::string get_socket_name(fd_t fd_, socket_end_t socket_end_)
Definition: address.hpp:120
ip.hpp
NULL
NULL
Definition: test_security_zap.cpp:405
EINTR
#define EINTR
Definition: errno.hpp:7
config.hpp
options
Message * options
Definition: src/google/protobuf/descriptor.cc:3119
zmq_errno
ZMQ_EXPORT int zmq_errno(void)
Definition: zmq.cpp:101
sock
void * sock
Definition: test_connect_resolve.cpp:9
EAGAIN
#define EAGAIN
Definition: errno.hpp:14
precompiled.hpp
zmq_assert
#define zmq_assert(x)
Definition: err.hpp:102
vmci_listener.hpp
string
GLsizei const GLchar *const * string
Definition: glcorearb.h:3083
errno
int errno
address
const char * address
Definition: builds/zos/test_fork.cpp:6
error
Definition: cJSON.c:88
zmq::fd_t
int fd_t
Definition: zmq.hpp:287
retired_fd
@ retired_fd
Definition: libzmq/tests/testutil.hpp:117
EPROTO
#define EPROTO
Definition: err.hpp:26
errno_assert
#define errno_assert(x)
Definition: err.hpp:113
ECONNABORTED
#define ECONNABORTED
Definition: zmq.h:140
windows.hpp
zmq::get_socket_address
zmq_socklen_t get_socket_address(fd_t fd_, socket_end_t socket_end_, sockaddr_storage *ss_)
Definition: address.cpp:102
zmq::make_unconnected_bind_endpoint_pair
endpoint_uri_pair_t make_unconnected_bind_endpoint_pair(const std::string &endpoint_)
Definition: endpoint.cpp:14
err
static UPB_NORETURN void err(tarjan *t)
Definition: ruby/ext/google/protobuf_c/upb.c:5856
timeout
GLbitfield GLuint64 timeout
Definition: glcorearb.h:3588
zmq::open_socket
fd_t open_socket(int domain_, int type_, int protocol_)
Definition: ip.cpp:73
io_thread.hpp
ENOBUFS
#define ENOBUFS
Definition: zmq.h:110
vmci.hpp
socket_base.hpp
zmq::zmq_socklen_t
socklen_t zmq_socklen_t
Definition: address.hpp:107
err.hpp
fd_t
zmq_fd_t fd_t
Definition: libzmq/tests/testutil.hpp:98
HANDLE
void * HANDLE
Definition: wepoll.c:70
vmci_address.hpp
zmq::socket_end_t
socket_end_t
Definition: address.hpp:110
session_base.hpp
EMFILE
#define EMFILE
Definition: errno.hpp:27
options_
DebugStringOptions options_
Definition: src/google/protobuf/descriptor.cc:2410


libaditof
Author(s):
autogenerated on Wed May 21 2025 02:07:01