Commit 26349349 authored by Martin Sustrik's avatar Martin Sustrik

IPv6 patch part 2/2

parent 6aaf095d
......@@ -174,7 +174,8 @@ static int resolve_nic_name (in_addr* addr_, char const *interface_)
#endif
int zmq::resolve_ip_interface (sockaddr_storage* addr_, char const *interface_)
int zmq::resolve_ip_interface (sockaddr_storage* addr_, socklen_t *addr_len_,
char const *interface_)
{
// Find the end ':' that separates NIC name from service.
const char *delimiter = strrchr (interface_, ':');
......@@ -183,7 +184,7 @@ int zmq::resolve_ip_interface (sockaddr_storage* addr_, char const *interface_)
return -1;
}
// Separate the name/port
// Separate the name/port.
std::string interface (interface_, delimiter - interface_);
std::string service (delimiter + 1);
......@@ -195,6 +196,7 @@ int zmq::resolve_ip_interface (sockaddr_storage* addr_, char const *interface_)
ip4_addr.sin_family = AF_INET;
ip4_addr.sin_port = htons ((uint16_t) atoi (service.c_str()));
// Initialize temporary output pointers with ip4_addr
sockaddr *out_addr = (sockaddr *) &ip4_addr;
size_t out_addrlen = sizeof (ip4_addr);
......@@ -210,6 +212,7 @@ int zmq::resolve_ip_interface (sockaddr_storage* addr_, char const *interface_)
ip4_addr.sin_addr.s_addr = htonl (INADDR_ANY);
zmq_assert (out_addrlen <= sizeof (*addr_));
memcpy (addr_, out_addr, out_addrlen);
*addr_len_ = out_addrlen;
return 0;
}
......@@ -220,11 +223,13 @@ int zmq::resolve_ip_interface (sockaddr_storage* addr_, char const *interface_)
if (rc == 0) {
zmq_assert (out_addrlen <= sizeof (*addr_));
memcpy (addr_, out_addr, out_addrlen);
*addr_len_ = out_addrlen;
return 0;
}
// There's no such interface name. Assume literal address.
rc = inet_pton (AF_INET, interface.c_str(), &ip4_addr.sin_addr);
if (rc == 0) {
errno = ENODEV;
return -1;
......@@ -234,10 +239,12 @@ int zmq::resolve_ip_interface (sockaddr_storage* addr_, char const *interface_)
zmq_assert (out_addrlen <= sizeof (*addr_));
memcpy (addr_, out_addr, out_addrlen);
*addr_len_ = out_addrlen;
return 0;
}
int zmq::resolve_ip_hostname (sockaddr_storage *addr_, const char *hostname_)
int zmq::resolve_ip_hostname (sockaddr_storage *addr_, socklen_t *addr_len_,
const char *hostname_)
{
sockaddr_in *addr = (sockaddr_in*) addr_;
......@@ -256,6 +263,8 @@ int zmq::resolve_ip_hostname (sockaddr_storage *addr_, const char *hostname_)
addrinfo req;
memset (&req, 0, sizeof (req));
req.ai_family = AF_INET;
*addr_len_ = sizeof (*addr_);
addrinfo *res;
int rc = getaddrinfo (hostname.c_str (), NULL, &req, &res);
if (rc) {
......@@ -278,15 +287,18 @@ int zmq::resolve_ip_hostname (sockaddr_storage *addr_, const char *hostname_)
#if !defined ZMQ_HAVE_WINDOWS && !defined ZMQ_HAVE_OPENVMS
int zmq::resolve_local_path (sockaddr_un *addr_, const char *path_)
int zmq::resolve_local_path (sockaddr_storage *addr_, socklen_t *addr_len_,
const char *path_)
{
if (strlen (path_) >= sizeof (addr_->sun_path))
sockaddr_un *un = (sockaddr_un*) addr_;
if (strlen (path_) >= sizeof (un->sun_path))
{
errno = ENAMETOOLONG;
return -1;
}
strcpy (addr_->sun_path, path_);
addr_->sun_family = AF_UNIX;
strcpy (un->sun_path, path_);
un->sun_family = AF_UNIX;
*addr_len_ = sizeof (sockaddr_un);
return 0;
}
......
......@@ -41,15 +41,18 @@ namespace zmq
// Resolves network interface name in <nic-name>:<port> format. Symbol "*"
// (asterisk) resolves to INADDR_ANY (all network interfaces).
int resolve_ip_interface (sockaddr_storage *addr_, char const *interface_);
int resolve_ip_interface (sockaddr_storage *addr_, socklen_t *addr_len_,
char const *interface_);
// This function resolves a string in <hostname>:<port-number> format.
// Hostname can be either the name of the host or its IP address.
int resolve_ip_hostname (sockaddr_storage *addr_, const char *hostname_);
int resolve_ip_hostname (sockaddr_storage *addr_, socklen_t *addr_len_,
const char *hostname_);
#if !defined ZMQ_HAVE_WINDOWS && !defined ZMQ_HAVE_OPENVMS
// This function sets up the sockaddr_un structure with the pathname_
int resolve_local_path (sockaddr_un *addr_, const char* pathname_);
// This function sets up address for UNIX domain transport.
int resolve_local_path (sockaddr_storage *addr_, socklen_t *addr_len_,
const char* pathname_);
#endif
}
......
......@@ -34,6 +34,7 @@ zmq::tcp_connecter_t::tcp_connecter_t () :
s (retired_fd)
{
memset (&addr, 0, sizeof (addr));
addr_len = 0;
}
zmq::tcp_connecter_t::~tcp_connecter_t ()
......@@ -45,7 +46,7 @@ zmq::tcp_connecter_t::~tcp_connecter_t ()
int zmq::tcp_connecter_t::set_address (const char *protocol_, const char *addr_)
{
if (strcmp (protocol_, "tcp") == 0)
return resolve_ip_hostname (&addr, addr_);
return resolve_ip_hostname (&addr, &addr_len, addr_);
errno = EPROTONOSUPPORT;
return -1;
......@@ -74,7 +75,7 @@ int zmq::tcp_connecter_t::open ()
wsa_assert (rc != SOCKET_ERROR);
// Connect to the remote peer.
rc = ::connect (s, (sockaddr*) &addr, sizeof (addr));
rc = ::connect (s, (sockaddr*) &addr, addr_len);
// Connect was successfull immediately.
if (rc == 0)
......@@ -153,9 +154,9 @@ zmq::tcp_connecter_t::~tcp_connecter_t ()
int zmq::tcp_connecter_t::set_address (const char *protocol_, const char *addr_)
{
if (strcmp (protocol_, "tcp") == 0)
return resolve_ip_hostname (&addr, addr_);
return resolve_ip_hostname (&addr, &addr_len, addr_);
else if (strcmp (protocol_, "ipc") == 0)
return resolve_local_path (( struct sockaddr_un*)&addr, addr_);
return resolve_local_path (&addr, &addr_len, addr_);
errno = EPROTONOSUPPORT;
return -1;
......@@ -182,18 +183,20 @@ int zmq::tcp_connecter_t::open ()
// Disable Nagle's algorithm.
int flag = 1;
rc = setsockopt (s, IPPROTO_TCP, TCP_NODELAY, (char*) &flag, sizeof (int));
rc = setsockopt (s, IPPROTO_TCP, TCP_NODELAY, (char*) &flag,
sizeof (int));
errno_assert (rc == 0);
#ifdef ZMQ_HAVE_OPENVMS
// Disable delayed acknowledgements.
flag = 1;
rc = setsockopt (s, IPPROTO_TCP, TCP_NODELACK, (char*) &flag, sizeof (int));
rc = setsockopt (s, IPPROTO_TCP, TCP_NODELACK, (char*) &flag,
sizeof (int));
errno_assert (rc != SOCKET_ERROR);
#endif
// Connect to the remote peer.
rc = ::connect (s, (struct sockaddr*) &addr, sizeof (addr));
rc = ::connect (s, (struct sockaddr*) &addr, addr_len);
// Connect was successfull immediately.
if (rc == 0)
......
......@@ -59,6 +59,7 @@ namespace zmq
// Address to connect to.
sockaddr_storage addr;
socklen_t addr_len;
// Underlying socket.
fd_t s;
......
......@@ -33,6 +33,7 @@ zmq::tcp_listener_t::tcp_listener_t () :
s (retired_fd)
{
memset (&addr, 0, sizeof (addr));
addr_len = 0;
}
zmq::tcp_listener_t::~tcp_listener_t ()
......@@ -50,7 +51,7 @@ int zmq::tcp_listener_t::set_address (const char *protocol_, const char *addr_)
}
// Convert the interface into sockaddr_in structure.
int rc = resolve_ip_interface (&addr, addr_);
int rc = resolve_ip_interface (&addr, &addr_len, addr_);
if (rc != 0)
return rc;
......@@ -73,7 +74,7 @@ int zmq::tcp_listener_t::set_address (const char *protocol_, const char *addr_)
wsa_assert (rc != SOCKET_ERROR);
// Bind the socket to the network interface and port.
rc = bind (s, (struct sockaddr*) &addr, sizeof (addr));
rc = bind (s, (struct sockaddr*) &addr, addr_len);
if (rc == SOCKET_ERROR) {
wsa_error_to_errno ();
return -1;
......@@ -158,7 +159,7 @@ int zmq::tcp_listener_t::set_address (const char *protocol_, const char *addr_)
if (strcmp (protocol_, "tcp") == 0 ) {
// Resolve the sockaddr to bind to.
int rc = resolve_ip_interface (&addr, addr_);
int rc = resolve_ip_interface (&addr, &addr_len, addr_);
if (rc != 0)
return -1;
......@@ -180,7 +181,7 @@ int zmq::tcp_listener_t::set_address (const char *protocol_, const char *addr_)
errno_assert (rc != -1);
// Bind the socket to the network interface and port.
rc = bind (s, (struct sockaddr*) &addr, sizeof (addr));
rc = bind (s, (struct sockaddr*) &addr, addr_len);
if (rc != 0) {
close ();
return -1;
......@@ -202,7 +203,7 @@ int zmq::tcp_listener_t::set_address (const char *protocol_, const char *addr_)
::unlink (addr_);
// Convert the address into sockaddr_un structure.
int rc = resolve_local_path ((struct sockaddr_un*) &addr, addr_);
int rc = resolve_local_path (&addr, &addr_len, addr_);
if (rc != 0)
return -1;
......
......@@ -54,6 +54,7 @@ namespace zmq
// Address to listen on.
sockaddr_storage addr;
socklen_t addr_len;
// Underlying socket.
fd_t s;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment