Date: Thursday, December 21, 2006 @ 23:23:17
  Author: gilles
    Path: /cvsroot/carob/carob

Modified: GNUmakefile (1.4 -> 1.5) include/ControllerInfo.hpp (1.4 -> 1.5)
          include/JavaSocket.hpp (1.37 -> 1.38) include/SocketAddress.hpp
          (1.2 -> 1.3) include/WatchedControllers.hpp (1.3 -> 1.4)
          src/ControllerInfo.cpp (1.10 -> 1.11)
          src/ControllerPingSender.cpp (1.4 -> 1.5) src/ControllerPool.cpp
          (1.17 -> 1.18) src/ControllerWatcher.cpp (1.8 -> 1.9)
          src/JavaSocket.cpp (1.64 -> 1.65) src/SocketAddress.cpp (1.3 ->
          1.4) src/WatchedControllers.cpp (1.4 -> 1.5)

Fixed CAROB-61: Controllers are now identified and indexed by a unique sockaddr,
determined in ControllerInfo constructor once for all.

Also helpful for CAROB-117


--------------------------------+
 GNUmakefile                    |    1 
 include/ControllerInfo.hpp     |  105 +++---------
 include/JavaSocket.hpp         |   11 -
 include/SocketAddress.hpp      |   10 -
 include/WatchedControllers.hpp |   49 +++--
 src/ControllerInfo.cpp         |  338 +++++++++++++++------------------------
 src/ControllerPingSender.cpp   |    7 
 src/ControllerPool.cpp         |    2 
 src/ControllerWatcher.cpp      |   26 +--
 src/JavaSocket.cpp             |   11 -
 src/SocketAddress.cpp          |  125 ++------------
 src/WatchedControllers.cpp     |   60 +++---
 12 files changed, 288 insertions(+), 457 deletions(-)


Index: carob/GNUmakefile
diff -u carob/GNUmakefile:1.4 carob/GNUmakefile:1.5
--- carob/GNUmakefile:1.4       Tue Dec 19 18:42:35 2006
+++ carob/GNUmakefile   Thu Dec 21 23:23:17 2006
@@ -41,6 +41,7 @@
                           ${SRCDIR}/JavaSocket.o\
                           ${SRCDIR}/DriverSocket.o\
                           ${SRCDIR}/CarobException.o\
+                          ${SRCDIR}/SocketAddress.o\
                           ${SRCDIR}/ControllerInfo.o\
                           ${SRCDIR}/ConnectionParameters.o\
                           ${SRCDIR}/ControllerPool.o\
Index: carob/include/ControllerInfo.hpp
diff -u carob/include/ControllerInfo.hpp:1.4 
carob/include/ControllerInfo.hpp:1.5
--- carob/include/ControllerInfo.hpp:1.4        Mon Dec 18 17:14:04 2006
+++ carob/include/ControllerInfo.hpp    Thu Dec 21 23:23:17 2006
@@ -21,15 +21,16 @@
 #ifndef CONTROLLER_INFO_HPP_
 #define CONTROLLER_INFO_HPP_
 
+#include "SocketAddress.hpp"
 #include "CarobException.hpp"
 
 #ifdef __MINGW32__
-  #include <winsock2.h>
+// NEEDED ?  #include <winsock2.h>
   #include <ws2tcpip.h>
   #include "Common.hpp" //for in_port_t
 #else
-  #include <sys/socket.h> // sockaddr
-  #include <netinet/in.h> // in_port_t
+// NEEDED ?  #include <sys/socket.h>
+  #include <netinet/in.h> // sockaddr & in_port_t
   #include <netdb.h> // for addrinfo
 #endif
 
@@ -39,35 +40,33 @@
 
 class DriverSocket;
 class AbstractControllerPool;
+
 /**
- * Identifies a controller.
- * For now a controller is identified by an host address and a port.
- * TODO: In the future, only its sockaddr should be kept (see CAROB-61)
+ * Identifies a controller.<br>
+ * This class holds the socket address to connect to and send/receive pings 
+ * to/from, plus the original hostname (for debug)
  */
 class ControllerInfo
 {
 public:
-  /** Empty constructor to set default values (host="" and port=0) */
-  ControllerInfo();
-  /**
-   * Copy contructor. Calls = operator
-   * @param ci original controller to copy from
-   * @throw ConnectionException in case of memory allocation failure 
-   */
-  ControllerInfo(const ControllerInfo& ci) throw (ConnectionException, 
UnexpectedException);
+  /** Empty contructor does nothing */
+  ControllerInfo() {};
   /**
-   * Constructs a Controller info with the given name and port
+   * Constructs a Controller info with the given name and port.<br>
+   * This constructor is the one used at init time, by the user. It will
+   * determine the socket address to connect to and to send/receive pings
+   * to/from, which will be the first one returned by getaddrinfo()
    * @param host hostname as a string. Can be either qualified name or numeric
    * @param port host port
-   * @throw ConnectionException in case of memory allocation failure 
+   * @throw ConnectionException if the given hostname cannot be resolved
    * */
   ControllerInfo(const std::wstring& host, in_port_t port) throw 
(ConnectionException, UnexpectedException);
   /**
-   * Constructs a Controller info with the given sockaddr
-   * @param addr sockaddr identifying the controller
-   * @param len addr length
+   * Copy contructor. Calls = operator
+   * @param ci original controller to copy from
+   * @throw ConnectionException in case of memory allocation failure 
    */
-  ControllerInfo(const struct sockaddr& addr, socklen_t len) throw 
(ConnectionException, UnexpectedException);
+  ControllerInfo(const ControllerInfo& ci) throw (ConnectionException, 
UnexpectedException);
   /**
    * Frees addrinfo
    */
@@ -86,32 +85,13 @@
    * @param ci controller to copy informations from
    * @throw ConnectionException in case of memory allocation failure 
    */
-  ControllerInfo&         operator =(const ControllerInfo& ci) throw 
(ConnectionException, UnexpectedException);
-  /** Comparison operator */
-  bool                    operator ==(const ControllerInfo& ci) const;
-  /**
-   * Utility lesser than operator for ControllerPoolManager
-   * For performance purposes, the comparison is done first on host_port, then
-   * on host_name
-   */
+  ControllerInfo&         operator =(const ControllerInfo& ci);
+  /** Less than operator used by ControllerPoolManager */
   bool                    operator <(const ControllerInfo& ci) const;
-  /**
-   * Utility greater than operator for ControllerPoolManager
-   * For performance purposes, the comparison is done first on host_port, then
-   * on host_name
-   */
-  bool                    operator >(const ControllerInfo& ci) const;
-  /**
-   * Gives the address family of this controller.<br>
-   * Returns the address family of the first UDP address found by getaddrinfo()
-   */
-  int                     getFamily() const;
-  /** Gives the host port */
-  in_port_t               getHostPort() const { return host_port; }
-  /** Returns the UDP socket address */
-  const struct sockaddr*  getUDPAddrPtr() const { return &UDP_addr; }
-  /** Returns the UDP socket address length */
-  socklen_t               getUDPAddrLen() const { return UDP_addr_len; }
+  /** Comparison operator. Uses < operator */
+  bool                    operator ==(const ControllerInfo& ci) const;
+  /** Returns the socket address associated to this controller */
+  const SocketAddress&    getSocketAddress() const { return socket_address; }
   /**
    * Cast to wstring operator to ease printing (for debug/traces).
    * @return sql query as a string
@@ -119,40 +99,19 @@
   operator                std::wstring () const;
 private:
   /**
-   * Retrieves the socket addresses for the controller identified by the given
-   * name.<br>
-   * Calls getaddrinfo() with a filter on given socket type (ie. UDP or TCP) 
and 
-   * family
+   * Retrieves all socket addresses for the controller identified by the given
+   * name/port.<br>
+   * Calls getaddrinfo() with a filter SOCK_STREAM filter (TCP)
    * @param name name of the controller
-   * @param socktype socket type: SOCK_STREAM (TCP) or SOCK_DGRAM (UDP)
-   * @param family address family: AF_INET (ipv4) or AF_INET6 (ipv6)
+   * @param port port on which the controller listens to
    */
-  struct addrinfo*        getAddrs(const std::wstring& name, in_port_t port, 
int socktype,  int family)
+  static addrinfo*        getAddrs(const std::wstring& name, in_port_t port)
                               throw (ConnectionException, UnexpectedException);
-  /**
-   * Call getnameinfo() on this UDP_addr to determine host address
-   */
-  void                    getHostAddressFromUDPAddr() throw 
(ConnectionException, UnexpectedException);
 
-  /** Host port */
-  in_port_t               host_port;
   /** Host name as given by the user */
   std::wstring            original_hostname;
-  /** Host address as string, retrieved from UDP socket address */
-  char                    host_address[NI_MAXHOST+1];
-  /** UDP socket address */
-  struct sockaddr         UDP_addr;
-  /** UDP socket address length */
-  socklen_t               UDP_addr_len;
-  /**
-   * whether or not this host has been connected, determines if the
-   * TCP_sock_addr is valid
-   */
-  bool                    has_been_connected;
-  /** sockaddr of the TCP socket we are connected to */
-  struct sockaddr         TCP_sock_addr;
-  /** size of the TCP socket address */
-  socklen_t               TCP_sock_addr_len;
+  /** The socket address to which pings and connection will be done */
+  SocketAddress           socket_address;
 };
 
 } //namespace CarobNS
