tipc_listener.cpp
Go to the documentation of this file.
1 /* SPDX-License-Identifier: MPL-2.0 */
2 
3 #include "precompiled.hpp"
4 
5 #include "tipc_listener.hpp"
6 
7 #if defined ZMQ_HAVE_TIPC
8 
9 #include <new>
10 
11 #include <string.h>
12 
13 #include "tipc_address.hpp"
14 #include "io_thread.hpp"
15 #include "config.hpp"
16 #include "err.hpp"
17 #include "ip.hpp"
18 #include "socket_base.hpp"
19 #include "address.hpp"
20 
21 #include <unistd.h>
22 #include <sys/socket.h>
23 #include <fcntl.h>
24 #if defined ZMQ_HAVE_VXWORKS
25 #include <sockLib.h>
26 #include <tipc/tipc.h>
27 #else
28 #include <linux/tipc.h>
29 #endif
30 
31 zmq::tipc_listener_t::tipc_listener_t (io_thread_t *io_thread_,
32  socket_base_t *socket_,
33  const options_t &options_) :
34  stream_listener_base_t (io_thread_, socket_, options_)
35 {
36 }
37 
38 void zmq::tipc_listener_t::in_event ()
39 {
40  fd_t fd = accept ();
41 
42  // If connection was reset by the peer in the meantime, just ignore it.
43  // TODO: Handle specific errors like ENFILE/EMFILE etc.
44  if (fd == retired_fd) {
45  _socket->event_accept_failed (
47  return;
48  }
49 
50  // Create the engine object for this connection.
51  create_engine (fd);
52 }
53 
56  socket_end_t socket_end_) const
57 {
58  return zmq::get_socket_name<tipc_address_t> (fd_, socket_end_);
59 }
60 
61 int zmq::tipc_listener_t::set_local_address (const char *addr_)
62 {
63  // Convert str to address struct
64  int rc = _address.resolve (addr_);
65  if (rc != 0)
66  return -1;
67 
68  // Cannot bind non-random Port Identity
69  const sockaddr_tipc *const a =
70  reinterpret_cast<const sockaddr_tipc *> (_address.addr ());
71  if (!_address.is_random () && a->addrtype == TIPC_ADDR_ID) {
72  errno = EINVAL;
73  return -1;
74  }
75 
76  // Create a listening socket.
77  _s = open_socket (AF_TIPC, SOCK_STREAM, 0);
78  if (_s == retired_fd)
79  return -1;
80 
81  // If random Port Identity, update address object to reflect the assigned address
82  if (_address.is_random ()) {
83  struct sockaddr_storage ss;
85  if (sl == 0)
86  goto error;
87 
88  _address =
89  tipc_address_t (reinterpret_cast<struct sockaddr *> (&ss), sl);
90  }
91 
92 
93  _address.to_string (_endpoint);
94 
95  // Bind the socket to tipc name
96  if (_address.is_service ()) {
97 #ifdef ZMQ_HAVE_VXWORKS
98  rc = bind (_s, (sockaddr *) address.addr (), address.addrlen ());
99 #else
100  rc = bind (_s, _address.addr (), _address.addrlen ());
101 #endif
102  if (rc != 0)
103  goto error;
104  }
105 
106  // Listen for incoming connections.
107  rc = listen (_s, options.backlog);
108  if (rc != 0)
109  goto error;
110 
111  _socket->event_listening (make_unconnected_bind_endpoint_pair (_endpoint),
112  _s);
113  return 0;
114 
115 error:
116  int err = errno;
117  close ();
118  errno = err;
119  return -1;
120 }
121 
122 zmq::fd_t zmq::tipc_listener_t::accept ()
123 {
124  // Accept one connection and deal with different failure modes.
125  // The situation where connection cannot be accepted due to insufficient
126  // resources is considered valid and treated by ignoring the connection.
127  struct sockaddr_storage ss = {};
128  socklen_t ss_len = sizeof (ss);
129 
130  zmq_assert (_s != retired_fd);
131 #ifdef ZMQ_HAVE_VXWORKS
132  fd_t sock = ::accept (_s, (struct sockaddr *) &ss, (int *) &ss_len);
133 #else
134  fd_t sock =
135  ::accept (_s, reinterpret_cast<struct sockaddr *> (&ss), &ss_len);
136 #endif
137  if (sock == -1) {
138  errno_assert (errno == EAGAIN || errno == EWOULDBLOCK
139  || errno == ENOBUFS || errno == EINTR
140  || errno == ECONNABORTED || errno == EPROTO
141  || errno == EMFILE || errno == ENFILE);
142  return retired_fd;
143  }
144  /*FIXME Accept filters?*/
145  return sock;
146 }
147 
148 #endif
zmq::get_socket_name
std::string get_socket_name(fd_t fd_, socket_end_t socket_end_)
Definition: address.hpp:120
tipc_listener.hpp
ip.hpp
zmq::socket_end_local
@ socket_end_local
Definition: address.hpp:112
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
EINVAL
#define EINVAL
Definition: errno.hpp:25
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
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
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
address.hpp
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
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
tipc_address.hpp
zmq::socket_end_t
socket_end_t
Definition: address.hpp:110
a
GLboolean GLboolean GLboolean GLboolean a
Definition: glcorearb.h:3228
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:00