瀏覽代碼

Implement comparison and hashing in NetAddress. Clean up Socket_Address code a bit.

rdb 11 年之前
父節點
當前提交
241adfe34d

+ 2 - 2
panda/src/nativenet/Sources.pp

@@ -17,7 +17,7 @@
     buffered_datagramreader.h buffered_datagramreader.i \
     ringbuffer.h ringbuffer.i socket_ip.h \
     socket_tcp_listen.h time_accumulator.h time_out.h \
-    socket_address.h \
+    socket_address.I socket_address.h \
     socket_portable.h  time_base.h time_span.h buffered_datagramwriter.h \
     socket_base.h socket_selector.h \
     socket_udp.h \
@@ -42,7 +42,7 @@
     ringbuffer.h ringbuffer.i socket_ip.h socket_tcp_listen.h \
     time_accumulator.h time_out.h \
     buffered_datagramreader.h buffered_datagramreader.i \
-    socket_address.h \
+    socket_address.I socket_address.h \
     socket_portable.h time_base.h time_span.h buffered_datagramwriter.h \
     socket_base.h socket_selector.h \
     socket_udp.h \

+ 278 - 0
panda/src/nativenet/socket_address.I

@@ -0,0 +1,278 @@
+// Filename: socket_address.I
+// Created by:  rdb (19Oct14)
+//
+////////////////////////////////////////////////////////////////////
+//
+// PANDA 3D SOFTWARE
+// Copyright (c) Carnegie Mellon University.  All rights reserved.
+//
+// All use of this software is subject to the terms of the revised BSD
+// license.  You should have received a copy of this license along
+// with this source code in a file named "LICENSE."
+//
+////////////////////////////////////////////////////////////////////
+
+
+//////////////////////////////////////////////////////////////
+//     Function: Socket_Address::GetIPAdddressRaw
+//       Access: Public
+//  Description: Return a RAW sockaddr_in
+//////////////////////////////////////////////////////////////
+INLINE unsigned long Socket_Address::
+GetIPAddressRaw() const {
+  return _addr.sin_addr.s_addr;
+}
+
+///////////////////////////////////////////////////////////////////
+//     Function: Socket_Address
+//       Access: Published
+//  Description: Constructor that lets us set a port value
+////////////////////////////////////////////////////////////////////
+INLINE Socket_Address::
+Socket_Address(unsigned short port) {
+  _addr.sin_family = AF_INET;
+  _addr.sin_addr.s_addr = INADDR_ANY;
+  _addr.sin_port = htons(port);
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: Socket_Address::Copy constructor
+//       Access: Published
+//  Description:
+////////////////////////////////////////////////////////////////////
+INLINE Socket_Address::
+Socket_Address(const Socket_Address &inaddr) {
+  _addr.sin_family = inaddr._addr.sin_family;
+  _addr.sin_addr.s_addr = inaddr._addr.sin_addr.s_addr;
+  _addr.sin_port = inaddr._addr.sin_port;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: Socket_Address::Constructor
+//       Access: Public
+//  Description:
+////////////////////////////////////////////////////////////////////
+INLINE Socket_Address::
+Socket_Address(const AddressType &inaddr) {
+  _addr.sin_family = inaddr.sin_family;
+  _addr.sin_addr.s_addr = inaddr.sin_addr.s_addr;
+  _addr.sin_port = inaddr.sin_port;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: Socket_Address::~Destructor
+//       Access: Published
+//  Description: Normal Destructor
+////////////////////////////////////////////////////////////////////
+INLINE Socket_Address::
+~Socket_Address() {
+}
+
+//////////////////////////////////////////////////////////////
+//     Function: Socket_Address::operator ==
+//       Access: Published
+//  Description:
+//////////////////////////////////////////////////////////////
+INLINE bool Socket_Address::
+operator == (const Socket_Address &in) const {
+  return ((_addr.sin_family == in._addr.sin_family) &&
+          (_addr.sin_addr.s_addr == in._addr.sin_addr.s_addr) &&
+          (_addr.sin_port == in._addr.sin_port));
+}
+
+//////////////////////////////////////////////////////////////
+//     Function: Socket_Address::operator !=
+//       Access: Published
+//  Description:
+//////////////////////////////////////////////////////////////
+INLINE bool Socket_Address::
+operator != (const Socket_Address &in) const {
+  return ((_addr.sin_family != in._addr.sin_family) ||
+          (_addr.sin_addr.s_addr != in._addr.sin_addr.s_addr) ||
+          (_addr.sin_port != in._addr.sin_port));
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: Socket_Address::set_broadcast
+//       Access: Published
+//  Description: Set to the broadcast address and a specified port
+////////////////////////////////////////////////////////////////////
+INLINE bool Socket_Address::
+set_broadcast(int port) {
+  _addr.sin_family = AF_INET;
+  _addr.sin_addr.s_addr = 0xffffffff;
+  _addr.sin_port = htons(port);
+  return true;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: Socket_Address::set_any_IP
+//       Access: Published
+//  Description: Set to any address and a specified port
+////////////////////////////////////////////////////////////////////
+INLINE bool Socket_Address::
+set_any_IP(int port) {
+  _addr.sin_family = AF_INET;
+  _addr.sin_addr.s_addr = INADDR_ANY;
+  _addr.sin_port = htons(port);
+  return true;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: Socket_Address::set_port
+//       Access: Published
+//  Description: Set to a specified port
+////////////////////////////////////////////////////////////////////
+INLINE bool Socket_Address::
+set_port(int port) {
+  _addr.sin_port = htons(port);
+  return true;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: Socket_Address::clear
+//       Access: Published
+//  Description: Set the internal values to a suitable known value
+////////////////////////////////////////////////////////////////////
+INLINE void Socket_Address::
+clear() {
+  _addr.sin_family = AF_INET;
+  _addr.sin_addr.s_addr = INADDR_ANY;
+  _addr.sin_port = htons(0);
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: Socket_Address::get_port
+//       Access: Published
+//  Description: Get the port portion as an integer
+////////////////////////////////////////////////////////////////////
+INLINE unsigned short Socket_Address::
+get_port() const {
+  return ntohs(_addr.sin_port);
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: Socket_Address::get_ip
+//       Access: Published
+//  Description: Return the IP address portion in dot notation string
+////////////////////////////////////////////////////////////////////
+INLINE std::string Socket_Address::
+get_ip() const {
+  return std::string(inet_ntoa(_addr.sin_addr));
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: Socket_Address::get_ip_port
+//       Access: Published
+//  Description: Return the ip address/port in dot notation string
+////////////////////////////////////////////////////////////////////
+INLINE std::string Socket_Address::
+get_ip_port() const {
+  char buf1[100];  // 100 is more than enough for any ip address:port combo..
+  sprintf(buf1, "%s:%d", inet_ntoa(_addr.sin_addr), get_port());
+  return std::string(buf1);
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: Socket_Address::set_host
+//       Access: Published
+//  Description: This function will take a port and string-based
+//               TCP address and initialize the address with this
+//               information.  Returns true on success; on failure,
+//               it returns false and the address may be undefined.
+////////////////////////////////////////////////////////////////////
+INLINE bool Socket_Address::
+set_host(const std::string &hostname, int port) {
+  struct hostent *hp = NULL;
+
+  //
+  // hmm inet_addr does not resolve 255.255.255.255 on ME/98 ??
+  //
+  // * HACK * ??
+  if (hostname  == "255.255.255.255") {
+    return set_broadcast(port);
+  }
+  //
+  //
+
+  PN_uint32 addr =  (long)inet_addr(hostname.c_str());
+  if (addr == INADDR_NONE) {
+    hp = gethostbyname(hostname.c_str());
+    if (hp == NULL) {
+      return false;
+    } else {
+      memcpy(&_addr.sin_addr, hp->h_addr_list[0], (unsigned int) hp->h_length);
+    }
+  } else {
+    memcpy(&_addr.sin_addr, &addr, sizeof(addr));
+  }
+
+  _addr.sin_port = htons(port);
+  _addr.sin_family = AF_INET;
+  return true;
+}
+
+//////////////////////////////////////////////////////////////
+//     Function: Socket_Address::set_host
+//       Access: Published
+//  Description:
+//////////////////////////////////////////////////////////////
+INLINE bool Socket_Address::
+set_host(const std::string &hostname) {
+  std::string::size_type pos = hostname.find(':');
+  if (pos == std::string::npos)
+    return false;
+
+  std::string host = hostname.substr(0, pos);
+  std::string port = hostname.substr(pos + 1, 100);;
+
+  int port_dig = atoi(port.c_str());
+  return set_host(host, port_dig);
+}
+
+//////////////////////////////////////////////////////////////
+//     Function: Socket_Address::set_host
+//       Access: Published
+//  Description:
+//////////////////////////////////////////////////////////////
+INLINE bool Socket_Address::
+set_host(PN_uint32 in_hostname, int port) {
+  memcpy(&_addr.sin_addr, &in_hostname, sizeof(in_hostname));
+  _addr.sin_port = htons(port);
+  _addr.sin_family = AF_INET;
+  return true;
+}
+
+//////////////////////////////////////////////////////////////
+//     Function: <
+//       Access: Published
+//  Description:
+//////////////////////////////////////////////////////////////
+INLINE bool Socket_Address::
+operator < (const Socket_Address &in) const {
+  if (_addr.sin_port < in._addr.sin_port)
+    return true;
+
+  if (_addr.sin_port > in._addr.sin_port)
+    return false;
+
+  if (_addr.sin_addr.s_addr < in._addr.sin_addr.s_addr)
+    return true;
+
+  if (_addr.sin_addr.s_addr > in._addr.sin_addr.s_addr)
+    return false;
+
+  return (_addr.sin_family < in._addr.sin_family);
+}
+
+//////////////////////////////////////////////////////////////
+//     Function: is_mcast_range
+//       Access: Published
+//  Description: True if the address is in the multicast range.
+//////////////////////////////////////////////////////////////
+INLINE bool Socket_Address::
+is_mcast_range(void) const {
+  PN_uint32 address = ntohl(_addr.sin_addr.s_addr);
+  //224.0.0.0-239.255.255.255 .. e0,ef
+  return (address >= 0xe0000000 && address < 0xefffffff);
+}

+ 31 - 265
panda/src/nativenet/socket_address.h

@@ -1,5 +1,5 @@
-#ifndef __SOCKET_ADDRESS_H__
-#define __SOCKET_ADDRESS_H__
+#ifndef SOCKET_ADDRESS_H
+#define SOCKET_ADDRESS_H
 
 #include "pandabase.h"
 #include "numeric_types.h"
@@ -12,277 +12,43 @@
 //    communication layer
 //
 //////////////////////////////
-class EXPCL_PANDA_NATIVENET Socket_Address
-{
+class EXPCL_PANDA_NATIVENET Socket_Address {
 public:
-    typedef struct sockaddr_in AddressType;
-    Socket_Address(const AddressType &inaddr);
-    AddressType & GetAddressInfo() { return _addr; }
-    const AddressType & GetAddressInfo() const   { return _addr; }
-PUBLISHED:
-    
-    inline Socket_Address(short port = 0);
-    inline Socket_Address(const Socket_Address &inaddr);
-
-    inline virtual ~Socket_Address();
-    
-    inline bool set_any_IP(int port);
-    inline bool set_port(int port);
-    inline bool set_broadcast(int port);
-    
-    inline bool set_host(const std::string &hostname, int port) ;
-    inline bool set_host(const std::string &hostname) ;
-    inline bool set_host(unsigned int ip4adr, int port);
-    inline void clear();
-    
-    inline unsigned short get_port() const;
-    inline std::string get_ip() const ;
-    inline std::string get_ip_port() const;
-    inline unsigned long GetIPAddressRaw() const;
-    
-    inline bool operator== (const Socket_Address &in) const;
-    inline bool operator < (const Socket_Address &in) const;
-    
-
-    inline bool isMcastRange();
-
-private:
-    AddressType _addr;
-    
-};
-
-//////////////////////////////////////////////////////////////
-// Function name : Socket_Address::GetIPAdddressRaw
-// Description   : Return a RAW sockaddr_in
-//////////////////////////////////////////////////////////////
-inline unsigned long  Socket_Address::GetIPAddressRaw() const
-{
-    return _addr.sin_addr.s_addr;
-}
-
-///////////////////////////////////////////////////////////////////
-// Function name : Socket_Address
-// Description   : Constructor that lets us set a port value
-////////////////////////////////////////////////////////////////////
-inline Socket_Address::Socket_Address(short port)
-{
-    _addr.sin_family = AF_INET;
-    _addr.sin_addr.s_addr = INADDR_ANY;
-    _addr.sin_port = htons(port);
-}
-
-////////////////////////////////////////////////////////////////////
-// Function name : Socket_Address Constructor
-// Description   : Copy Constructor
-////////////////////////////////////////////////////////////////////
-inline Socket_Address::Socket_Address(const Socket_Address &inaddr)
-{
-    _addr.sin_family = inaddr._addr.sin_family;
-    _addr.sin_addr.s_addr = inaddr._addr.sin_addr.s_addr;
-    _addr.sin_port = inaddr._addr.sin_port;
-}
-
-inline Socket_Address::Socket_Address(const AddressType &inaddr)
-{
-    _addr.sin_family = inaddr.sin_family;
-    _addr.sin_addr.s_addr = inaddr.sin_addr.s_addr;
-    _addr.sin_port = inaddr.sin_port;
-}
-
-////////////////////////////////////////////////////////////////////
-// Function name : ~Socket_Address::Socket_Address
-// Description   : Normal Destructor
-////////////////////////////////////////////////////////////////////
-inline Socket_Address::~Socket_Address()
-{}
+  typedef struct sockaddr_in AddressType;
+  Socket_Address(const AddressType &inaddr);
+  AddressType &GetAddressInfo() { return _addr; }
+  const AddressType &GetAddressInfo() const { return _addr; }
 
-//////////////////////////////////////////////////////////////
-// Function name : Socket_Address::operator==
-// Description   : Allow for normal == operation on a address item..
-//      Will simplify the use in sorted containers..
-//////////////////////////////////////////////////////////////
-inline bool Socket_Address::operator==(const Socket_Address &in) const
-{
-    return ((_addr.sin_family == in._addr.sin_family) &&
-        (_addr.sin_addr.s_addr == in._addr.sin_addr.s_addr) &&
-        (_addr.sin_port == in._addr.sin_port)
-        );
-}
-
-////////////////////////////////////////////////////////////////////
-// Function name : set_broadcast
-// Description   : Set to the broadcast address and a specified port
-////////////////////////////////////////////////////////////////////
-inline bool Socket_Address::set_broadcast(int port)
-{
-    _addr.sin_family = AF_INET;
-    _addr.sin_addr.s_addr = 0xffffffff;
-    _addr.sin_port = htons(port);
-    return true;
-}
-
-////////////////////////////////////////////////////////////////////
-// Function name : set_any_IP
-// Description   : Set to any address and a specified port
-////////////////////////////////////////////////////////////////////
-inline bool Socket_Address::set_any_IP(int port)
-{
-    _addr.sin_family = AF_INET;
-    _addr.sin_addr.s_addr = INADDR_ANY;
-    _addr.sin_port = htons(port);
-    return true;
-}
-
-////////////////////////////////////////////////////////////////////
-// Function name : set_port
-// Description   : Set to a specified port
-////////////////////////////////////////////////////////////////////
-inline bool Socket_Address::set_port(int port)
-{
-    _addr.sin_port = htons(port);
-    return true;
-}
-
-////////////////////////////////////////////////////////////////////
-// Function name : clear
-// Description   : Set the internal values to a suitable known value
-////////////////////////////////////////////////////////////////////
-inline void Socket_Address::clear()
-{
-    _addr.sin_family = AF_INET;
-    _addr.sin_addr.s_addr = INADDR_ANY;
-    _addr.sin_port = htons(0);
-}
-
-////////////////////////////////////////////////////////////////////
-// Function name : get_port
-// Description   : Get the port portion as an integer
-////////////////////////////////////////////////////////////////////
-inline unsigned short Socket_Address::get_port() const
-{
-    return ntohs(_addr.sin_port);
-}
-
-////////////////////////////////////////////////////////////////////
-// Function name : get_ip
-// Description   : Return the ip address portion in dot notation string
-////////////////////////////////////////////////////////////////////
-inline std::string Socket_Address::get_ip() const
-{
-    return std::string(inet_ntoa(_addr.sin_addr));
-}
-
-////////////////////////////////////////////////////////////////////
-// Function name : get_ip_port
-// Description   : Return the ip address/port in dot notation string
-////////////////////////////////////////////////////////////////////
-inline std::string Socket_Address::get_ip_port() const
-{
-    char buf1[100];  // 100 is more than enough for any ip address:port combo..
-    sprintf(buf1, "%s:%d", inet_ntoa(_addr.sin_addr), get_port());
-    return std::string(buf1);
-}
+PUBLISHED:
+  INLINE Socket_Address(unsigned short port = 0);
+  INLINE Socket_Address(const Socket_Address &inaddr);
 
-////////////////////////////////////////////////////////////////////
-// Function name : set_host
-// Description   : this function will take a port and string-based tcp address and initialize
-//      the address with the information
-//
-// Return type  : bool (address is undefined after an error)
-////////////////////////////////////////////////////////////////////
-inline bool Socket_Address::set_host(const std::string &hostname, int port) 
-{
-    struct hostent  *hp = NULL;
+  INLINE virtual ~Socket_Address();
 
-    //
-    // hmm inet_addr does not resolve 255.255.255.255 on ME/98 ??
-    //
-    // * HACK * ?? 
-    if(hostname  == "255.255.255.255")
-        return set_broadcast(port);
-    //
-    //
+  INLINE bool set_any_IP(int port);
+  INLINE bool set_port(int port);
+  INLINE bool set_broadcast(int port);
 
-    PN_uint32 addr =  (long)inet_addr (hostname.c_str());                
-    if(addr == INADDR_NONE)
-    {
-        hp = gethostbyname(hostname.c_str());
-        if(hp== NULL)
-            return false;
-        else
-            memcpy(&(_addr.sin_addr),hp->h_addr_list[0] ,  (unsigned int) hp->h_length);                    
-    }
-    else
-        (void) memcpy(&_addr.sin_addr,&addr,sizeof(addr));
+  INLINE bool set_host(const std::string &hostname, int port) ;
+  INLINE bool set_host(const std::string &hostname) ;
+  INLINE bool set_host(unsigned int ip4adr, int port);
+  INLINE void clear();
 
-    _addr.sin_port = htons(port);
-    _addr.sin_family = AF_INET;
-    return true;
-}
+  INLINE unsigned short get_port() const;
+  INLINE std::string get_ip() const ;
+  INLINE std::string get_ip_port() const;
+  INLINE unsigned long GetIPAddressRaw() const;
 
-//////////////////////////////////////////////////////////////
-// Function name : Socket_Address::set_host
-// Description   :
-//////////////////////////////////////////////////////////////
-inline bool Socket_Address::set_host(const std::string &hostname)
-{
-    std::string::size_type pos = hostname.find(':');
-    if (pos == std::string::npos)
-        return false;
-    
-    std::string host = hostname.substr(0, pos);
-    std::string port = hostname.substr(pos + 1, 100);;
-    
-    int port_dig = atoi(port.c_str());
-    
-    return set_host(host, port_dig);
-}
+  INLINE bool operator ==(const Socket_Address &in) const;
+  INLINE bool operator !=(const Socket_Address &in) const;
+  INLINE bool operator < (const Socket_Address &in) const;
 
-//////////////////////////////////////////////////////////////
-// Function name : Socket_Address::set_host
-// Description   :
-//////////////////////////////////////////////////////////////
-inline bool Socket_Address::set_host(PN_uint32 in_hostname, int port)
-{
-    memcpy(&_addr.sin_addr, &in_hostname, sizeof(in_hostname));
-    _addr.sin_port = htons(port);
-    _addr.sin_family = AF_INET;
-    return true;
-}
+  INLINE bool is_mcast_range() const;
 
-//////////////////////////////////////////////////////////////
-// Function name : <
-// Description   :
-//////////////////////////////////////////////////////////////
-inline bool Socket_Address::operator < (const Socket_Address &in) const
-{
-    if (_addr.sin_port < in._addr.sin_port)
-        return true;
-    
-    if (_addr.sin_port > in._addr.sin_port)
-        return false;
-    
-    if (_addr.sin_addr.s_addr < in._addr.sin_addr.s_addr)
-        return true;
-    
-    if (_addr.sin_addr.s_addr > in._addr.sin_addr.s_addr)
-        return false;
-    
-    
-    return (_addr.sin_family < in._addr.sin_family);
-}
-//////////////////////////////////////////////////////////////
-// Function name : isMcastRange
-// Description   : return true if the address is in the mcast range.
-//////////////////////////////////////////////////////////////
-inline bool Socket_Address::isMcastRange(void)
-{
-    PN_uint32  address = ntohl(_addr.sin_addr.s_addr);
-//224.0.0.0-239.255.255.255 .. e0,ef
-    if(address >= 0xe0000000 && address < 0xefffffff)
-        return true;
-    return false;
-}
+private:
+  AddressType _addr;
+};
 
+#include "socket_address.I"
 
-#endif //__SOCKET_ADDRESS_H__
+#endif  // SOCKET_ADDRESS_H

+ 44 - 14
panda/src/net/netAddress.cxx

@@ -18,7 +18,7 @@
 
 ////////////////////////////////////////////////////////////////////
 //     Function: NetAddress::Constructor
-//       Access: Public
+//       Access: Published
 //  Description: Constructs an unspecified address.
 ////////////////////////////////////////////////////////////////////
 NetAddress::
@@ -27,7 +27,7 @@ NetAddress() {
 
 ////////////////////////////////////////////////////////////////////
 //     Function: NetAddress::Constructor
-//       Access: Public
+//       Access: Published
 //  Description: Constructs an address from a given Socket_Address.
 //               Normally, this constructor should not be used by user
 //               code; instead, create a default NetAddress and use
@@ -40,7 +40,7 @@ NetAddress(const Socket_Address &addr) : _addr(addr) {
 
 ////////////////////////////////////////////////////////////////////
 //     Function: NetAddress::set_any
-//       Access: Public
+//       Access: Published
 //  Description: Sets the address up to refer to a particular port,
 //               but not to any particular IP.  Returns true if
 //               successful, false otherwise (currently, this only
@@ -53,7 +53,7 @@ set_any(int port) {
 
 ////////////////////////////////////////////////////////////////////
 //     Function: NetAddress::set_localhost
-//       Access: Public
+//       Access: Published
 //  Description: Sets the address up to refer to a particular port,
 //               on this host.
 ////////////////////////////////////////////////////////////////////
@@ -64,7 +64,7 @@ set_localhost(int port) {
 
 ////////////////////////////////////////////////////////////////////
 //     Function: NetAddress::set_broadcast
-//       Access: Public
+//       Access: Published
 //  Description: Sets the address to the broadcast address.
 ////////////////////////////////////////////////////////////////////
 bool NetAddress::
@@ -74,7 +74,7 @@ set_broadcast(int port) {
 
 ////////////////////////////////////////////////////////////////////
 //     Function: NetAddress::set_host
-//       Access: Public
+//       Access: Published
 //  Description: Sets the address up to refer to a particular port
 //               on a particular host.  Returns true if the hostname
 //               is known, false otherwise.
@@ -86,7 +86,7 @@ set_host(const string &hostname, int port) {
 
 ////////////////////////////////////////////////////////////////////
 //     Function: NetAddress::clear
-//       Access: Public
+//       Access: Published
 //  Description: Resets the NetAddress to its initial state.
 ////////////////////////////////////////////////////////////////////
 void NetAddress::
@@ -96,7 +96,7 @@ clear() {
 
 ////////////////////////////////////////////////////////////////////
 //     Function: NetAddress::get_port
-//       Access: Public
+//       Access: Published
 //  Description: Returns the port number to which this address refers.
 ////////////////////////////////////////////////////////////////////
 int NetAddress::
@@ -106,7 +106,7 @@ get_port() const {
 
 ////////////////////////////////////////////////////////////////////
 //     Function: NetAddress::set_port
-//       Access: Public
+//       Access: Published
 //  Description: Resets the port number without otherwise changing the
 //               address.
 ////////////////////////////////////////////////////////////////////
@@ -117,7 +117,7 @@ set_port(int port) {
 
 ////////////////////////////////////////////////////////////////////
 //     Function: NetAddress::get_ip_string
-//       Access: Public
+//       Access: Published
 //  Description: Returns the IP address to which this address refers,
 //               formatted as a string.
 ////////////////////////////////////////////////////////////////////
@@ -128,7 +128,7 @@ get_ip_string() const {
 
 ////////////////////////////////////////////////////////////////////
 //     Function: NetAddress::get_ip
-//       Access: Public
+//       Access: Published
 //  Description: Returns the IP address to which this address refers,
 //               as a 32-bit integer, in host byte order.
 ////////////////////////////////////////////////////////////////////
@@ -139,7 +139,7 @@ get_ip() const {
 
 ////////////////////////////////////////////////////////////////////
 //     Function: NetAddress::get_ip_component
-//       Access: Public
+//       Access: Published
 //  Description: Returns the nth 8-bit component of the IP address.
 //               An IP address has four components; component 0 is the
 //               first (leftmost), and component 3 is the last
@@ -156,7 +156,7 @@ get_ip_component(int n) const {
 
 ////////////////////////////////////////////////////////////////////
 //     Function: NetAddress::get_addr
-//       Access: Public
+//       Access: Published
 //  Description: Returns the Socket_Address for this address.
 ////////////////////////////////////////////////////////////////////
 const Socket_Address &NetAddress::
@@ -166,10 +166,40 @@ get_addr() const {
 
 ////////////////////////////////////////////////////////////////////
 //     Function: NetAddress::output
-//       Access: Public
+//       Access: Published
 //  Description:
 ////////////////////////////////////////////////////////////////////
 void NetAddress::
 output(ostream &out) const {
   out << get_ip_string();
 }
+
+//////////////////////////////////////////////////////////////
+//     Function: NetAddress::get_hash
+//       Access: Published
+//  Description:
+//////////////////////////////////////////////////////////////
+size_t NetAddress::
+get_hash() const {
+  return  (size_t)(((int)get_ip()) ^ ((int)get_port() << 16));
+}
+
+//////////////////////////////////////////////////////////////
+//     Function: NetAddress::operator ==
+//       Access: Published
+//  Description:
+//////////////////////////////////////////////////////////////
+bool NetAddress::
+operator == (const NetAddress &other) const {
+  return _addr == other._addr;
+}
+
+//////////////////////////////////////////////////////////////
+//     Function: NetAddress::operator !=
+//       Access: Published
+//  Description:
+//////////////////////////////////////////////////////////////
+bool NetAddress::
+operator != (const NetAddress &other) const {
+  return _addr != other._addr;
+}

+ 4 - 0
panda/src/net/netAddress.h

@@ -46,6 +46,10 @@ PUBLISHED:
 
   void output(ostream &out) const;
 
+  size_t get_hash() const;
+  bool operator == (const NetAddress &other) const;
+  bool operator != (const NetAddress &other) const;
+
 private:
   Socket_Address _addr;
 };