Index: carob/include/JavaSocket.hpp
diff -u carob/include/JavaSocket.hpp:1.37 carob/include/JavaSocket.hpp:1.38
--- carob/include/JavaSocket.hpp:1.37   Mon Dec 18 17:02:51 2006
+++ carob/include/JavaSocket.hpp        Thu Dec 21 23:23:17 2006
@@ -22,6 +22,7 @@
 #ifndef SOCKET_H_
 #define SOCKET_H_
 
+#include "SocketAddress.hpp"
 #include "StringCodecs.hpp"
 #include "CarobException.hpp"
 
@@ -32,8 +33,7 @@
 #ifdef __MINGW32__
   #include <winsock2.h>
 #else
-  #include <netinet/in.h> //for in_addr_t
-  #include <netdb.h> // for addrinfo
+  #include <netinet/in.h> //for in_port_t
 #endif
 
 namespace CarobNS {
@@ -77,13 +77,12 @@
   void          create(int domain)
                     throw (ConnectionException, UnexpectedException);
   /**
-   * Connects to the given host/port
-   * @param ai address info of the host to connect to
-   * @param port port as a in_addr_t (unsigned int)
+   * Connects to the given socket address
+   * @param addr socket address of the host to connect to
    * @return true upon successfull connection, false otherwise
    * @throws ConnectionException
    */
-  bool          connectTo(struct addrinfo* ai, in_port_t port)
+  bool          connectTo(const SocketAddress& addr)
                     throw (ConnectionException, UnexpectedException);
   /** 
    * Closes connection.
Index: carob/include/SocketAddress.hpp
diff -u carob/include/SocketAddress.hpp:1.2 carob/include/SocketAddress.hpp:1.3
--- carob/include/SocketAddress.hpp:1.2 Thu Dec 21 19:56:26 2006
+++ carob/include/SocketAddress.hpp     Thu Dec 21 23:23:17 2006
@@ -35,7 +35,6 @@
 namespace CarobNS {
 
 std::wostream& operator<< (std::wostream& ostr, const sockaddr& toprint);
-std::wostream& operator<< (std::wostream& ostr, const addrinfo& toprint);
 
 /**
  * Wraps a sockaddr, its size and provides a less than operator so it can be
@@ -65,20 +64,21 @@
    * @param sa the socket address to set
    * @param l length of sa
    */
-  void            setAddress(sockaddr* sa, socklen_t l);
+  void            setAddress(const sockaddr* sa, socklen_t l);
   /** Assignement operator, calls #setAddress(sockaddr* sa, socklen_t l) */
   SocketAddress&  operator = (const SocketAddress& sa);
   /** Less than operator, so SocketAddress can be keys of stl maps */
   bool            operator < (const SocketAddress& sa) const;
   /** Returns a pointer to the socket address */
-  sockaddr*       getAddressPtr() const { return address; }
+  // This C-style cast is mandatory: reinterpret_cast brakes constness...
+  const sockaddr* getAddressPtr() const { return (sockaddr*)&address; }
   /** Returns the socket address length */
   socklen_t       getAddressLength() const { return address_length; }
   /** Gets the address family of this socket */
-  sa_family_t     getFamily() const;
+  sa_family_t     getFamily() const { return address.ss_family; }
 private:
   /** Pointer to the sockaddr struct */
-  sockaddr*       address;
+  sockaddr_storage address;
   /** Size of the sockaddr struct */
   socklen_t       address_length;
 };
Index: carob/include/WatchedControllers.hpp
diff -u carob/include/WatchedControllers.hpp:1.3 
carob/include/WatchedControllers.hpp:1.4
--- carob/include/WatchedControllers.hpp:1.3    Tue Dec  5 16:18:40 2006
+++ carob/include/WatchedControllers.hpp        Thu Dec 21 23:23:17 2006
@@ -22,7 +22,8 @@
 #ifndef WATCHED_CONTROLLERS_H_
 #define WATCHED_CONTROLLERS_H_
 
-#include "ConnectionParameters.hpp"
+#include "SocketAddress.hpp"
+#include "ControllerInfo.hpp"
 #include "CriticalSection.hpp"
 
 #include <map>
