summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMartin Sustrik <sustrik@250bpm.com>2012-04-24 11:25:26 +0200
committerMartin Sustrik <sustrik@250bpm.com>2012-04-25 17:08:06 +0200
commitd2347c9fdda8d21ede3f91ae8a4873ac04b498aa (patch)
tree8902345479a512c8e6b00847b7a8ec2da7770254 /src
parent94a38c72a7c8803d0947ac86a425152a8b1895ba (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.am6
-rw-r--r--src/address.cpp (renamed from src/tcp_address.cpp)114
-rw-r--r--src/address.hpp60
-rw-r--r--src/ipc_address.cpp60
-rw-r--r--src/ipc_address.hpp62
-rw-r--r--src/ipc_connecter.cpp4
-rw-r--r--src/ipc_connecter.hpp4
-rw-r--r--src/ipc_listener.cpp8
-rw-r--r--src/tcp_address.hpp78
-rw-r--r--src/tcp_connecter.cpp22
-rw-r--r--src/tcp_connecter.hpp6
-rw-r--r--src/tcp_listener.cpp15
-rw-r--r--src/tcp_listener.hpp4
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;