diff options
author | Martin Sustrik <sustrik@250bpm.com> | 2012-04-24 11:25:26 +0200 |
---|---|---|
committer | Martin Sustrik <sustrik@250bpm.com> | 2012-04-25 17:08:06 +0200 |
commit | d2347c9fdda8d21ede3f91ae8a4873ac04b498aa (patch) | |
tree | 8902345479a512c8e6b00847b7a8ec2da7770254 /src | |
parent | 94a38c72a7c8803d0947ac86a425152a8b1895ba (diff) |
tcp_address_t and ipc_address_t merged into a single class
This patch is a preliminary work for mergine TCP and IPC connecters
and listeners. The ultimated goal is to avoid code duplication
occuring in these classes.
Signed-off-by: Martin Sustrik <sustrik@250bpm.com>
Diffstat (limited to 'src')
-rw-r--r-- | src/Makefile.am | 6 | ||||
-rw-r--r-- | src/address.cpp (renamed from src/tcp_address.cpp) | 114 | ||||
-rw-r--r-- | src/address.hpp | 60 | ||||
-rw-r--r-- | src/ipc_address.cpp | 60 | ||||
-rw-r--r-- | src/ipc_address.hpp | 62 | ||||
-rw-r--r-- | src/ipc_connecter.cpp | 4 | ||||
-rw-r--r-- | src/ipc_connecter.hpp | 4 | ||||
-rw-r--r-- | src/ipc_listener.cpp | 8 | ||||
-rw-r--r-- | src/tcp_address.hpp | 78 | ||||
-rw-r--r-- | src/tcp_connecter.cpp | 22 | ||||
-rw-r--r-- | src/tcp_connecter.hpp | 6 | ||||
-rw-r--r-- | src/tcp_listener.cpp | 15 | ||||
-rw-r--r-- | src/tcp_listener.hpp | 4 |
13 files changed, 159 insertions, 284 deletions
diff --git a/src/Makefile.am b/src/Makefile.am index 03b6381..033ba52 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -16,6 +16,7 @@ include_HEADERS = ../include/xs.h endif libxs_la_SOURCES = \ + address.hpp \ array.hpp \ atomic_counter.hpp \ atomic_ptr.hpp \ @@ -36,7 +37,6 @@ libxs_la_SOURCES = \ io_object.hpp \ io_thread.hpp \ ip.hpp \ - ipc_address.hpp \ ipc_connecter.hpp \ ipc_listener.hpp \ i_engine.hpp \ @@ -74,7 +74,6 @@ libxs_la_SOURCES = \ stream_engine.hpp \ sub.hpp \ surveyor.hpp \ - tcp_address.hpp \ tcp_connecter.hpp \ tcp_listener.hpp \ thread.hpp \ @@ -89,6 +88,7 @@ libxs_la_SOURCES = \ xsurveyor.hpp \ ypipe.hpp \ yqueue.hpp \ + address.cpp \ clock.cpp \ core.cpp \ ctx.cpp \ @@ -102,7 +102,6 @@ libxs_la_SOURCES = \ io_object.cpp \ io_thread.cpp \ ip.cpp \ - ipc_address.cpp \ ipc_connecter.cpp \ ipc_listener.cpp \ kqueue.cpp \ @@ -134,7 +133,6 @@ libxs_la_SOURCES = \ stream_engine.cpp \ sub.cpp \ surveyor.cpp \ - tcp_address.cpp \ tcp_connecter.cpp \ tcp_listener.cpp \ thread.cpp \ diff --git a/src/tcp_address.cpp b/src/address.cpp index 9132c37..8fb40f0 100644 --- a/src/tcp_address.cpp +++ b/src/address.cpp @@ -22,7 +22,7 @@ #include <string.h> #include <string> -#include "tcp_address.hpp" +#include "address.hpp" #include "platform.hpp" #include "stdint.hpp" #include "err.hpp" @@ -52,7 +52,8 @@ #include <stdlib.h> // On Solaris platform, network interface name can be queried by ioctl. -int xs::tcp_address_t::resolve_nic_name (const char *nic_, bool ipv4only_) +static int resolve_nic_name (xs::address_t *self_, const char *nic_, + bool ipv4only_) { // TODO: Unused parameter, IPv6 support not implemented for Solaris. (void) ipv4only_; @@ -72,7 +73,7 @@ int xs::tcp_address_t::resolve_nic_name (const char *nic_, bool ipv4only_) size_t ifr_size = sizeof (struct lifreq) * ifn.lifn_count; char *ifr = (char*) malloc (ifr_size); alloc_assert (ifr); - + // Retrieve interface names. lifconf ifc; ifc.lifc_family = AF_INET; @@ -91,7 +92,7 @@ int xs::tcp_address_t::resolve_nic_name (const char *nic_, bool ipv4only_) rc = ioctl (fd, SIOCGLIFADDR, (char*) ifrp); xs_assert (rc != -1); if (ifrp->lifr_addr.ss_family == AF_INET) { - address.ipv4 = *(sockaddr_in*) &ifrp->lifr_addr; + *(sockaddr_in*) self_ = *(sockaddr_in*) &ifrp->lifr_addr; found = true; break; } @@ -117,7 +118,8 @@ int xs::tcp_address_t::resolve_nic_name (const char *nic_, bool ipv4only_) #include <sys/ioctl.h> #include <net/if.h> -int xs::tcp_address_t::resolve_nic_name (const char *nic_, bool ipv4only_) +static int resolve_nic_name (xs::address_t *self_, const char *nic_, + bool ipv4only_) { // TODO: Unused parameter, IPv6 support not implemented for AIX or HP/UX. (void) ipv4only_; @@ -126,7 +128,7 @@ int xs::tcp_address_t::resolve_nic_name (const char *nic_, bool ipv4only_) int sd = open_socket (AF_INET, SOCK_DGRAM, 0); xs_assert (sd != -1); - struct ifreq ifr; + struct ifreq ifr; // Copy interface name for ioctl get. strncpy (ifr.ifr_name, nic_, sizeof (ifr.ifr_name)); @@ -142,10 +144,9 @@ int xs::tcp_address_t::resolve_nic_name (const char *nic_, bool ipv4only_) return -1; } - memcpy (&address.ipv4.sin_addr, &((sockaddr_in*) &ifr.ifr_addr)->sin_addr, - sizeof (in_addr)); + ((sockaddr_in*) self_)->sin_addr = ((sockaddr_in*) &ifr.ifr_addr)->sin_addr; - return 0; + return 0; } #elif ((defined XS_HAVE_LINUX || defined XS_HAVE_FREEBSD ||\ @@ -157,12 +158,13 @@ int xs::tcp_address_t::resolve_nic_name (const char *nic_, bool ipv4only_) // On these platforms, network interface name can be queried // using getifaddrs function. -int xs::tcp_address_t::resolve_nic_name (const char *nic_, bool ipv4only_) +static int resolve_nic_name (xs::address_t *self_, const char *nic_, + bool ipv4only_) { // Get the addresses. ifaddrs* ifa = NULL; int rc = getifaddrs (&ifa); - errno_assert (rc == 0); + errno_assert (rc == 0); xs_assert (ifa != NULL); // Find the corresponding network interface. @@ -178,7 +180,7 @@ int xs::tcp_address_t::resolve_nic_name (const char *nic_, bool ipv4only_) || (!ipv4only_ && family == AF_INET6)) && !strcmp (nic_, ifp->ifa_name)) { - memcpy (&address, ifp->ifa_addr, + memcpy (self_, ifp->ifa_addr, (family == AF_INET) ? sizeof (struct sockaddr_in) : sizeof (struct sockaddr_in6)); found = true; @@ -201,7 +203,8 @@ int xs::tcp_address_t::resolve_nic_name (const char *nic_, bool ipv4only_) // On other platforms we assume there are no sane interface names. // This is true especially of Windows. -int xs::tcp_address_t::resolve_nic_name (const char *nic_, bool ipv4only_) +static int resolve_nic_name (xs::address_t *self_, const char *nic_, + bool ipv4only_) { // All unused parameters. (void) nic_; @@ -213,7 +216,7 @@ int xs::tcp_address_t::resolve_nic_name (const char *nic_, bool ipv4only_) #endif -int xs::tcp_address_t::resolve_interface (char const *interface_, +static int resolve_interface (xs::address_t *self_, char const *interface_, bool ipv4only_) { // Initialize temporary output pointers with storage address. @@ -241,13 +244,13 @@ int xs::tcp_address_t::resolve_interface (char const *interface_, // * resolves to INADDR_ANY or in6addr_any. if (strcmp (interface_, "*") == 0) { - xs_assert (out_addrlen <= (socklen_t) sizeof (address)); - memcpy (&address, out_addr, out_addrlen); + xs_assert (out_addrlen <= (socklen_t) sizeof (xs::address_t)); + memcpy (self_, out_addr, out_addrlen); return 0; } // Try to resolve the string as a NIC name. - int rc = resolve_nic_name (interface_, ipv4only_); + int rc = resolve_nic_name (self_, interface_, ipv4only_); if (rc != 0 && errno != ENODEV) return rc; if (rc == 0) @@ -293,8 +296,8 @@ int xs::tcp_address_t::resolve_interface (char const *interface_, } // Use the first result. - xs_assert ((size_t) (res->ai_addrlen) <= sizeof (address)); - memcpy (&address, res->ai_addr, res->ai_addrlen); + xs_assert ((size_t) (res->ai_addrlen) <= sizeof (xs::address_t)); + memcpy (self_, res->ai_addr, res->ai_addrlen); // Cleanup getaddrinfo after copying the possibly referenced result. if (res) @@ -303,7 +306,8 @@ int xs::tcp_address_t::resolve_interface (char const *interface_, return 0; } -int xs::tcp_address_t::resolve_hostname (const char *hostname_, bool ipv4only_) +static int resolve_hostname (xs::address_t *self_, const char *hostname_, + bool ipv4only_) { // Set up the query. #if defined XS_HAVE_OPENVMS && defined __ia64 && __INITIAL_POINTER_SIZE == 64 @@ -351,26 +355,19 @@ int xs::tcp_address_t::resolve_hostname (const char *hostname_, bool ipv4only_) } // Copy first result to output addr with hostname and service. - xs_assert ((size_t) (res->ai_addrlen) <= sizeof (address)); - memcpy (&address, res->ai_addr, res->ai_addrlen); - + xs_assert ((size_t) (res->ai_addrlen) <= sizeof (xs::address_t)); + memcpy (self_, res->ai_addr, res->ai_addrlen); + freeaddrinfo (res); return 0; } -xs::tcp_address_t::tcp_address_t () +int xs::address_resolve_tcp (address_t *self_, const char *name_, bool local_, + bool ipv4only_, bool ignore_port_) { - memset (&address, 0, sizeof (address)); -} + memset (self_, 0, sizeof (address_t)); -xs::tcp_address_t::~tcp_address_t () -{ -} - -int xs::tcp_address_t::resolve (const char *name_, bool local_, bool ipv4only_, - bool ignore_port_) -{ // Find the ':' at end that separates address from the port number. const char *delimiter = strrchr (name_, ':'); std::string addr_str; @@ -403,40 +400,51 @@ int xs::tcp_address_t::resolve (const char *name_, bool local_, bool ipv4only_, // Resolve the IP address. int rc; if (local_) - rc = resolve_interface (addr_str.c_str (), ipv4only_); + rc = resolve_interface (self_, addr_str.c_str (), ipv4only_); else - rc = resolve_hostname (addr_str.c_str (), ipv4only_); + rc = resolve_hostname (self_, addr_str.c_str (), ipv4only_); if (rc != 0) return -1; // Set the port into the address structure. - if (address.generic.sa_family == AF_INET6) - address.ipv6.sin6_port = htons (port); + if (self_->ss_family == AF_INET6) + ((struct sockaddr_in6*) self_)->sin6_port = htons (port); else - address.ipv4.sin_port = htons (port); + ((struct sockaddr_in* ) self_)->sin_port = htons (port); return 0; } -sockaddr *xs::tcp_address_t::addr () -{ - return &address.generic; -} -socklen_t xs::tcp_address_t::addrlen () +int xs::address_resolve_ipc (address_t *self_, const char *name_) { - if (address.generic.sa_family == AF_INET6) - return (socklen_t) sizeof (address.ipv6); - else - return (socklen_t) sizeof (address.ipv4); -} - -#if defined XS_HAVE_WINDOWS -unsigned short xs::tcp_address_t::family () +#if defined XS_HAVE_WINDOWS || defined XS_HAVE_OPENVMS + errno = ENOTSUP; + return -1; #else -sa_family_t xs::tcp_address_t::family () + memset (self_, 0, sizeof (address_t)); + struct sockaddr_un *un = (struct sockaddr_un*) self_; + if (strlen (name_) >= sizeof (un->sun_path)) { + errno = ENAMETOOLONG; + return -1; + } + self_->ss_family = AF_UNIX; + strncpy (un->sun_path, name_, sizeof (un->sun_path)); + return 0; #endif +} + +socklen_t xs::address_size (address_t *self_) { - return address.generic.sa_family; +#if !defined XS_HAVE_WINDOWS && !defined XS_HAVE_OPENVMS + if (self_->ss_family == AF_UNIX) + return (socklen_t) sizeof (struct sockaddr_un); +#endif + if (self_->ss_family == AF_INET6) + return (socklen_t) sizeof (struct sockaddr_in6); + if (self_->ss_family == AF_INET) + return (socklen_t) sizeof (struct sockaddr_in); + xs_assert (false); + return 0; } diff --git a/src/address.hpp b/src/address.hpp new file mode 100644 index 0000000..2d86a02 --- /dev/null +++ b/src/address.hpp @@ -0,0 +1,60 @@ +/* + Copyright (c) 2009-2012 250bpm s.r.o. + Copyright (c) 2007-2009 iMatix Corporation + Copyright (c) 2007-2011 Other contributors as noted in the AUTHORS file + + This file is part of Crossroads I/O project. + + Crossroads I/O 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. + + Crossroads 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 __XS_ADDRESS_HPP_INCLUDED__ +#define __XS_ADDRESS_HPP_INCLUDED__ + +#include "platform.hpp" + +#if defined XS_HAVE_WINDOWS +#include "windows.hpp" +#else +#include <sys/socket.h> +#include <sys/types.h> +#include <netinet/in.h> +#endif + +#if !defined XS_HAVE_WINDOWS && !defined XS_HAVE_OPENVMS +#include <sys/un.h> +#endif + +namespace xs +{ + + typedef struct sockaddr_storage address_t; + + // This function translates textual TCP address into an address + // strcuture. If 'local' is true, names are resolved as local interface + // names. If it is false, names are resolved as remote hostnames. + // If 'ipv4only' is true, the name will never resolve to IPv6 address. + int address_resolve_tcp (address_t *self_, const char *name_, bool local_, + bool ipv4only_, bool ignore_port_=false); + + // Resolves IPC (UNIX domain socket) address. + int address_resolve_ipc (address_t *self_, const char *name_); + + // Returns actual size of the address. + socklen_t address_size (address_t *self_); + +} + +#endif + diff --git a/src/ipc_address.cpp b/src/ipc_address.cpp deleted file mode 100644 index faea5db..0000000 --- a/src/ipc_address.cpp +++ /dev/null @@ -1,60 +0,0 @@ -/* - Copyright (c) 2012 250bpm s.r.o. - Copyright (c) 2011 Other contributors as noted in the AUTHORS file - - This file is part of Crossroads I/O project. - - Crossroads I/O 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. - - Crossroads 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 "ipc_address.hpp" - -#if !defined XS_HAVE_WINDOWS && !defined XS_HAVE_OPENVMS - -#include "err.hpp" - -#include <string.h> - -xs::ipc_address_t::ipc_address_t () -{ - memset (&address, 0, sizeof (address)); -} - -xs::ipc_address_t::~ipc_address_t () -{ -} - -int xs::ipc_address_t::resolve (const char *path_) -{ - if (strlen (path_) >= sizeof (address.sun_path)) { - errno = ENAMETOOLONG; - return -1; - } - - address.sun_family = AF_UNIX; - strncpy (address.sun_path, path_, sizeof (address.sun_path)); - return 0; -} - -sockaddr *xs::ipc_address_t::addr () -{ - return (sockaddr*) &address; -} - -socklen_t xs::ipc_address_t::addrlen () -{ - return (socklen_t) sizeof (address); -} - -#endif diff --git a/src/ipc_address.hpp b/src/ipc_address.hpp deleted file mode 100644 index 09b6eff..0000000 --- a/src/ipc_address.hpp +++ /dev/null @@ -1,62 +0,0 @@ -/* - Copyright (c) 2011-2012 250bpm s.r.o. - Copyright (c) 2011 Other contributors as noted in the AUTHORS file - - This file is part of Crossroads I/O project. - - Crossroads I/O 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. - - Crossroads 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 __XS_IPC_ADDRESS_HPP_INCLUDED__ -#define __XS_IPC_ADDRESS_HPP_INCLUDED__ - -#include "platform.hpp" - -#if !defined XS_HAVE_WINDOWS && !defined XS_HAVE_OPENVMS - -#include <sys/types.h> -#include <sys/socket.h> -#include <sys/un.h> - -namespace xs -{ - - class ipc_address_t - { - public: - - ipc_address_t (); - ~ipc_address_t (); - - // This function sets up the address for UNIX domain transport. - int resolve (const char* path_); - - sockaddr *addr (); - socklen_t addrlen (); - - private: - - struct sockaddr_un address; - - ipc_address_t (const ipc_address_t&); - const ipc_address_t &operator = (const ipc_address_t&); - }; - -} - -#endif - -#endif - - diff --git a/src/ipc_connecter.cpp b/src/ipc_connecter.cpp index ab2d872..ec9c5b1 100644 --- a/src/ipc_connecter.cpp +++ b/src/ipc_connecter.cpp @@ -174,7 +174,7 @@ int xs::ipc_connecter_t::get_new_reconnect_ivl () int xs::ipc_connecter_t::set_address (const char *addr_) { - return address.resolve (addr_); + return address_resolve_ipc (&address, addr_); } int xs::ipc_connecter_t::open () @@ -190,7 +190,7 @@ int xs::ipc_connecter_t::open () unblock_socket (s); // Connect to the remote peer. - int rc = ::connect (s, address.addr (), address.addrlen ()); + int rc = ::connect (s, (const sockaddr*) &address, address_size (&address)); // Connect was successfull immediately. if (rc == 0) diff --git a/src/ipc_connecter.hpp b/src/ipc_connecter.hpp index 84c50fa..2a874bc 100644 --- a/src/ipc_connecter.hpp +++ b/src/ipc_connecter.hpp @@ -29,7 +29,7 @@ #include "own.hpp" #include "stdint.hpp" #include "io_object.hpp" -#include "ipc_address.hpp" +#include "address.hpp" namespace xs { @@ -88,7 +88,7 @@ namespace xs fd_t connect (); // Address to connect to. - ipc_address_t address; + address_t address; // Underlying socket. fd_t s; diff --git a/src/ipc_listener.cpp b/src/ipc_listener.cpp index 43f75c1..286c531 100644 --- a/src/ipc_listener.cpp +++ b/src/ipc_listener.cpp @@ -27,7 +27,7 @@ #include <string.h> #include "stream_engine.hpp" -#include "ipc_address.hpp" +#include "address.hpp" #include "io_thread.hpp" #include "session_base.hpp" #include "config.hpp" @@ -103,8 +103,8 @@ int xs::ipc_listener_t::set_address (const char *addr_) filename.clear (); // Initialise the address structure. - ipc_address_t address; - int rc = address.resolve (addr_); + address_t address; + int rc = address_resolve_ipc (&address, addr_); if (rc != 0) return -1; @@ -114,7 +114,7 @@ int xs::ipc_listener_t::set_address (const char *addr_) return -1; // Bind the socket to the file path. - rc = bind (s, address.addr (), address.addrlen ()); + rc = bind (s, (const sockaddr*) &address, address_size (&address)); if (rc != 0) return -1; diff --git a/src/tcp_address.hpp b/src/tcp_address.hpp deleted file mode 100644 index 0a12ff3..0000000 --- a/src/tcp_address.hpp +++ /dev/null @@ -1,78 +0,0 @@ -/* - Copyright (c) 2009-2012 250bpm s.r.o. - Copyright (c) 2007-2009 iMatix Corporation - Copyright (c) 2007-2011 Other contributors as noted in the AUTHORS file - - This file is part of Crossroads I/O project. - - Crossroads I/O 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. - - Crossroads 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 __XS_TCP_ADDRESS_HPP_INCLUDED__ -#define __XS_TCP_ADDRESS_HPP_INCLUDED__ - -#include "platform.hpp" - -#if defined XS_HAVE_WINDOWS -#include "windows.hpp" -#else -#include <sys/socket.h> -#include <netinet/in.h> -#endif - -namespace xs -{ - - class tcp_address_t - { - public: - - tcp_address_t (); - ~tcp_address_t (); - - // This function translates textual TCP address into an address - // strcuture. If 'local' is true, names are resolved as local interface - // names. If it is false, names are resolved as remote hostnames. - // If 'ipv4only' is true, the name will never resolve to IPv6 address. - int resolve (const char* name_, bool local_, bool ipv4only_, - bool ignore_port_=false); - -#if defined XS_HAVE_WINDOWS - unsigned short family (); -#else - sa_family_t family (); -#endif - sockaddr *addr (); - socklen_t addrlen (); - - private: - - int resolve_nic_name (const char *nic_, bool ipv4only_); - int resolve_interface (const char *interface_, bool ipv4only_); - int resolve_hostname (const char *hostname_, bool ipv4only_); - - union { - sockaddr generic; - sockaddr_in ipv4; - sockaddr_in6 ipv6; - } address; - - tcp_address_t (const tcp_address_t&); - const tcp_address_t &operator = (const tcp_address_t&); - }; - -} - -#endif - diff --git a/src/tcp_connecter.cpp b/src/tcp_connecter.cpp index 2fbbff6..d1c04db 100644 --- a/src/tcp_connecter.cpp +++ b/src/tcp_connecter.cpp @@ -181,6 +181,8 @@ int xs::tcp_connecter_t::get_new_reconnect_ivl () int xs::tcp_connecter_t::set_address (const char *addr_) { + memset (&source_address, 0, sizeof (source_address)); + // Find the ';'. It separates source address address from a destination. const char *delimiter = strchr (addr_, ';'); @@ -188,7 +190,7 @@ int xs::tcp_connecter_t::set_address (const char *addr_) if (delimiter) { std::string saddr_str (addr_, delimiter - addr_); addr_str = delimiter + 1; - int rc = source_address.resolve (saddr_str.c_str(), true, + int rc = address_resolve_tcp (&source_address, saddr_str.c_str(), true, options.ipv4only ? true : false, true); if (rc != 0) return -1; @@ -196,33 +198,39 @@ int xs::tcp_connecter_t::set_address (const char *addr_) else addr_str = addr_; - return address.resolve (addr_str.c_str(), false, + return address_resolve_tcp (&address, addr_str.c_str(), false, options.ipv4only ? true : false); } int xs::tcp_connecter_t::open () { + int rc; + xs_assert (s == retired_fd); // Create the socket. - s = open_tcp_socket (address.family (), options.keepalive ? true : false); + s = open_tcp_socket (address.ss_family, options.keepalive ? true : false); if (s == -1) return -1; // On some systems, IPv4 mapping in IPv6 sockets is disabled by default. // Switch it on in such cases. - if (address.family () == AF_INET6) + if (address.ss_family == AF_INET6) enable_ipv4_mapping (s); // Set the socket to non-blocking mode so that we get async connect(). unblock_socket (s); // Set a source address for conversations. - if (source_address.family ()) - ::bind (s, source_address.addr (), source_address.addrlen ()); + if (source_address.ss_family) { + rc = ::bind (s, (const sockaddr*) &source_address, + address_size (&source_address)); + if (rc != 0) + return -1; + } // Connect to the remote peer. - int rc = ::connect (s, address.addr (), address.addrlen ()); + rc = ::connect (s, (const sockaddr*) &address, address_size (&address)); // Connect was successfull immediately. if (rc == 0) diff --git a/src/tcp_connecter.hpp b/src/tcp_connecter.hpp index 87b4604..26a0151 100644 --- a/src/tcp_connecter.hpp +++ b/src/tcp_connecter.hpp @@ -26,7 +26,7 @@ #include "own.hpp" #include "stdint.hpp" #include "io_object.hpp" -#include "tcp_address.hpp" +#include "address.hpp" namespace xs { @@ -82,10 +82,10 @@ namespace xs fd_t connect (); // Address to connect to. - tcp_address_t address; + address_t address; // Source address. - tcp_address_t source_address; + address_t source_address; // Underlying socket. fd_t s; diff --git a/src/tcp_listener.cpp b/src/tcp_listener.cpp index 22797e2..ccae1ae 100644 --- a/src/tcp_listener.cpp +++ b/src/tcp_listener.cpp @@ -119,20 +119,21 @@ void xs::tcp_listener_t::close () int xs::tcp_listener_t::set_address (const char *addr_) { // Convert the textual address into address structure. - int rc = address.resolve (addr_, true, options.ipv4only ? true : false); + int rc = address_resolve_tcp (&address, addr_, true, + options.ipv4only ? true : false); if (rc != 0) return -1; // Create a listening socket. - s = open_tcp_socket (address.family (), false); + s = open_tcp_socket (address.ss_family, false); // IPv6 address family not supported, try automatic downgrade to IPv4. - if (address.family () == AF_INET6 && errno == EAFNOSUPPORT && + if (address.ss_family == AF_INET6 && errno == EAFNOSUPPORT && !options.ipv4only) { - rc = address.resolve (addr_, true, true); + rc = address_resolve_tcp (&address, addr_, true, true); if (rc != 0) return rc; - s = open_tcp_socket (address.family (), false); + s = open_tcp_socket (address.ss_family, false); } if (s == retired_fd) @@ -140,7 +141,7 @@ int xs::tcp_listener_t::set_address (const char *addr_) // On some systems, IPv4 mapping in IPv6 sockets is disabled by default. // Switch it on in such cases. - if (address.family () == AF_INET6) + if (address.ss_family == AF_INET6) enable_ipv4_mapping (s); // Allow reusing of the address. @@ -155,7 +156,7 @@ int xs::tcp_listener_t::set_address (const char *addr_) #endif // Bind the socket to the network interface and port. - rc = bind (s, address.addr (), address.addrlen ()); + rc = bind (s, (const sockaddr*) &address, address_size (&address)); #ifdef XS_HAVE_WINDOWS if (rc == SOCKET_ERROR) { wsa_error_to_errno (); diff --git a/src/tcp_listener.hpp b/src/tcp_listener.hpp index 4ac6657..a5023ee 100644 --- a/src/tcp_listener.hpp +++ b/src/tcp_listener.hpp @@ -26,7 +26,7 @@ #include "own.hpp" #include "stdint.hpp" #include "io_object.hpp" -#include "tcp_address.hpp" +#include "address.hpp" namespace xs { @@ -63,7 +63,7 @@ namespace xs fd_t accept (); // Address to listen on. - tcp_address_t address; + address_t address; // True, if the undelying file for UNIX domain socket exists. bool has_file; |