@@ -44,30 +45,33 @@
 class WatchedControllers
 {
   /**
-   * Holds a controller lastTimeSeen variable and state (up or down)
+   * Holds a controller, its lastTimeSeen variable and its state (up or down)
    */
-  class ControllerState
+  class ControllerAndState
   {
   public:
-    ControllerState();
-    ControllerState(long initTime);
-    ControllerState(const ControllerState& src);
+    ControllerAndState();
+    ControllerAndState(const ControllerInfo& ctrl);
+    ControllerAndState(const ControllerInfo& ctrl, long initTime);
+    ControllerAndState(const ControllerAndState& src);
 
-    ControllerState&  operator = (const ControllerState& src);
+    ControllerAndState&   operator = (const ControllerAndState& src);
 
-    void              updateTime(long newTime) { last_time_seen = newTime; }
+    void                  updateTime(long newTime) { last_time_seen = newTime; 
}
 
-    bool              isUp() const { return responds_to_pings; }
+    bool                  isUp() const { return responds_to_pings; }
 
-    long              getLastTimeSeen() const { return last_time_seen; }
+    long                  getLastTimeSeen() const { return last_time_seen; }
 
-    void              setUp() { responds_to_pings = true; }
+    void                  setUp() { responds_to_pings = true; }
 
-    void              setDown() { responds_to_pings = false; }
+    void                  setDown() { responds_to_pings = false; }
 
+    const ControllerInfo& getController() const { return controller; }
   private:
-    bool              responds_to_pings;
-    long              last_time_seen;
+    ControllerInfo        controller;
+    bool                  responds_to_pings;
+    long                  last_time_seen;
   };
 
 public:
@@ -109,13 +113,13 @@
    * Associates given lastTimeSeen value to specified controller and update its
    * state: if the controller was considered as down, calls the
    * [EMAIL PROTECTED] ControllerStateChangedCallback#onControllerUp(const 
ControllerInfo&)}
-   * @param ctrl controller to be updated
+   * @param ctrlAddr controller socket address to be updated
    * @param newTime time to associate to this controller. Typically the result
    * of gettimeofday()
    * 
    * @see ControllerStateChangedCallback
    */
-  void setControllerResponsed(const ControllerInfo& ctrl, long newTime);
+  void setControllerResponsed(const SocketAddress& ctrlAddr, long newTime);
 
   /**
    * Updates all controllers state according to the given time.<br>
@@ -135,9 +139,9 @@
    * If the given controller was already down, does nothing. Otherwise, marks 
it
    * as dead and calls
    * [EMAIL PROTECTED] ControllerStateChangedCallback#onControllerDown(const 
ControllerInfo&)}
-   * @param ctrl controller to consider as failing
+   * @param ctrlAddr controller socket address to consider as failing
    */
-  void setControllerDown(const ControllerInfo& ctrl);
+  void setControllerDown(const SocketAddress& ctrlAddr);
 
   /**
    * Returns a 'safe' read-only iterator on controllers' ControllerInfo.<br>
@@ -145,11 +149,14 @@
    * This way, the iterator will not be affected by hashmap operations
    * @return a vector of all monitored controllers
    */
-  std::vector<ControllerInfo> getControllers() const;
+  std::vector<SocketAddress> getControllerAddresses() const;
 
 private:
-  /** All controllers with corresponding state */
-  std::map<ControllerInfo, ControllerState>   controllers;
+  /**
+   * UDP addresses identifying controllers and associater controller and
+   * states
+   */
+  std::map<SocketAddress, ControllerAndState> controllers;
 
   /** To manage controllers concurrent accesses */
   static CriticalSection                      controllers_CS;
Index: carob/src/ControllerInfo.cpp
diff -u carob/src/ControllerInfo.cpp:1.10 carob/src/ControllerInfo.cpp:1.11
--- carob/src/ControllerInfo.cpp:1.10   Wed Dec 20 21:40:54 2006
+++ carob/src/ControllerInfo.cpp        Thu Dec 21 23:23:17 2006
@@ -20,160 +20,67 @@
  */
 
 #include "ControllerInfo.hpp"
+#include "SocketAddress.hpp"
 #include "DriverSocket.hpp"
 #include "ControllerPool.hpp"
 #include "StringCodecs.hpp" //for toString()
 #include "Common.hpp" //for logging
-
-#include <sstream>
-#include <iostream>
-#include <errno.h>
+#include <sstream> //for wostringstream
 
 using namespace CarobNS;
 
 using std::wstring;
 
-ControllerInfo::ControllerInfo() : host_port(static_cast<in_port_t>(-1)),
-    original_hostname(L""), UDP_addr_len(0), has_been_connected(false),
-    TCP_sock_addr_len(0)
+// defined below
+namespace CarobNS
 {
-  host_address[0] = '\0';
+std::wostream& operator<< (std::wostream& ostr, const addrinfo& toprint);
 }
 
 ControllerInfo::ControllerInfo(const std::wstring &name, in_port_t port)
