mirror of
https://github.com/zeromq/libzmq.git
synced 2024-12-12 10:33:52 +01:00
Resolve addresses in the calling thread on connect.
This allows us to actually report an error to the caller on resolve failure, rather than asserting later on in the io thread. Signed-off-by: Staffan Gimåker <staffan@spotify.com>
This commit is contained in:
parent
b2e2fa622d
commit
b9fb48f47b
@ -6,6 +6,7 @@ pkgconfig_DATA = libzmq.pc
|
||||
include_HEADERS = ../include/zmq.h ../include/zmq_utils.h
|
||||
|
||||
libzmq_la_SOURCES = \
|
||||
address.hpp \
|
||||
array.hpp \
|
||||
atomic_counter.hpp \
|
||||
atomic_ptr.hpp \
|
||||
@ -76,6 +77,7 @@ libzmq_la_SOURCES = \
|
||||
xsub.hpp \
|
||||
ypipe.hpp \
|
||||
yqueue.hpp \
|
||||
address.cpp \
|
||||
clock.cpp \
|
||||
ctx.cpp \
|
||||
decoder.cpp \
|
||||
|
50
src/address.cpp
Normal file
50
src/address.cpp
Normal file
@ -0,0 +1,50 @@
|
||||
/*
|
||||
Copyright (c) 2012 Spotify AB
|
||||
Copyright (c) 2012 Other contributors as noted in the AUTHORS file
|
||||
|
||||
This file is part of 0MQ.
|
||||
|
||||
0MQ is free software; you can redistribute it and/or modify it under
|
||||
the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation; either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
0MQ is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "address.hpp"
|
||||
#include "err.hpp"
|
||||
#include "tcp_address.hpp"
|
||||
#include "ipc_address.hpp"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
zmq::address_t::address_t (
|
||||
const std::string &protocol_, const std::string &address_)
|
||||
: protocol (protocol_),
|
||||
address (address_)
|
||||
{
|
||||
memset (&resolved, 0, sizeof (resolved));
|
||||
}
|
||||
|
||||
zmq::address_t::~address_t ()
|
||||
{
|
||||
if (protocol == "tcp") {
|
||||
if (resolved.tcp_addr) {
|
||||
delete resolved.tcp_addr;
|
||||
resolved.tcp_addr = 0;
|
||||
}
|
||||
}
|
||||
else if (protocol == "ipc") {
|
||||
if (resolved.ipc_addr) {
|
||||
delete resolved.ipc_addr;
|
||||
resolved.ipc_addr = 0;
|
||||
}
|
||||
}
|
||||
}
|
48
src/address.hpp
Normal file
48
src/address.hpp
Normal file
@ -0,0 +1,48 @@
|
||||
/*
|
||||
Copyright (c) 2012 Spotify AB
|
||||
Copyright (c) 2012 Other contributors as noted in the AUTHORS file
|
||||
|
||||
This file is part of 0MQ.
|
||||
|
||||
0MQ is free software; you can redistribute it and/or modify it under
|
||||
the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation; either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
0MQ is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef __ZMQ_ADDRESS_HPP_INCLUDED__
|
||||
#define __ZMQ_ADDRESS_HPP_INCLUDED__
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace zmq
|
||||
{
|
||||
class tcp_address_t;
|
||||
class ipc_address_t;
|
||||
|
||||
struct address_t {
|
||||
address_t (const std::string &protocol_, const std::string &address_);
|
||||
|
||||
~address_t ();
|
||||
|
||||
const std::string protocol;
|
||||
const std::string address;
|
||||
|
||||
// Protocol specific resolved address
|
||||
union {
|
||||
tcp_address_t *tcp_addr;
|
||||
ipc_address_t *ipc_addr;
|
||||
} resolved;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
@ -47,12 +47,12 @@ int zmq::ipc_address_t::resolve (const char *path_)
|
||||
return 0;
|
||||
}
|
||||
|
||||
sockaddr *zmq::ipc_address_t::addr ()
|
||||
const sockaddr *zmq::ipc_address_t::addr () const
|
||||
{
|
||||
return (sockaddr*) &address;
|
||||
}
|
||||
|
||||
socklen_t zmq::ipc_address_t::addrlen ()
|
||||
socklen_t zmq::ipc_address_t::addrlen () const
|
||||
{
|
||||
return (socklen_t) sizeof (address);
|
||||
}
|
||||
|
@ -41,8 +41,8 @@ namespace zmq
|
||||
// This function sets up the address for UNIX domain transport.
|
||||
int resolve (const char* path_);
|
||||
|
||||
sockaddr *addr ();
|
||||
socklen_t addrlen ();
|
||||
const sockaddr *addr () const;
|
||||
socklen_t addrlen () const;
|
||||
|
||||
private:
|
||||
|
||||
|
@ -31,6 +31,8 @@
|
||||
#include "random.hpp"
|
||||
#include "err.hpp"
|
||||
#include "ip.hpp"
|
||||
#include "address.hpp"
|
||||
#include "ipc_address.hpp"
|
||||
|
||||
#include <unistd.h>
|
||||
#include <sys/types.h>
|
||||
@ -39,19 +41,18 @@
|
||||
|
||||
zmq::ipc_connecter_t::ipc_connecter_t (class io_thread_t *io_thread_,
|
||||
class session_base_t *session_, const options_t &options_,
|
||||
const char *address_, bool wait_) :
|
||||
const address_t *addr_, bool wait_) :
|
||||
own_t (io_thread_, options_),
|
||||
io_object_t (io_thread_),
|
||||
addr (addr_),
|
||||
s (retired_fd),
|
||||
handle_valid (false),
|
||||
wait (wait_),
|
||||
session (session_),
|
||||
current_reconnect_ivl(options.reconnect_ivl)
|
||||
{
|
||||
// TODO: set_addess should be called separately, so that the error
|
||||
// can be propagated.
|
||||
int rc = set_address (address_);
|
||||
zmq_assert (rc == 0);
|
||||
zmq_assert (addr);
|
||||
zmq_assert (addr->protocol == "ipc");
|
||||
}
|
||||
|
||||
zmq::ipc_connecter_t::~ipc_connecter_t ()
|
||||
@ -165,11 +166,6 @@ int zmq::ipc_connecter_t::get_new_reconnect_ivl ()
|
||||
return this_interval;
|
||||
}
|
||||
|
||||
int zmq::ipc_connecter_t::set_address (const char *addr_)
|
||||
{
|
||||
return address.resolve (addr_);
|
||||
}
|
||||
|
||||
int zmq::ipc_connecter_t::open ()
|
||||
{
|
||||
zmq_assert (s == retired_fd);
|
||||
@ -183,7 +179,9 @@ int zmq::ipc_connecter_t::open ()
|
||||
unblock_socket (s);
|
||||
|
||||
// Connect to the remote peer.
|
||||
int rc = ::connect (s, address.addr (), address.addrlen ());
|
||||
int rc = ::connect (
|
||||
s, addr->resolved.ipc_addr->addr (),
|
||||
addr->resolved.ipc_addr->addrlen ());
|
||||
|
||||
// Connect was successfull immediately.
|
||||
if (rc == 0)
|
||||
|
@ -29,13 +29,13 @@
|
||||
#include "own.hpp"
|
||||
#include "stdint.hpp"
|
||||
#include "io_object.hpp"
|
||||
#include "ipc_address.hpp"
|
||||
|
||||
namespace zmq
|
||||
{
|
||||
|
||||
class io_thread_t;
|
||||
class session_base_t;
|
||||
struct address_t;
|
||||
|
||||
class ipc_connecter_t : public own_t, public io_object_t
|
||||
{
|
||||
@ -45,7 +45,7 @@ namespace zmq
|
||||
// connection process.
|
||||
ipc_connecter_t (zmq::io_thread_t *io_thread_,
|
||||
zmq::session_base_t *session_, const options_t &options_,
|
||||
const char *address_, bool delay_);
|
||||
const address_t *addr_, bool delay_);
|
||||
~ipc_connecter_t ();
|
||||
|
||||
private:
|
||||
@ -72,9 +72,6 @@ namespace zmq
|
||||
// Returns the currently used interval
|
||||
int get_new_reconnect_ivl ();
|
||||
|
||||
// Set address to connect to.
|
||||
int set_address (const char *addr_);
|
||||
|
||||
// Open IPC connecting socket. Returns -1 in case of error,
|
||||
// 0 if connect was successfull immediately. Returns -1 with
|
||||
// EAGAIN errno if async connect was launched.
|
||||
@ -87,8 +84,8 @@ namespace zmq
|
||||
// retired_fd if the connection was unsuccessfull.
|
||||
fd_t connect ();
|
||||
|
||||
// Address to connect to.
|
||||
ipc_address_t address;
|
||||
// Address to connect to. Owned by session_base_t.
|
||||
const address_t *addr;
|
||||
|
||||
// Underlying socket.
|
||||
fd_t s;
|
||||
|
@ -88,7 +88,7 @@ void zmq::ipc_listener_t::in_event ()
|
||||
|
||||
// Create and launch a session object.
|
||||
session_base_t *session = session_base_t::create (io_thread, false, socket,
|
||||
options, NULL, NULL);
|
||||
options, NULL);
|
||||
errno_assert (session);
|
||||
session->inc_seqnum ();
|
||||
launch_child (session);
|
||||
|
@ -119,9 +119,8 @@ bool zmq::pair_t::xhas_out ()
|
||||
|
||||
zmq::pair_session_t::pair_session_t (io_thread_t *io_thread_, bool connect_,
|
||||
socket_base_t *socket_, const options_t &options_,
|
||||
const char *protocol_, const char *address_) :
|
||||
session_base_t (io_thread_, connect_, socket_, options_, protocol_,
|
||||
address_)
|
||||
const address_t *addr_) :
|
||||
session_base_t (io_thread_, connect_, socket_, options_, addr_)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -65,7 +65,7 @@ namespace zmq
|
||||
|
||||
pair_session_t (zmq::io_thread_t *io_thread_, bool connect_,
|
||||
socket_base_t *socket_, const options_t &options_,
|
||||
const char *protocol_, const char *address_);
|
||||
const address_t *addr_);
|
||||
~pair_session_t ();
|
||||
|
||||
private:
|
||||
|
@ -46,9 +46,8 @@ bool zmq::pub_t::xhas_in ()
|
||||
|
||||
zmq::pub_session_t::pub_session_t (io_thread_t *io_thread_, bool connect_,
|
||||
socket_base_t *socket_, const options_t &options_,
|
||||
const char *protocol_, const char *address_) :
|
||||
xpub_session_t (io_thread_, connect_, socket_, options_, protocol_,
|
||||
address_)
|
||||
const address_t *addr_) :
|
||||
xpub_session_t (io_thread_, connect_, socket_, options_, addr_)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -55,7 +55,7 @@ namespace zmq
|
||||
|
||||
pub_session_t (zmq::io_thread_t *io_thread_, bool connect_,
|
||||
zmq::socket_base_t *socket_, const options_t &options_,
|
||||
const char *protocol_, const char *address_);
|
||||
const address_t *addr_);
|
||||
~pub_session_t ();
|
||||
|
||||
private:
|
||||
|
@ -62,9 +62,8 @@ bool zmq::pull_t::xhas_in ()
|
||||
|
||||
zmq::pull_session_t::pull_session_t (io_thread_t *io_thread_, bool connect_,
|
||||
socket_base_t *socket_, const options_t &options_,
|
||||
const char *protocol_, const char *address_) :
|
||||
session_base_t (io_thread_, connect_, socket_, options_, protocol_,
|
||||
address_)
|
||||
const address_t *addr_) :
|
||||
session_base_t (io_thread_, connect_, socket_, options_, addr_)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -67,7 +67,7 @@ namespace zmq
|
||||
|
||||
pull_session_t (zmq::io_thread_t *io_thread_, bool connect_,
|
||||
socket_base_t *socket_, const options_t &options_,
|
||||
const char *protocol_, const char *address_);
|
||||
const address_t *addr_);
|
||||
~pull_session_t ();
|
||||
|
||||
private:
|
||||
|
@ -62,9 +62,8 @@ bool zmq::push_t::xhas_out ()
|
||||
|
||||
zmq::push_session_t::push_session_t (io_thread_t *io_thread_, bool connect_,
|
||||
socket_base_t *socket_, const options_t &options_,
|
||||
const char *protocol_, const char *address_) :
|
||||
session_base_t (io_thread_, connect_, socket_, options_, protocol_,
|
||||
address_)
|
||||
const address_t *addr_) :
|
||||
session_base_t (io_thread_, connect_, socket_, options_, addr_)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -66,7 +66,7 @@ namespace zmq
|
||||
|
||||
push_session_t (zmq::io_thread_t *io_thread_, bool connect_,
|
||||
socket_base_t *socket_, const options_t &options_,
|
||||
const char *protocol_, const char *address_);
|
||||
const address_t *addr_);
|
||||
~push_session_t ();
|
||||
|
||||
private:
|
||||
|
@ -114,9 +114,8 @@ bool zmq::rep_t::xhas_out ()
|
||||
|
||||
zmq::rep_session_t::rep_session_t (io_thread_t *io_thread_, bool connect_,
|
||||
socket_base_t *socket_, const options_t &options_,
|
||||
const char *protocol_, const char *address_) :
|
||||
xrep_session_t (io_thread_, connect_, socket_, options_, protocol_,
|
||||
address_)
|
||||
const address_t *addr_) :
|
||||
xrep_session_t (io_thread_, connect_, socket_, options_, addr_)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -66,7 +66,7 @@ namespace zmq
|
||||
|
||||
rep_session_t (zmq::io_thread_t *io_thread_, bool connect_,
|
||||
zmq::socket_base_t *socket_, const options_t &options_,
|
||||
const char *protocol_, const char *address_);
|
||||
const address_t *addr_);
|
||||
~rep_session_t ();
|
||||
|
||||
private:
|
||||
|
@ -139,9 +139,8 @@ bool zmq::req_t::xhas_out ()
|
||||
|
||||
zmq::req_session_t::req_session_t (io_thread_t *io_thread_, bool connect_,
|
||||
socket_base_t *socket_, const options_t &options_,
|
||||
const char *protocol_, const char *address_) :
|
||||
xreq_session_t (io_thread_, connect_, socket_, options_, protocol_,
|
||||
address_),
|
||||
const address_t *addr_) :
|
||||
xreq_session_t (io_thread_, connect_, socket_, options_, addr_),
|
||||
state (identity)
|
||||
{
|
||||
}
|
||||
|
@ -67,7 +67,7 @@ namespace zmq
|
||||
|
||||
req_session_t (zmq::io_thread_t *io_thread_, bool connect_,
|
||||
zmq::socket_base_t *socket_, const options_t &options_,
|
||||
const char *protocol_, const char *address_);
|
||||
const address_t *addr_);
|
||||
~req_session_t ();
|
||||
|
||||
// Overloads of the functions from session_base_t.
|
||||
|
@ -30,6 +30,7 @@
|
||||
#include "ipc_connecter.hpp"
|
||||
#include "pgm_sender.hpp"
|
||||
#include "pgm_receiver.hpp"
|
||||
#include "address.hpp"
|
||||
|
||||
#include "req.hpp"
|
||||
#include "xreq.hpp"
|
||||
@ -45,52 +46,52 @@
|
||||
|
||||
zmq::session_base_t *zmq::session_base_t::create (class io_thread_t *io_thread_,
|
||||
bool connect_, class socket_base_t *socket_, const options_t &options_,
|
||||
const char *protocol_, const char *address_)
|
||||
const address_t *addr_)
|
||||
{
|
||||
session_base_t *s = NULL;
|
||||
switch (options_.type) {
|
||||
case ZMQ_REQ:
|
||||
s = new (std::nothrow) req_session_t (io_thread_, connect_,
|
||||
socket_, options_, protocol_, address_);
|
||||
socket_, options_, addr_);
|
||||
break;
|
||||
case ZMQ_XREQ:
|
||||
s = new (std::nothrow) xreq_session_t (io_thread_, connect_,
|
||||
socket_, options_, protocol_, address_);
|
||||
socket_, options_, addr_);
|
||||
case ZMQ_REP:
|
||||
s = new (std::nothrow) rep_session_t (io_thread_, connect_,
|
||||
socket_, options_, protocol_, address_);
|
||||
socket_, options_, addr_);
|
||||
break;
|
||||
case ZMQ_XREP:
|
||||
s = new (std::nothrow) xrep_session_t (io_thread_, connect_,
|
||||
socket_, options_, protocol_, address_);
|
||||
socket_, options_, addr_);
|
||||
break;
|
||||
case ZMQ_PUB:
|
||||
s = new (std::nothrow) pub_session_t (io_thread_, connect_,
|
||||
socket_, options_, protocol_, address_);
|
||||
socket_, options_, addr_);
|
||||
break;
|
||||
case ZMQ_XPUB:
|
||||
s = new (std::nothrow) xpub_session_t (io_thread_, connect_,
|
||||
socket_, options_, protocol_, address_);
|
||||
socket_, options_, addr_);
|
||||
break;
|
||||
case ZMQ_SUB:
|
||||
s = new (std::nothrow) sub_session_t (io_thread_, connect_,
|
||||
socket_, options_, protocol_, address_);
|
||||
socket_, options_, addr_);
|
||||
break;
|
||||
case ZMQ_XSUB:
|
||||
s = new (std::nothrow) xsub_session_t (io_thread_, connect_,
|
||||
socket_, options_, protocol_, address_);
|
||||
socket_, options_, addr_);
|
||||
break;
|
||||
case ZMQ_PUSH:
|
||||
s = new (std::nothrow) push_session_t (io_thread_, connect_,
|
||||
socket_, options_, protocol_, address_);
|
||||
socket_, options_, addr_);
|
||||
break;
|
||||
case ZMQ_PULL:
|
||||
s = new (std::nothrow) pull_session_t (io_thread_, connect_,
|
||||
socket_, options_, protocol_, address_);
|
||||
socket_, options_, addr_);
|
||||
break;
|
||||
case ZMQ_PAIR:
|
||||
s = new (std::nothrow) pair_session_t (io_thread_, connect_,
|
||||
socket_, options_, protocol_, address_);
|
||||
socket_, options_, addr_);
|
||||
break;
|
||||
default:
|
||||
errno = EINVAL;
|
||||
@ -102,7 +103,7 @@ zmq::session_base_t *zmq::session_base_t::create (class io_thread_t *io_thread_,
|
||||
|
||||
zmq::session_base_t::session_base_t (class io_thread_t *io_thread_,
|
||||
bool connect_, class socket_base_t *socket_, const options_t &options_,
|
||||
const char *protocol_, const char *address_) :
|
||||
const address_t *addr_) :
|
||||
own_t (io_thread_, options_),
|
||||
io_object_t (io_thread_),
|
||||
connect (connect_),
|
||||
@ -114,12 +115,9 @@ zmq::session_base_t::session_base_t (class io_thread_t *io_thread_,
|
||||
io_thread (io_thread_),
|
||||
has_linger_timer (false),
|
||||
send_identity (options_.send_identity),
|
||||
recv_identity (options_.recv_identity)
|
||||
recv_identity (options_.recv_identity),
|
||||
addr (addr_)
|
||||
{
|
||||
if (protocol_)
|
||||
protocol = protocol_;
|
||||
if (address_)
|
||||
address = address_;
|
||||
}
|
||||
|
||||
zmq::session_base_t::~session_base_t ()
|
||||
@ -135,6 +133,9 @@ zmq::session_base_t::~session_base_t ()
|
||||
// Close the engine.
|
||||
if (engine)
|
||||
engine->terminate ();
|
||||
|
||||
if (addr)
|
||||
delete addr;
|
||||
}
|
||||
|
||||
void zmq::session_base_t::attach_pipe (pipe_t *pipe_)
|
||||
@ -393,18 +394,18 @@ void zmq::session_base_t::start_connecting (bool wait_)
|
||||
|
||||
// Create the connecter object.
|
||||
|
||||
if (protocol == "tcp") {
|
||||
if (addr->protocol == "tcp") {
|
||||
tcp_connecter_t *connecter = new (std::nothrow) tcp_connecter_t (
|
||||
io_thread, this, options, address.c_str (), wait_);
|
||||
io_thread, this, options, addr, wait_);
|
||||
alloc_assert (connecter);
|
||||
launch_child (connecter);
|
||||
return;
|
||||
}
|
||||
|
||||
#if !defined ZMQ_HAVE_WINDOWS && !defined ZMQ_HAVE_OPENVMS
|
||||
if (protocol == "ipc") {
|
||||
if (addr->protocol == "ipc") {
|
||||
ipc_connecter_t *connecter = new (std::nothrow) ipc_connecter_t (
|
||||
io_thread, this, options, address.c_str (), wait_);
|
||||
io_thread, this, options, addr, wait_);
|
||||
alloc_assert (connecter);
|
||||
launch_child (connecter);
|
||||
return;
|
||||
@ -414,10 +415,10 @@ void zmq::session_base_t::start_connecting (bool wait_)
|
||||
#if defined ZMQ_HAVE_OPENPGM
|
||||
|
||||
// Both PGM and EPGM transports are using the same infrastructure.
|
||||
if (protocol == "pgm" || protocol == "epgm") {
|
||||
if (addr->protocol == "pgm" || addr->protocol == "epgm") {
|
||||
|
||||
// For EPGM transport with UDP encapsulation of PGM is used.
|
||||
bool udp_encapsulation = (protocol == "epgm");
|
||||
bool udp_encapsulation = (addr->protocol == "epgm");
|
||||
|
||||
// At this point we'll create message pipes to the session straight
|
||||
// away. There's no point in delaying it as no concept of 'connect'
|
||||
@ -429,7 +430,7 @@ void zmq::session_base_t::start_connecting (bool wait_)
|
||||
io_thread, options);
|
||||
alloc_assert (pgm_sender);
|
||||
|
||||
int rc = pgm_sender->init (udp_encapsulation, address.c_str ());
|
||||
int rc = pgm_sender->init (udp_encapsulation, addr->address.c_str ());
|
||||
zmq_assert (rc == 0);
|
||||
|
||||
send_attach (this, pgm_sender);
|
||||
@ -441,7 +442,7 @@ void zmq::session_base_t::start_connecting (bool wait_)
|
||||
io_thread, options);
|
||||
alloc_assert (pgm_receiver);
|
||||
|
||||
int rc = pgm_receiver->init (udp_encapsulation, address.c_str ());
|
||||
int rc = pgm_receiver->init (udp_encapsulation, addr->address.c_str ());
|
||||
zmq_assert (rc == 0);
|
||||
|
||||
send_attach (this, pgm_receiver);
|
||||
|
@ -36,6 +36,7 @@ namespace zmq
|
||||
class io_thread_t;
|
||||
class socket_base_t;
|
||||
struct i_engine;
|
||||
struct address_t;
|
||||
|
||||
class session_base_t :
|
||||
public own_t,
|
||||
@ -47,8 +48,7 @@ namespace zmq
|
||||
// Create a session of the particular type.
|
||||
static session_base_t *create (zmq::io_thread_t *io_thread_,
|
||||
bool connect_, zmq::socket_base_t *socket_,
|
||||
const options_t &options_, const char *protocol_,
|
||||
const char *address_);
|
||||
const options_t &options_, const address_t *addr_);
|
||||
|
||||
// To be used once only, when creating the session.
|
||||
void attach_pipe (zmq::pipe_t *pipe_);
|
||||
@ -69,8 +69,8 @@ namespace zmq
|
||||
|
||||
session_base_t (zmq::io_thread_t *io_thread_, bool connect_,
|
||||
zmq::socket_base_t *socket_, const options_t &options_,
|
||||
const char *protocol_, const char *address_);
|
||||
~session_base_t ();
|
||||
const address_t *addr_);
|
||||
virtual ~session_base_t ();
|
||||
|
||||
private:
|
||||
|
||||
@ -129,8 +129,7 @@ namespace zmq
|
||||
bool recv_identity;
|
||||
|
||||
// Protocol and address to use when connecting.
|
||||
std::string protocol;
|
||||
std::string address;
|
||||
const address_t *addr;
|
||||
|
||||
session_base_t (const session_base_t&);
|
||||
const session_base_t &operator = (const session_base_t&);
|
||||
|
@ -49,6 +49,9 @@
|
||||
#include "platform.hpp"
|
||||
#include "likely.hpp"
|
||||
#include "msg.hpp"
|
||||
#include "address.hpp"
|
||||
#include "ipc_address.hpp"
|
||||
#include "tcp_address.hpp"
|
||||
|
||||
#include "pair.hpp"
|
||||
#include "pub.hpp"
|
||||
@ -447,9 +450,33 @@ int zmq::socket_base_t::connect (const char *addr_)
|
||||
return -1;
|
||||
}
|
||||
|
||||
address_t *paddr = new (std::nothrow) address_t (protocol, address);
|
||||
zmq_assert (paddr);
|
||||
|
||||
// Resolve address (if needed by the protocol)
|
||||
if (protocol == "tcp") {
|
||||
paddr->resolved.tcp_addr = new (std::nothrow) tcp_address_t ();
|
||||
zmq_assert (paddr->resolved.tcp_addr);
|
||||
int rc = paddr->resolved.tcp_addr->resolve (
|
||||
address.c_str (), false, options.ipv4only ? true : false);
|
||||
if (rc != 0) {
|
||||
delete paddr;
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
else if(protocol == "ipc") {
|
||||
paddr->resolved.ipc_addr = new (std::nothrow) ipc_address_t ();
|
||||
zmq_assert (paddr->resolved.ipc_addr);
|
||||
int rc = paddr->resolved.ipc_addr->resolve (address.c_str ());
|
||||
if (rc != 0) {
|
||||
delete paddr;
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
// Create session.
|
||||
session_base_t *session = session_base_t::create (io_thread, true, this,
|
||||
options, protocol.c_str (), address.c_str ());
|
||||
options, paddr);
|
||||
errno_assert (session);
|
||||
|
||||
// Create a bi-directional pipe.
|
||||
|
@ -82,9 +82,8 @@ bool zmq::sub_t::xhas_out ()
|
||||
|
||||
zmq::sub_session_t::sub_session_t (io_thread_t *io_thread_, bool connect_,
|
||||
socket_base_t *socket_, const options_t &options_,
|
||||
const char *protocol_, const char *address_) :
|
||||
xsub_session_t (io_thread_, connect_, socket_, options_, protocol_,
|
||||
address_)
|
||||
const address_t *addr_) :
|
||||
xsub_session_t (io_thread_, connect_, socket_, options_, addr_)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -57,7 +57,7 @@ namespace zmq
|
||||
|
||||
sub_session_t (zmq::io_thread_t *io_thread_, bool connect_,
|
||||
zmq::socket_base_t *socket_, const options_t &options_,
|
||||
const char *protocol_, const char *address_);
|
||||
const address_t *addr_);
|
||||
~sub_session_t ();
|
||||
|
||||
private:
|
||||
|
@ -419,12 +419,12 @@ int zmq::tcp_address_t::resolve (const char *name_, bool local_, bool ipv4only_)
|
||||
return 0;
|
||||
}
|
||||
|
||||
sockaddr *zmq::tcp_address_t::addr ()
|
||||
const sockaddr *zmq::tcp_address_t::addr () const
|
||||
{
|
||||
return &address.generic;
|
||||
}
|
||||
|
||||
socklen_t zmq::tcp_address_t::addrlen ()
|
||||
socklen_t zmq::tcp_address_t::addrlen () const
|
||||
{
|
||||
if (address.generic.sa_family == AF_INET6)
|
||||
return (socklen_t) sizeof (address.ipv6);
|
||||
@ -433,9 +433,9 @@ socklen_t zmq::tcp_address_t::addrlen ()
|
||||
}
|
||||
|
||||
#if defined ZMQ_HAVE_WINDOWS
|
||||
unsigned short zmq::tcp_address_t::family ()
|
||||
unsigned short zmq::tcp_address_t::family () const
|
||||
#else
|
||||
sa_family_t zmq::tcp_address_t::family ()
|
||||
sa_family_t zmq::tcp_address_t::family () const
|
||||
#endif
|
||||
{
|
||||
return address.generic.sa_family;
|
||||
|
@ -48,12 +48,12 @@ namespace zmq
|
||||
int resolve (const char* name_, bool local_, bool ipv4only_);
|
||||
|
||||
#if defined ZMQ_HAVE_WINDOWS
|
||||
unsigned short family ();
|
||||
unsigned short family () const;
|
||||
#else
|
||||
sa_family_t family ();
|
||||
sa_family_t family () const;
|
||||
#endif
|
||||
sockaddr *addr ();
|
||||
socklen_t addrlen ();
|
||||
const sockaddr *addr () const;
|
||||
socklen_t addrlen () const;
|
||||
|
||||
private:
|
||||
|
||||
|
@ -29,6 +29,8 @@
|
||||
#include "random.hpp"
|
||||
#include "err.hpp"
|
||||
#include "ip.hpp"
|
||||
#include "address.hpp"
|
||||
#include "tcp_address.hpp"
|
||||
|
||||
#if defined ZMQ_HAVE_WINDOWS
|
||||
#include "windows.hpp"
|
||||
@ -48,19 +50,18 @@
|
||||
|
||||
zmq::tcp_connecter_t::tcp_connecter_t (class io_thread_t *io_thread_,
|
||||
class session_base_t *session_, const options_t &options_,
|
||||
const char *address_, bool wait_) :
|
||||
const address_t *addr_, bool wait_) :
|
||||
own_t (io_thread_, options_),
|
||||
io_object_t (io_thread_),
|
||||
addr (addr_),
|
||||
s (retired_fd),
|
||||
handle_valid (false),
|
||||
wait (wait_),
|
||||
session (session_),
|
||||
current_reconnect_ivl(options.reconnect_ivl)
|
||||
{
|
||||
// TODO: set_addess should be called separately, so that the error
|
||||
// can be propagated.
|
||||
int rc = set_address (address_);
|
||||
errno_assert (rc == 0);
|
||||
zmq_assert (addr);
|
||||
zmq_assert (addr->protocol == "tcp");
|
||||
}
|
||||
|
||||
zmq::tcp_connecter_t::~tcp_connecter_t ()
|
||||
@ -176,17 +177,12 @@ int zmq::tcp_connecter_t::get_new_reconnect_ivl ()
|
||||
return this_interval;
|
||||
}
|
||||
|
||||
int zmq::tcp_connecter_t::set_address (const char *addr_)
|
||||
{
|
||||
return address.resolve (addr_, false, options.ipv4only ? true : false);
|
||||
}
|
||||
|
||||
int zmq::tcp_connecter_t::open ()
|
||||
{
|
||||
zmq_assert (s == retired_fd);
|
||||
|
||||
// Create the socket.
|
||||
s = open_socket (address.family (), SOCK_STREAM, IPPROTO_TCP);
|
||||
s = open_socket (addr->resolved.tcp_addr->family (), SOCK_STREAM, IPPROTO_TCP);
|
||||
#ifdef ZMQ_HAVE_WINDOWS
|
||||
if (s == INVALID_SOCKET) {
|
||||
wsa_error_to_errno ();
|
||||
@ -199,14 +195,16 @@ int zmq::tcp_connecter_t::open ()
|
||||
|
||||
// On some systems, IPv4 mapping in IPv6 sockets is disabled by default.
|
||||
// Switch it on in such cases.
|
||||
if (address.family () == AF_INET6)
|
||||
if (addr->resolved.tcp_addr->family () == AF_INET6)
|
||||
enable_ipv4_mapping (s);
|
||||
|
||||
// Set the socket to non-blocking mode so that we get async connect().
|
||||
unblock_socket (s);
|
||||
|
||||
// Connect to the remote peer.
|
||||
int rc = ::connect (s, address.addr (), address.addrlen ());
|
||||
int rc = ::connect (
|
||||
s, addr->resolved.tcp_addr->addr (),
|
||||
addr->resolved.tcp_addr->addrlen ());
|
||||
|
||||
// Connect was successfull immediately.
|
||||
if (rc == 0)
|
||||
|
@ -26,13 +26,13 @@
|
||||
#include "own.hpp"
|
||||
#include "stdint.hpp"
|
||||
#include "io_object.hpp"
|
||||
#include "tcp_address.hpp"
|
||||
|
||||
namespace zmq
|
||||
{
|
||||
|
||||
class io_thread_t;
|
||||
class session_base_t;
|
||||
struct address_t;
|
||||
|
||||
class tcp_connecter_t : public own_t, public io_object_t
|
||||
{
|
||||
@ -42,7 +42,7 @@ namespace zmq
|
||||
// connection process.
|
||||
tcp_connecter_t (zmq::io_thread_t *io_thread_,
|
||||
zmq::session_base_t *session_, const options_t &options_,
|
||||
const char *address_, bool delay_);
|
||||
const address_t *addr_, bool delay_);
|
||||
~tcp_connecter_t ();
|
||||
|
||||
private:
|
||||
@ -69,9 +69,6 @@ namespace zmq
|
||||
// Returns the currently used interval
|
||||
int get_new_reconnect_ivl ();
|
||||
|
||||
// Set address to connect to.
|
||||
int set_address (const char *addr_);
|
||||
|
||||
// Open TCP connecting socket. Returns -1 in case of error,
|
||||
// 0 if connect was successfull immediately. Returns -1 with
|
||||
// EAGAIN errno if async connect was launched.
|
||||
@ -84,8 +81,8 @@ namespace zmq
|
||||
// retired_fd if the connection was unsuccessfull.
|
||||
fd_t connect ();
|
||||
|
||||
// Address to connect to.
|
||||
tcp_address_t address;
|
||||
// Address to connect to. Owned by session_base_t.
|
||||
const address_t *addr;
|
||||
|
||||
// Underlying socket.
|
||||
fd_t s;
|
||||
|
@ -100,7 +100,7 @@ void zmq::tcp_listener_t::in_event ()
|
||||
|
||||
// Create and launch a session object.
|
||||
session_base_t *session = session_base_t::create (io_thread, false, socket,
|
||||
options, NULL, NULL);
|
||||
options, NULL);
|
||||
errno_assert (session);
|
||||
session->inc_seqnum ();
|
||||
launch_child (session);
|
||||
|
@ -176,9 +176,8 @@ void zmq::xpub_t::send_unsubscription (unsigned char *data_, size_t size_,
|
||||
|
||||
zmq::xpub_session_t::xpub_session_t (io_thread_t *io_thread_, bool connect_,
|
||||
socket_base_t *socket_, const options_t &options_,
|
||||
const char *protocol_, const char *address_) :
|
||||
session_base_t (io_thread_, connect_, socket_, options_, protocol_,
|
||||
address_)
|
||||
const address_t *addr_) :
|
||||
session_base_t (io_thread_, connect_, socket_, options_, addr_)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -91,7 +91,7 @@ namespace zmq
|
||||
|
||||
xpub_session_t (zmq::io_thread_t *io_thread_, bool connect_,
|
||||
socket_base_t *socket_, const options_t &options_,
|
||||
const char *protocol_, const char *address_);
|
||||
const address_t *addr_);
|
||||
~xpub_session_t ();
|
||||
|
||||
private:
|
||||
|
@ -309,9 +309,8 @@ bool zmq::xrep_t::xhas_out ()
|
||||
|
||||
zmq::xrep_session_t::xrep_session_t (io_thread_t *io_thread_, bool connect_,
|
||||
socket_base_t *socket_, const options_t &options_,
|
||||
const char *protocol_, const char *address_) :
|
||||
session_base_t (io_thread_, connect_, socket_, options_, protocol_,
|
||||
address_)
|
||||
const address_t *addr_) :
|
||||
session_base_t (io_thread_, connect_, socket_, options_, addr_)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -110,7 +110,7 @@ namespace zmq
|
||||
|
||||
xrep_session_t (zmq::io_thread_t *io_thread_, bool connect_,
|
||||
socket_base_t *socket_, const options_t &options_,
|
||||
const char *protocol_, const char *address_);
|
||||
const address_t *addr_);
|
||||
~xrep_session_t ();
|
||||
|
||||
private:
|
||||
|
@ -117,9 +117,8 @@ void zmq::xreq_t::xterminated (pipe_t *pipe_)
|
||||
|
||||
zmq::xreq_session_t::xreq_session_t (io_thread_t *io_thread_, bool connect_,
|
||||
socket_base_t *socket_, const options_t &options_,
|
||||
const char *protocol_, const char *address_) :
|
||||
session_base_t (io_thread_, connect_, socket_, options_, protocol_,
|
||||
address_)
|
||||
const address_t *addr_) :
|
||||
session_base_t (io_thread_, connect_, socket_, options_, addr_)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -78,7 +78,7 @@ namespace zmq
|
||||
|
||||
xreq_session_t (zmq::io_thread_t *io_thread_, bool connect_,
|
||||
zmq::socket_base_t *socket_, const options_t &options_,
|
||||
const char *protocol_, const char *address_);
|
||||
const address_t *addr_);
|
||||
~xreq_session_t ();
|
||||
|
||||
private:
|
||||
|
@ -220,9 +220,8 @@ void zmq::xsub_t::send_subscription (unsigned char *data_, size_t size_,
|
||||
|
||||
zmq::xsub_session_t::xsub_session_t (io_thread_t *io_thread_, bool connect_,
|
||||
socket_base_t *socket_, const options_t &options_,
|
||||
const char *protocol_, const char *address_) :
|
||||
session_base_t (io_thread_, connect_, socket_, options_, protocol_,
|
||||
address_)
|
||||
const address_t *addr_) :
|
||||
session_base_t (io_thread_, connect_, socket_, options_, addr_)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -93,7 +93,7 @@ namespace zmq
|
||||
|
||||
xsub_session_t (class io_thread_t *io_thread_, bool connect_,
|
||||
socket_base_t *socket_, const options_t &options_,
|
||||
const char *protocol_, const char *address_);
|
||||
const address_t *addr_);
|
||||
~xsub_session_t ();
|
||||
|
||||
private:
|
||||
|
@ -11,7 +11,8 @@ noinst_PROGRAMS = test_pair_inproc \
|
||||
test_reqrep_device \
|
||||
test_sub_forward \
|
||||
test_invalid_rep \
|
||||
test_msg_flags
|
||||
test_msg_flags \
|
||||
test_connect_resolve
|
||||
|
||||
if !ON_MINGW
|
||||
noinst_PROGRAMS += test_shutdown_stress \
|
||||
@ -30,6 +31,7 @@ test_reqrep_device_SOURCES = test_reqrep_device.cpp
|
||||
test_sub_forward_SOURCES = test_sub_forward.cpp
|
||||
test_invalid_rep_SOURCES = test_invalid_rep.cpp
|
||||
test_msg_flags_SOURCES = test_msg_flags.cpp
|
||||
test_connect_resolve_SOURCES = test_connect_resolve.cpp
|
||||
|
||||
if !ON_MINGW
|
||||
test_shutdown_stress_SOURCES = test_shutdown_stress.cpp
|
||||
|
54
tests/test_connect_resolve.cpp
Normal file
54
tests/test_connect_resolve.cpp
Normal file
@ -0,0 +1,54 @@
|
||||
/*
|
||||
Copyright (c) 2012 Spotify AB
|
||||
Copyright (c) 2012 Other contributors as noted in the AUTHORS file
|
||||
|
||||
This file is part of 0MQ.
|
||||
|
||||
0MQ is free software; you can redistribute it and/or modify it under
|
||||
the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation; either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
0MQ is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include "../include/zmq.h"
|
||||
|
||||
int main (int argc, char *argv [])
|
||||
{
|
||||
fprintf (stderr, "test_connect_resolve running...\n");
|
||||
|
||||
void *ctx = zmq_init (1);
|
||||
assert (ctx);
|
||||
|
||||
// Create pair of socket, each with high watermark of 2. Thus the total
|
||||
// buffer space should be 4 messages.
|
||||
void *sock = zmq_socket (ctx, ZMQ_PUB);
|
||||
assert (sock);
|
||||
|
||||
int rc = zmq_connect (sock, "tcp://localhost:1234");
|
||||
assert (rc == 0);
|
||||
|
||||
rc = zmq_connect (sock, "tcp://foobar123xyz:1234");
|
||||
assert (rc == -1);
|
||||
assert (errno == EINVAL);
|
||||
|
||||
rc = zmq_close (sock);
|
||||
assert (rc == 0);
|
||||
|
||||
rc = zmq_term (ctx);
|
||||
assert (rc == 0);
|
||||
|
||||
return 0;
|
||||
}
|
Loading…
Reference in New Issue
Block a user