From 2634934999408124837afceaf577b75ed58116d7 Mon Sep 17 00:00:00 2001 From: Martin Sustrik Date: Sat, 23 Jan 2010 08:19:30 +0100 Subject: IPv6 patch part 2/2 --- src/ip.cpp | 26 +++++++++++++++++++------- src/ip.hpp | 11 +++++++---- src/tcp_connecter.cpp | 17 ++++++++++------- src/tcp_connecter.hpp | 1 + src/tcp_listener.cpp | 11 ++++++----- src/tcp_listener.hpp | 1 + 6 files changed, 44 insertions(+), 23 deletions(-) (limited to 'src') diff --git a/src/ip.cpp b/src/ip.cpp index 1520f87..7ee8641 100644 --- a/src/ip.cpp +++ b/src/ip.cpp @@ -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; } diff --git a/src/ip.hpp b/src/ip.hpp index 0144546..9d9f5c0 100644 --- a/src/ip.hpp +++ b/src/ip.hpp @@ -41,15 +41,18 @@ namespace zmq // Resolves network interface name in : 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 : 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 } diff --git a/src/tcp_connecter.cpp b/src/tcp_connecter.cpp index 436da88..ebd9b9d 100644 --- a/src/tcp_connecter.cpp +++ b/src/tcp_connecter.cpp @@ -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) diff --git a/src/tcp_connecter.hpp b/src/tcp_connecter.hpp index 23a6e9c..eee13ef 100644 --- a/src/tcp_connecter.hpp +++ b/src/tcp_connecter.hpp @@ -59,6 +59,7 @@ namespace zmq // Address to connect to. sockaddr_storage addr; + socklen_t addr_len; // Underlying socket. fd_t s; diff --git a/src/tcp_listener.cpp b/src/tcp_listener.cpp index c26201c..3d15abe 100644 --- a/src/tcp_listener.cpp +++ b/src/tcp_listener.cpp @@ -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; diff --git a/src/tcp_listener.hpp b/src/tcp_listener.hpp index 87748d0..3b60719 100644 --- a/src/tcp_listener.hpp +++ b/src/tcp_listener.hpp @@ -54,6 +54,7 @@ namespace zmq // Address to listen on. sockaddr_storage addr; + socklen_t addr_len; // Underlying socket. fd_t s; -- cgit v1.2.3