-    throw (ConnectionException, UnexpectedException) : host_port(port),
-    original_hostname(name), UDP_addr_len(0), has_been_connected(false),
-    TCP_sock_addr_len(0)
-{
-  // get the udp addresses
-  struct addrinfo* addrs = getAddrs(name, port, SOCK_DGRAM, AF_UNSPEC); // 
AF_UNSPEC = all families, function return will tell us which
-  // UDP_addrs always contain at least one address, otherwise an exception 
would
+    throw (ConnectionException, UnexpectedException) :
+    original_hostname(name)
+{
+  // get the addresses
+  addrinfo* addrs = getAddrs(name, port);
+  // addrs always contain at least one address, otherwise an exception would
   // have been thrown
-  // We cannot know for sure which of the returned addresses is valid, so we
-  // take the first one, preferably the one which sin_addr is not 0, and 
discard
-  // others
-  UDP_addr_len = addrs->ai_addrlen;
-  // Try to find an address with non 0 sin_addr
-  struct addrinfo* iter = addrs;
-  bool nonZeroAddrFound = false;
-  while (!nonZeroAddrFound && iter != NULL)
-  {
-    if (iter->ai_addr->sa_family == AF_INET)
-    {
-      sockaddr_in inAddr;
-      memcpy(&inAddr, &(iter->ai_addr), iter->ai_addrlen);
-      if (inAddr.sin_addr.s_addr != 0)
-        nonZeroAddrFound = true;
-    }
-    else if (iter->ai_addr->sa_family == AF_INET6)
-    {
-      sockaddr_in6 inAddr6;
-      memcpy(&inAddr6, &(iter->ai_addr), iter->ai_addrlen);
-      for (int i = 0; i < 16; i++)
-      {
-        if (inAddr6.sin6_addr.s6_addr[i] != 0)
-        {
-          nonZeroAddrFound = true;
-          break;
-        }
-      }
-    }
-    if (!nonZeroAddrFound) // keep the position of the good address
-      iter = iter->ai_next;
-  }
-  if (!nonZeroAddrFound)
-    // not found, let's use the first one
-    iter = addrs;
-
-  memcpy(&UDP_addr, iter->ai_addr, UDP_addr_len);
-  // discards the returned addresses
+  // We cannot know for sure which of the returned addresses is valid, we take
+  // arbitrarly the first one
+  socket_address.setAddress(addrs->ai_addr, addrs->ai_addrlen);
+  // discard the allocated addresses
   freeaddrinfo(addrs);
-
-  // get the unique numeric host name from this UDP address
-  getHostAddressFromUDPAddr();
 }
 
 ControllerInfo::ControllerInfo(const ControllerInfo& ci)
-    throw (ConnectionException, UnexpectedException) : 
-    host_port(static_cast<in_port_t>(-1)), original_hostname(L""),
-    UDP_addr_len(0), has_been_connected(false), TCP_sock_addr_len(0)
+    throw (ConnectionException, UnexpectedException)
 {
   // make use of the = operator
   *this = ci;
 }
 
-ControllerInfo::ControllerInfo(const struct sockaddr& UDPAddr, socklen_t len)
-    throw (ConnectionException, UnexpectedException) :
-    host_port(static_cast<in_port_t>(-1)), original_hostname(L""),
-    UDP_addr_len(len), has_been_connected(false), TCP_sock_addr_len(0)
+ControllerInfo::~ControllerInfo()
 {
-  // the given address becomes our udp adrress
-  memcpy(&UDP_addr, &UDPAddr, UDP_addr_len);
-  // Get the port depending on address family
-  sa_family_t family = UDP_addr.sa_family;
-  if (family == AF_INET) // ipv4
-  {
-    sockaddr_in inAddr;
-    memcpy(&inAddr, &UDP_addr, UDP_addr_len);
-    host_port = ntohs(inAddr.sin_port);
-  }
-  else if (family == AF_INET6)
-  {
-    sockaddr_in6 inAddr6;
-    memcpy(&inAddr6, &UDP_addr, UDP_addr_len);
-    host_port = ntohs(inAddr6.sin6_port);
-  }
-  // Get a unique numeric string rep of the given address.
-  getHostAddressFromUDPAddr();
-
-  // Try to get a pretty name for host
-  char hostname_str[NI_MAXHOST+1];
-  int error = getnameinfo(&UDP_addr, UDP_addr_len, hostname_str, 
sizeof(hostname_str), NULL, 0, NI_NOFQDN);
-  if (error == 0)
-  {
-    // ok, use returned address
-    original_hostname = fromString(hostname_str);
-  }
-  else
-  {
-    // failure, just use the numeric address
-    original_hostname = fromString(host_address);
-  }
 }
 
-ControllerInfo& ControllerInfo::operator =(const ControllerInfo& ci)
-    throw (ConnectionException, UnexpectedException)
+ControllerInfo& ControllerInfo::operator = (const ControllerInfo& ci)
 {
-  host_port = ci.host_port;
+  socket_address = ci.socket_address;
   original_hostname = ci.original_hostname;
-  strncpy(host_address, ci.host_address, NI_MAXHOST);
-  // copy the udp address
-  UDP_addr_len = ci.UDP_addr_len;
-  memcpy(&UDP_addr, &(ci.UDP_addr), UDP_addr_len);
-  has_been_connected = ci.has_been_connected;
-  // copy the TCP socket address if appropriate
-  if (ci.has_been_connected)
-  {
-    TCP_sock_addr_len = ci.TCP_sock_addr_len;
-    memcpy(&TCP_sock_addr, &(ci.TCP_sock_addr), ci.TCP_sock_addr_len);
-  }
   return *this;
 }
 
-ControllerInfo::~ControllerInfo()
-{
-}
-
-struct addrinfo* ControllerInfo::getAddrs(const std::wstring& name, in_port_t 
port, int socktype,  int family)
+/* static */
+addrinfo* ControllerInfo::getAddrs(const std::wstring& name, in_port_t port)
     throw (ConnectionException, UnexpectedException)
 {
   const wstring fctName(L"ControllerInfo::getAddrs");
   char service[NI_MAXSERV];
-  struct addrinfo*  addressList = NULL;
-  struct addrinfo   hint;
+  addrinfo*  addressList = NULL;
+  addrinfo   hint;
   memset(&hint, 0, sizeof(hint));
-  hint.ai_socktype = SOCK_DGRAM;
-  hint.ai_family = family;
+  hint.ai_socktype = SOCK_STREAM;
+  hint.ai_family = AF_UNSPEC;
   hint.ai_flags = AI_ADDRCONFIG; // will prevent receiving addresses we can't 
talk to
   #ifdef AI_NUMERICSERV
   // prevent name resolution (only if AI_NUMERICSERV is supported) 
@@ -182,6 +89,18 @@
   // convert given port to char*
   snprintf(service, NI_MAXSERV, "%d", port);
   int error = getaddrinfo(toString(name).c_str(), service, &hint, 
&addressList);
+  if (isInfoEnabled())
+  {
+    std::wostringstream msg;
+    msg<<L"Gathered following addresses for "<<name<<":"<<port<<" : ";
+    for (addrinfo *addri = addressList; addri != NULL; addri = addri->ai_next)
+    {
+      msg << *addri;
+      if (addri->ai_next)
+        msg << L"; ";
+    }
+    logInfo(fctName, msg.str());
+  }
   // not sure addressList can be NULL without error, but it is cheap to check
   if (error || addressList == NULL)
   {
@@ -192,6 +111,7 @@
       // get the error from getaddrinfo
       const char* gaiMsg = gai_strerror(error);
       wMsg += L". Error was: " + fromString(gaiMsg);
+      freeaddrinfo(addressList);
     }
 #endif
     if (isDebugEnabled())
@@ -201,41 +121,15 @@
   return addressList;
 }
 
-int ControllerInfo::getFamily() const
-{
-  return UDP_addr.sa_family;
-}
-
-void ControllerInfo::getHostAddressFromUDPAddr() throw (ConnectionException, 
UnexpectedException)
-{
-  const wstring fctName(L"ControllerInfo::gethost_addressFromUDPAddr");
-  int error = getnameinfo(&UDP_addr, UDP_addr_len, host_address, 
sizeof(host_address), NULL, 0, NI_NUMERICHOST);
-  if (error != 0)
-  {
-    wstring wMsg(L"Error while executing getnameinfo()");
-#ifndef __MINGW32__
-    const char* gaiMsg = gai_strerror(error);
-    wMsg += L". Error was: " + fromString(gaiMsg);
-#endif
-    if (isDebugEnabled())
-      logDebug(fctName, wMsg);
-    throw ConnectionException(wMsg);
-  }
-}
-
 DriverSocket* ControllerInfo::connect(AbstractControllerPool& pool)
     throw (ConnectionException, UnexpectedException)
 {
   const wstring fctName(L"ControllerInfo::connect()");
-  struct addrinfo* addr = getAddrs(fromString(host_address), host_port, 
SOCK_STREAM, getFamily());
-
-  // to iterate on the returned list
-  struct addrinfo* addrIter = addr;
 
   DriverSocket* socketPtr = new DriverSocket();
   // set the correct protocol family
   int family = PF_INET;
-  if (getFamily() == AF_INET6)
+  if (socket_address.getFamily() == AF_INET6)
   {
     family = PF_INET6;
     if (isWarnEnabled())
@@ -248,7 +142,6 @@
   catch (ConnectionException ce)
   {
     delete socketPtr;
-    freeaddrinfo(addr);      
     throw;
   }
   // register the socket to our policy so it can be killed during connection
@@ -256,76 +149,121 @@
 
   if (isDebugEnabled())
     logDebug(fctName, L"Connecting...");
-  // if we got multiple addresses, we will try to connect to all of these (in
-  // the order returned by getAddrs()
-  while (addrIter != NULL)
+
+  try
   {
-    try
+    if (socketPtr->connectTo(socket_address))
     {
-      if (socketPtr->connectTo(addrIter, getHostPort()))
-      {
-        if (isInfoEnabled())
-          logInfo(fctName, L"Connection to " + static_cast<wstring>(*this) + 
L" succeeded");
-        // Connection succeeded: keep the valid addrinfo sockaddr and free list
-        memcpy(&TCP_sock_addr, addrIter->ai_addr, addrIter->ai_addrlen);
-        TCP_sock_addr_len = addrIter->ai_addrlen;
-        freeaddrinfo(addr);
-        has_been_connected = true;
-        return socketPtr;
-      }
+      if (isInfoEnabled())
+        logInfo(fctName, L"Connection to " + static_cast<wstring>(*this)
+            + L" succeeded");
+      return socketPtr;
     }
-    catch (ConnectionException ce)
-    {
-      pool.unRegisterSocket(*this, socketPtr);
-      delete socketPtr;
-      freeaddrinfo(addr);      
-      throw ce;
-    }
-    if (isDebugEnabled())
-      logDebug(fctName, L"Could not connect, trying next address if any...");
-    addrIter = addrIter->ai_next;
   }
+  catch (ConnectionException ce)
+  {
+    pool.unRegisterSocket(*this, socketPtr);
+    delete socketPtr;
+    throw ce;
+  }
+  if (isDebugEnabled())
+    logDebug(fctName, L"Could not connect to " + static_cast<wstring>(*this));
+
   // could not connect to any of the addresses
   pool.unRegisterSocket(*this, socketPtr);
   delete socketPtr;
-  freeaddrinfo(addr);
   throw ConnectionException(L"Connection failed");
 }
 
-bool ControllerInfo::operator ==(const ControllerInfo& ci) const
-{
-  int cmp = strncmp(host_address, ci.host_address, NI_MAXHOST);
-  if (cmp == 0) // same name, compare ports
-  {
-    return host_port == ci.host_port;
-  }
-  // different name
-  return false;
-}
-
-bool ControllerInfo::operator <(const ControllerInfo& ci) const
+bool ControllerInfo::operator < (const ControllerInfo& ci) const
 {
-  int cmp = strncmp(host_address, ci.host_address, NI_MAXHOST);
-  if (cmp == 0) // same name, compare ports
-  {
-    return host_port < ci.host_port;
-  }
-  // different name, return result of compairison
-  return cmp < 0;
+  return (socket_address < ci.socket_address);
 }
 
-bool ControllerInfo::operator >(const ControllerInfo& ci) const
+bool ControllerInfo::operator == (const ControllerInfo& ci) const
 {
-  int cmp = strncmp(host_address, ci.host_address, NI_MAXHOST);
-  if (cmp == 0) // same name, compare ports
-  {
-    return host_port > ci.host_port;
-  }
-  // different name, return result of compairison
-  return cmp > 0;
+  // if none if less that the other, they are equal!
+  return (!(*this < ci)
+       && !(ci < *this));
 }
 
 ControllerInfo::operator std::wstring() const
 {
-  return original_hostname + L"/" + fromString(host_address) + L":" + 
toWString(host_port);
+  std::wostringstream msg;
+  msg<<original_hostname<<L" ("<<*(socket_address.getAddressPtr())<<L")";
+  return msg.str();
+}
+
+/*
+ Typically used like this:
+
+  for (addrinfo *addri = addressList; addri != NULL; addri = addri->ai_next)
+  {
+    std::wcerr << *addri;
+    if (addri->ai_next)
+      std::wcerr << L"; ";
+  }
+*/
+namespace CarobNS
+{
+std::wostream&
+operator<< (std::wostream& oss, const addrinfo& addri)
+{
+
+    switch(addri.ai_family) {
+    case AF_INET:
+        oss << L"AF_INET"; break;
+    case AF_INET6:
+        oss << L"AF_INET6"; break;
+    case AF_UNIX:
+        oss << L"AF_UNIX"; break;
+    case AF_UNSPEC:
+        oss << L"AF_UNSPEC"; break;
+    default:
+        oss << L"unknown ai_family number=" << addri.ai_family ; break;
+    }
+    oss << L":";
+
+    if (addri.ai_canonname)
+        oss << StaticCodecs::fromASCII(addri.ai_canonname) << L"/";
+    else
+        oss << L"<unresolved>" << L"/";
+
+    oss << *(addri.ai_addr);
+
+    oss << L",";
+    switch(addri.ai_socktype) {
+    case SOCK_STREAM:
+        oss << L"SOCK_STREAM"; break;
+    case SOCK_DGRAM:
+        oss << L"SOCK_DGRAM"; break;
+    default:
+        oss << L"unknown socket type=" << addri.ai_socktype ; break;
+    }
+
+    oss << L"/";
+    switch(addri.ai_protocol) {
+    case IPPROTO_TCP:
+        oss << L"IPPROTO_TCP"; break;
+    case IPPROTO_UDP:
+        oss << L"IPPROTO_UDP"; break;
+    default:
+        oss << L"unknown protocol=" << addri.ai_protocol ; break;
+    }
+
+
+    oss << L",flags=";
+
+    oss << addri.ai_flags;
+
+    // hex
+    std::wostringstream wss;
+    wss.setf(std::ios_base::hex, std::ios_base::basefield);
+    wss.setf(std::ios_base::showbase);
+    wss << L"(" << addri.ai_flags << L")";
+
+    oss << wss.str();
+
+    return oss;
+}
 }
Index: carob/src/ControllerPingSender.cpp
diff -u carob/src/ControllerPingSender.cpp:1.4 
carob/src/ControllerPingSender.cpp:1.5
--- carob/src/ControllerPingSender.cpp:1.4      Wed Dec 20 19:38:41 2006
+++ carob/src/ControllerPingSender.cpp  Thu Dec 21 23:23:17 2006
@@ -21,6 +21,7 @@
 
 #include "ControllerPingSender.hpp"
 
+#include "SocketAddress.hpp"
 #include "WatchedControllers.hpp"
 #include "Common.hpp"
 
@@ -60,11 +61,11 @@
   packet[0] = CONTROLLER_PING_VERSION;
   while (!is_stopped)
   {
-    std::vector<ControllerInfo> ctrls = controllers.getControllers();
-    for (std::vector<ControllerInfo>::const_iterator iter = ctrls.begin(); 
iter != ctrls.end(); iter++)
+    std::vector<SocketAddress> ctrls = controllers.getControllerAddresses();
+    for (std::vector<SocketAddress>::const_iterator iter = ctrls.begin(); iter 
!= ctrls.end(); iter++)
     {
       sendto(send_socket, static_cast<void*>(packet), sizeof(packet), 0,
-          iter->getUDPAddrPtr(), iter->getUDPAddrLen());
+          iter->getAddressPtr(), iter->getAddressLength());
       // This is really too much logs...
     }
     // detect violent clock changes (user hardly set new date/time)
Index: carob/src/ControllerPool.cpp
diff -u carob/src/ControllerPool.cpp:1.17 carob/src/ControllerPool.cpp:1.18
--- carob/src/ControllerPool.cpp:1.17   Wed Dec 20 19:38:41 2006
+++ carob/src/ControllerPool.cpp        Thu Dec 21 23:23:17 2006
@@ -201,7 +201,7 @@
   {
     if (*iter_pi1 < *iter_pi2)
       return true;
-    if (*iter_pi1 > *iter_pi2)
+    if (*iter_pi2 < *iter_pi1)
       return false;
     iter_pi1++;
     iter_pi2++;
Index: carob/src/ControllerWatcher.cpp
diff -u carob/src/ControllerWatcher.cpp:1.8 carob/src/ControllerWatcher.cpp:1.9
--- carob/src/ControllerWatcher.cpp:1.8 Wed Dec 20 19:38:41 2006
+++ carob/src/ControllerWatcher.cpp     Thu Dec 21 23:23:17 2006
@@ -21,6 +21,7 @@
 
 #include "ControllerWatcher.hpp"
 
+#include "SocketAddress.hpp"
 #include "ControllerPingSender.hpp"
 #include "ControllerStateChangedCallback.hpp"
 #include "WatchedControllers.hpp"
@@ -29,6 +30,7 @@
 #include "Common.hpp"
 
 #include <fcntl.h> // setsockopt
+#include <sstream> //for wostringstream
 
 #include <unistd.h> // usleep()
 
@@ -73,7 +75,7 @@
       controllerTimeout, callbackPtr);
 
   // Get the ip family of the first controller, this will be the default one
-  socket_fd = socket(controllerList.front().getFamily(), SOCK_DGRAM, 0);
+  socket_fd = socket(controllerList.front().getSocketAddress().getFamily(), 
SOCK_DGRAM, 0);
   // set socket non blocking
 #ifdef __MINGW32__
   int var = 1;
@@ -115,30 +117,32 @@
 {
   const wstring fctName(L"ControllerWatcher::processAnswers");
   java_byte buf[1];
-  struct sockaddr respondingCtrlAddr;
-  socklen_t respondingCtrlAddrLength = sizeof(respondingCtrlAddr);
+  sockaddr_storage respondingCtrlAddr;
+  socklen_t respondingCtrlAddrLength = sizeof(sockaddr_storage);
   ssize_t recLength = recvfrom(socket_fd, static_cast<void*>(buf), 1,
-       0, &respondingCtrlAddr, &respondingCtrlAddrLength);
+       0, reinterpret_cast<sockaddr*>(&respondingCtrlAddr), 
&respondingCtrlAddrLength);
   while (recLength > 0)
   {
     try
     {
-      ControllerInfo ctrl(respondingCtrlAddr, respondingCtrlAddrLength);
+      SocketAddress ctrlAddr(reinterpret_cast<sockaddr*>(&respondingCtrlAddr), 
respondingCtrlAddrLength);
       // This is really too much logs...
 //      if (isDebugEnabled())
 //        logDebug(fctName, L"Received response from " + 
static_cast<wstring>(ctrl));
       if (buf[0] == CONTROLLER_PING_VERSION)
       {
-        controllers_ptr->setControllerResponsed(ctrl, getCurrentTimeInMs());
+        controllers_ptr->setControllerResponsed(ctrlAddr, 
getCurrentTimeInMs());
       }
       else if (isDebugEnabled())
       {
-        logDebug(fctName, L"Wrong ping version in response from "
-            + static_cast<wstring>(ctrl) + L" was: " + toUserString(buf[0]) + 
L", expected:"
-            + toUserString(CONTROLLER_PING_VERSION));
+        std::wostringstream buffer;
+        buffer<<L"Wrong ping version in response from "//<<FIXME: ctrlAddr
+              <<+ L" was: "<<buf[0]
+              <<L", expected:"<<CONTROLLER_PING_VERSION;
+        logDebug(fctName, buffer.str());
       }
       recLength = recvfrom(socket_fd, static_cast<void*>(buf), 1,
-           0, &respondingCtrlAddr, &respondingCtrlAddrLength);
+           0, reinterpret_cast<sockaddr*>(&respondingCtrlAddr), 
&respondingCtrlAddrLength);
     }
     catch (ConnectionException ignored)
     {
@@ -174,5 +178,5 @@
  */
 void ControllerWatcher::forceControllerDown(const ControllerInfo& c)
 {
-  controllers_ptr->setControllerDown(c);
+  controllers_ptr->setControllerDown(c.getSocketAddress());
 }
Index: carob/src/JavaSocket.cpp
diff -u carob/src/JavaSocket.cpp:1.64 carob/src/JavaSocket.cpp:1.65
--- carob/src/JavaSocket.cpp:1.64       Wed Dec 20 19:38:41 2006
+++ carob/src/JavaSocket.cpp    Thu Dec 21 23:23:17 2006
@@ -20,6 +20,7 @@
  */
 
 #include "JavaSocket.hpp"
+#include "SocketAddress.hpp"
 
 #include "Common.hpp"
 #include "SystemDependantDefs.hpp"
@@ -29,9 +30,7 @@
 #else
   #include <sys/types.h>   //  socket(), send(), etc.
   #include <sys/socket.h>  //         "
-  #include <netdb.h> // getaddrinfo() etc.
   #include <netinet/tcp.h> // TCP_NODELAY etc.
-  #include <unistd.h> // sleep()
 #endif
 #include <errno.h>
 #include <fcntl.h>
@@ -111,7 +110,7 @@
     logDebug(fctName, L"Socket created.");
 }
 
-bool JavaSocket::connectTo(struct addrinfo* ai, in_port_t port)
+bool JavaSocket::connectTo(const SocketAddress& addr)
     throw (ConnectionException, UnexpectedException)
 {
   const wstring fctName(L"JavaSocket::connectTo");
@@ -123,12 +122,8 @@
     throw ConnectionException(L"Invalid socket for connection");
   }
 
-  sockaddr_in addr = {0};
-  addr = *(reinterpret_cast<struct sockaddr_in*>(ai->ai_addr));
-  addr.sin_port = htons(port);
-
   // try non blocking connect
-  int resp = ::connect(socket_fd, reinterpret_cast<sockaddr*>(&addr), 
sizeof(addr));
+  int resp = ::connect(socket_fd, addr.getAddressPtr(), 
addr.getAddressLength());
   if (resp==0)
   {
     // connection succeeded, set back to blocking mode
Index: carob/src/SocketAddress.cpp
diff -u carob/src/SocketAddress.cpp:1.3 carob/src/SocketAddress.cpp:1.4
--- carob/src/SocketAddress.cpp:1.3     Thu Dec 21 20:26:28 2006
+++ carob/src/SocketAddress.cpp Thu Dec 21 23:23:17 2006
@@ -40,7 +40,7 @@
 
 using namespace CarobNS;
 
-SocketAddress::SocketAddress() : address(NULL), 
address_length(static_cast<socklen_t>(-1))
+SocketAddress::SocketAddress() : address_length(static_cast<socklen_t>(-1))
 {
 }
 
@@ -54,41 +54,46 @@
   setAddress(sa, l);
 }
 
-void SocketAddress::setAddress(sockaddr* sa, socklen_t l)
+SocketAddress::~SocketAddress()
 {
-  address_length = l;
-  address = static_cast<sockaddr*>(malloc(l));
-  memcpy(address, sa, l);
+}
+void SocketAddress::setAddress(const sockaddr* sa, socklen_t l)
+{
+  if (sa != NULL && l > 0)
+  {
+    address_length = l;
+    memcpy(&address, sa, l);
+  }
 }
 
 SocketAddress& SocketAddress::operator = (const SocketAddress& sa)
 {
-  setAddress(sa.address, sa.address_length);
+  setAddress(reinterpret_cast<const sockaddr*>(&(sa.address)), 
sa.address_length);
   return *this;
 }  
 
 bool SocketAddress::operator < (const SocketAddress& sa) const
 {
-  if (address == NULL)
-    return true;
-  if (sa.address == NULL)
-    return true;
   if (address_length != sa.address_length)
     return (address_length < sa.address_length);
-  if (address->sa_family != sa.address->sa_family)
-    return (address->sa_family < sa.address->sa_family);
+  if (getFamily() != sa.getFamily())
+    return (getFamily() < sa.getFamily());
   if (getFamily() == AF_INET) // ipv4
   {
     sockaddr_in this_in, sa_in;
-    memcpy(&this_in, address, address_length);
-    memcpy(&sa_in, &sa.address, sa.address_length);
+    memcpy(&this_in, &address, address_length);
+    memcpy(&sa_in, &(sa.address), sa.address_length);
+    if (this_in.sin_port != sa_in.sin_port)
+      return (this_in.sin_port < sa_in.sin_port);
     return (this_in.sin_addr.s_addr < sa_in.sin_addr.s_addr);
   }
   else if (getFamily() == AF_INET6)// ipv6
   {
     sockaddr_in6 this_in6, sa_in6;
-    memcpy(&this_in6, address, address_length);
-    memcpy(&sa_in6, &sa.address, sa.address_length);
+    memcpy(&this_in6, &address, address_length);
+    memcpy(&sa_in6, &(sa.address), sa.address_length);
+    if (this_in6.sin6_port != sa_in6.sin6_port)
+      return (this_in6.sin6_port < sa_in6.sin6_port);
     for (int i=0; i<16; i++)
       if (this_in6.sin6_addr.s6_addr[i] >= sa_in6.sin6_addr.s6_addr[i])
         return false;
@@ -102,14 +107,6 @@
   }
 }
 
-sa_family_t SocketAddress::getFamily() const
-{
-  if (address == NULL)
-    return AF_UNSPEC;
-  return address->sa_family;
-}
-
-
 namespace
 {
 
@@ -130,11 +127,8 @@
 
 }
 
-namespace CarobNS
-{
-
 std::wostream&
-operator<< (std::wostream& oss, const sockaddr& sock)
+CarobNS::operator<< (std::wostream& oss, const sockaddr& sock)
 {
 
     switch(sock.sa_family) {
@@ -164,78 +158,3 @@
 
     return oss;
 }
-
-
-/*
- Typically used like this:
-
-  for (addrinfo *addri = addressList; addri != NULL; addri = addri->ai_next)
-  {
-    std::wcerr << *addri;
-    if (addri->ai_next)
-      std::wcerr << L"; ";
-  }
-*/
-
-std::wostream&
-operator<< (std::wostream& oss, const addrinfo& addri)
-{
-
-    switch(addri.ai_family) {
-    case AF_INET:
-        oss << L"AF_INET"; break;
-    case AF_INET6:
-        oss << L"AF_INET6"; break;
-    case AF_UNIX:
-        oss << L"AF_UNIX"; break;
-    case AF_UNSPEC:
-        oss << L"AF_UNSPEC"; break;
-    default:
-        oss << L"unknown ai_family number=" << addri.ai_family ; break;
-    }
-    oss << L":";
-
-    if (addri.ai_canonname)
-        oss << StaticCodecs::fromASCII(addri.ai_canonname) << L"/";
-    else
-        oss << L"<unresolved>" << L"/";
-
-    oss << *(addri.ai_addr);
-
-    oss << L",";
-    switch(addri.ai_socktype) {
-    case SOCK_STREAM:
-        oss << L"SOCK_STREAM"; break;
-    case SOCK_DGRAM:
-        oss << L"SOCK_DGRAM"; break;
-    default:
-        oss << L"unknown socket type=" << addri.ai_socktype ; break;
-    }
-
-    oss << L"/";
-    switch(addri.ai_protocol) {
-    case IPPROTO_TCP:
-        oss << L"IPPROTO_TCP"; break;
-    case IPPROTO_UDP:
-        oss << L"IPPROTO_UDP"; break;
-    default:
-        oss << L"unknown protocol=" << addri.ai_protocol ; break;
-    }
-
-
-    oss << L",flags=";
-
-    oss << addri.ai_flags;
-
-    // hex
-    std::wostringstream wss;
-    wss.setf(std::ios_base::hex, std::ios_base::basefield);
-    wss.setf(std::ios_base::showbase);
-    wss << L"(" << addri.ai_flags << L")";
-
-    oss << wss.str();
-
-    return oss;
-}
-
-} // namespace CarobNS
Index: carob/src/WatchedControllers.cpp
diff -u carob/src/WatchedControllers.cpp:1.4 
carob/src/WatchedControllers.cpp:1.5
--- carob/src/WatchedControllers.cpp:1.4        Wed Dec 20 19:38:41 2006
+++ carob/src/WatchedControllers.cpp    Thu Dec 21 23:23:17 2006
@@ -31,23 +31,29 @@
 using std::vector;
 using std::wstring;
 
-WatchedControllers::ControllerState::ControllerState() : 
responds_to_pings(true),
-    last_time_seen(-1)
+WatchedControllers::ControllerAndState::ControllerAndState() :
+    responds_to_pings(true), last_time_seen(-1)
 {
 }
 
-WatchedControllers::ControllerState::ControllerState(long initTime) : 
responds_to_pings(true),
-    last_time_seen(initTime)
+WatchedControllers::ControllerAndState::ControllerAndState(const 
ControllerInfo& ctrl) :
+    controller(ctrl), responds_to_pings(true), last_time_seen(-1)
 {
 }
 
-WatchedControllers::ControllerState::ControllerState(const ControllerState& 
src) :
-    responds_to_pings(src.responds_to_pings), last_time_seen(last_time_seen)
+WatchedControllers::ControllerAndState::ControllerAndState(const 
ControllerInfo& ctrl, long initTime) :
+    controller(ctrl), responds_to_pings(true), last_time_seen(initTime)
 {
 }
 
-WatchedControllers::ControllerState& 
WatchedControllers::ControllerState::operator = (const ControllerState& src)
+WatchedControllers::ControllerAndState::ControllerAndState(const 
ControllerAndState& src)
 {
+  *this = src;
+}
+
+WatchedControllers::ControllerAndState& 
WatchedControllers::ControllerAndState::operator = (const ControllerAndState& 
src)
+{
+  controller = src.controller;
   responds_to_pings = src.responds_to_pings;
   last_time_seen = src.last_time_seen;
   return *this;
@@ -55,7 +61,6 @@
 
 /* init static member critical section */
 CriticalSection WatchedControllers::controllers_CS;
-
 WatchedControllers::WatchedControllers(const vector<ControllerInfo>& 
controllersPrm,
     long initTime, int controllerTimeout, ControllerStateChangedCallback* 
cbPtr) :
     controller_timeout(controllerTimeout),
@@ -65,42 +70,45 @@
   // list without worrying of concurrent modifications
   for (std::vector<ControllerInfo>::const_iterator iter = 
controllersPrm.begin(); iter != controllersPrm.end(); iter++)
   {
-    this->controllers[*iter].updateTime(initTime);
+    ControllerAndState cs(*iter, initTime);
+    this->controllers.insert(std::pair<SocketAddress, 
ControllerAndState>(iter->getSocketAddress(), cs));
   }
 }
 
 WatchedControllers::~WatchedControllers()
 {
+  controllers.clear();
   delete callback_ptr;
 }
 
 void WatchedControllers::addController(const ControllerInfo& ctrl, long 
lastTimeSeen)
 {
   LockScope ls(&controllers_CS);
-  controllers[ctrl].updateTime(lastTimeSeen);
+  ControllerAndState cs(ctrl, lastTimeSeen);
+  this->controllers.insert(std::pair<SocketAddress, 
ControllerAndState>(ctrl.getSocketAddress(), cs));
 }
 
 void WatchedControllers::removeController(const ControllerInfo& ctrl)
 {
   LockScope ls(&controllers_CS);
-  controllers.erase(ctrl);
+  controllers.erase(ctrl.getSocketAddress());
 }
 
-void WatchedControllers::setControllerResponsed(const ControllerInfo& ctrl, 
long newTime)
+void WatchedControllers::setControllerResponsed(const SocketAddress& ctrlAddr, 
long newTime)
 {
   const wstring fctName(L"WatchedControllers::setControllerResponsed");
   LockScope ls(&controllers_CS);
-  ControllerState& state = controllers[ctrl];
+  ControllerAndState& state = controllers[ctrlAddr];
   // Set the new time
   state.updateTime(newTime);
   // if the controller was down, we launch the callback
   if (!state.isUp())
   {
     if (isInfoEnabled())
-      logInfo(fctName, L"Controller " + static_cast<wstring>(ctrl)
+      logInfo(fctName, L"Controller " + 
static_cast<wstring>(state.getController())
            + L" responds to pings again. Adding it to the pool.");
     state.setUp();
-    callback_ptr->onControllerUp(ctrl);
+    callback_ptr->onControllerUp(state.getController());
   }
 }
 
@@ -108,45 +116,45 @@
 {
   const wstring fctName(L"WatchedControllers::lookForDeadControllers");
   LockScope ls(&controllers_CS);
-  for (map<ControllerInfo, ControllerState>::iterator iter = 
controllers.begin();
+  for (map<SocketAddress, ControllerAndState>::iterator iter = 
controllers.begin();
       iter != controllers.end(); iter++)
   {
     if (iter->second.isUp()
         && int(currentTime - iter->second.getLastTimeSeen()) > 
controller_timeout)
     {
       if (isWarnEnabled())
-        logWarn(fctName, L"Controller " + static_cast<wstring>(iter->first)
+        logWarn(fctName, L"Controller " + 
static_cast<wstring>(iter->second.getController())
              + L" does not respond to pings. Considering it as down.");
       iter->second.setDown();
-      callback_ptr->onControllerDown(iter->first);
+      callback_ptr->onControllerDown(iter->second.getController());
     }
   }
 }
 
-void WatchedControllers::setControllerDown(const ControllerInfo& ctrl)
+void WatchedControllers::setControllerDown(const SocketAddress& ctrlAddr)
 {
   LockScope ls(&controllers_CS);
-  ControllerState& state = controllers[ctrl];
+  ControllerAndState& state = controllers[ctrlAddr];
   if (state.isUp()) // don't do the job twice
   {
     if (isWarnEnabled())
-      logWarn(L"WatchedControllers::setControllerDown", L"Controller " + 
static_cast<wstring>(ctrl)
+      logWarn(L"WatchedControllers::setControllerDown", L"Controller " + 
static_cast<wstring>(state.getController())
            + L" detected as down by driver");
     state.setDown();
-    callback_ptr->onControllerDown(ctrl);
+    callback_ptr->onControllerDown(state.getController());
   }
 }
 
-vector<ControllerInfo> WatchedControllers::getControllers() const
+vector<SocketAddress> WatchedControllers::getControllerAddresses() const
 {
   // get a copy of the map to work on.
-  map<ControllerInfo, ControllerState> copy;
+  map<SocketAddress, ControllerAndState> copy;
   {
     LockScope ls(&controllers_CS);
     copy = controllers;
   }
-  vector<ControllerInfo> ctrls;
-  for (map<ControllerInfo, ControllerState>::const_iterator iter = 
copy.begin(); iter != copy.end(); iter++)
+  vector<SocketAddress> ctrls;
+  for (map<SocketAddress, ControllerAndState>::const_iterator iter = 
copy.begin(); iter != copy.end(); iter++)
     ctrls.push_back(iter->first);
   return ctrls;
 }

_______________________________________________
Carob-commits mailing list
[email protected]
https://forge.continuent.org/mailman/listinfo/carob-commits

Reply via email to