tipc_connecter.cpp
Go to the documentation of this file.
1 /* SPDX-License-Identifier: MPL-2.0 */
2 
3 #include "precompiled.hpp"
4 
5 #include "tipc_connecter.hpp"
6 
7 #if defined ZMQ_HAVE_TIPC
8 
9 #include <new>
10 #include <string>
11 
12 #include "io_thread.hpp"
13 #include "platform.hpp"
14 #include "random.hpp"
15 #include "err.hpp"
16 #include "ip.hpp"
17 #include "address.hpp"
18 #include "tipc_address.hpp"
19 #include "session_base.hpp"
20 
21 #include <unistd.h>
22 #include <sys/types.h>
23 #include <sys/socket.h>
24 #ifdef ZMQ_HAVE_VXWORKS
25 #include <sockLib.h>
26 #endif
27 
28 zmq::tipc_connecter_t::tipc_connecter_t (class io_thread_t *io_thread_,
29  class session_base_t *session_,
30  const options_t &options_,
31  address_t *addr_,
32  bool delayed_start_) :
33  stream_connecter_base_t (
34  io_thread_, session_, options_, addr_, delayed_start_)
35 {
36  zmq_assert (_addr->protocol == "tipc");
37 }
38 
39 void zmq::tipc_connecter_t::out_event ()
40 {
41  fd_t fd = connect ();
42  rm_handle ();
43 
44  // Handle the error condition by attempt to reconnect.
45  if (fd == retired_fd) {
46  close ();
47  add_reconnect_timer ();
48  return;
49  }
50 
51  create_engine (fd, get_socket_name<tipc_address_t> (fd, socket_end_local));
52 }
53 
54 void zmq::tipc_connecter_t::start_connecting ()
55 {
56  // Open the connecting socket.
57  int rc = open ();
58 
59  // Connect may succeed in synchronous manner.
60  if (rc == 0) {
61  _handle = add_fd (_s);
62  out_event ();
63  }
64 
65  // Connection establishment may be delayed. Poll for its completion.
66  else if (rc == -1 && errno == EINPROGRESS) {
67  _handle = add_fd (_s);
68  set_pollout (_handle);
69  _socket->event_connect_delayed (
71  }
72 
73  // Handle any other error condition by eventual reconnect.
74  else {
75  if (_s != retired_fd)
76  close ();
77  add_reconnect_timer ();
78  }
79 }
80 
81 int zmq::tipc_connecter_t::open ()
82 {
83  zmq_assert (_s == retired_fd);
84 
85  // Cannot connect to random tipc addresses
86  if (_addr->resolved.tipc_addr->is_random ()) {
87  errno = EINVAL;
88  return -1;
89  }
90  // Create the socket.
91  _s = open_socket (AF_TIPC, SOCK_STREAM, 0);
92  if (_s == retired_fd)
93  return -1;
94 
95  // Set the non-blocking flag.
96  unblock_socket (_s);
97  // Connect to the remote peer.
98 #ifdef ZMQ_HAVE_VXWORKS
99  int rc = ::connect (s, (sockaddr *) addr->resolved.tipc_addr->addr (),
100  addr->resolved.tipc_addr->addrlen ());
101 #else
102  int rc = ::connect (_s, _addr->resolved.tipc_addr->addr (),
103  _addr->resolved.tipc_addr->addrlen ());
104 #endif
105  // Connect was successful immediately.
106  if (rc == 0)
107  return 0;
108 
109  // Translate other error codes indicating asynchronous connect has been
110  // launched to a uniform EINPROGRESS.
111  if (rc == -1 && errno == EINTR) {
112  errno = EINPROGRESS;
113  return -1;
114  }
115  // Forward the error.
116  return -1;
117 }
118 
119 zmq::fd_t zmq::tipc_connecter_t::connect ()
120 {
121  // Following code should handle both Berkeley-derived socket
122  // implementations and Solaris.
123  int err = 0;
124 #ifdef ZMQ_HAVE_VXWORKS
125  int len = sizeof (err);
126 #else
127  socklen_t len = sizeof (err);
128 #endif
129  int rc = getsockopt (_s, SOL_SOCKET, SO_ERROR,
130  reinterpret_cast<char *> (&err), &len);
131  if (rc == -1)
132  err = errno;
133  if (err != 0) {
134  // Assert if the error was caused by 0MQ bug.
135  // Networking problems are OK. No need to assert.
136  errno = err;
138  || errno == ETIMEDOUT || errno == EHOSTUNREACH
139  || errno == ENETUNREACH || errno == ENETDOWN);
140 
141  return retired_fd;
142  }
143  fd_t result = _s;
144  _s = retired_fd;
145  return result;
146 }
147 
148 #endif
ip.hpp
zmq::socket_end_local
@ socket_end_local
Definition: address.hpp:112
zmq::make_unconnected_connect_endpoint_pair
endpoint_uri_pair_t make_unconnected_connect_endpoint_pair(const std::string &endpoint_)
Definition: endpoint.cpp:7
EINTR
#define EINTR
Definition: errno.hpp:7
zmq_errno
ZMQ_EXPORT int zmq_errno(void)
Definition: zmq.cpp:101
EINVAL
#define EINVAL
Definition: errno.hpp:25
precompiled.hpp
zmq_assert
#define zmq_assert(x)
Definition: err.hpp:102
random.hpp
errno
int errno
ECONNREFUSED
#define ECONNREFUSED
Definition: zmq.h:122
zmq::fd_t
int fd_t
Definition: zmq.hpp:287
retired_fd
@ retired_fd
Definition: libzmq/tests/testutil.hpp:117
errno_assert
#define errno_assert(x)
Definition: err.hpp:113
err
static UPB_NORETURN void err(tarjan *t)
Definition: ruby/ext/google/protobuf_c/upb.c:5856
ENETDOWN
#define ENETDOWN
Definition: zmq.h:113
EINPROGRESS
#define EINPROGRESS
Definition: zmq.h:125
address.hpp
zmq::unblock_socket
void unblock_socket(fd_t s_)
Definition: ip.cpp:107
zmq::open_socket
fd_t open_socket(int domain_, int type_, int protocol_)
Definition: ip.cpp:73
tipc_connecter.hpp
io_thread.hpp
len
int len
Definition: php/ext/google/protobuf/map.c:206
ECONNRESET
#define ECONNRESET
Definition: zmq.h:143
err.hpp
fd_t
zmq_fd_t fd_t
Definition: libzmq/tests/testutil.hpp:98
EHOSTUNREACH
#define EHOSTUNREACH
Definition: zmq.h:152
ENETUNREACH
#define ENETUNREACH
Definition: zmq.h:137
ETIMEDOUT
#define ETIMEDOUT
Definition: zmq.h:149
tipc_address.hpp
session_base.hpp
options_
DebugStringOptions options_
Definition: src/google/protobuf/descriptor.cc:2410


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