NetworkAddress.cxx
上传用户:sy_wanhua
上传日期:2013-07-25
资源大小:3048k
文件大小:13k
- /* ====================================================================
- * The Vovida Software License, Version 1.0
- *
- * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in
- * the documentation and/or other materials provided with the
- * distribution.
- *
- * 3. The names "VOCAL", "Vovida Open Communication Application Library",
- * and "Vovida Open Communication Application Library (VOCAL)" must
- * not be used to endorse or promote products derived from this
- * software without prior written permission. For written
- * permission, please contact vocal@vovida.org.
- *
- * 4. Products derived from this software may not be called "VOCAL", nor
- * may "VOCAL" appear in their name, without prior written
- * permission of Vovida Networks, Inc.
- *
- * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND
- * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA
- * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES
- * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
- * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
- * DAMAGE.
- *
- * ====================================================================
- *
- * This software consists of voluntary contributions made by Vovida
- * Networks, Inc. and many individuals on behalf of Vovida Networks,
- * Inc. For more information on Vovida Networks, Inc., please see
- * <http://www.vovida.org/>.
- *
- */
- static const char* const NetworkAddress_cxx_Version =
- "$Id: NetworkAddress.cxx,v 1.8 2001/06/27 01:43:47 bko Exp $";
- #include <string>
- #if defined(__FreeBSD__)
- #include <sys/types.h>
- #include "netdb_r.h"
- #endif
- #include "errno.h"
- #include <netinet/in.h>
- #include <arpa/inet.h>
- #ifndef WIN32
- #include <strstream.h>
- #else
- #include <strstream>
- #endif
- #include <netdb.h>
- #include "NetworkAddress.h"
- #include "cpLog.h"
- #include "vsock.hxx"
- #include <iostream>
- #ifdef WIN32
- const int NetworkAddress::getHostLookupFailed = 1;
- const int NetworkAddress::getHostLookupOK = 0;
- #endif
- NetworkAddress::NetworkAddress ( int port /* = -1 */) :
- aPort(port),
- rawHostName("localhost"),
- ipAddressSet(false)
- {
- }
- NetworkAddress::NetworkAddress ( const string& hostname, int port /* = -1 */) :
- aPort(port),
- rawHostName(hostname),
- ipAddressSet(false)
- {
- string::size_type pos = hostname.find(":");
- rawHostName = hostname.substr(0,pos);
- if (pos != string::npos)
- {
- aPort = atoi(hostname.substr(pos+1, string::npos).c_str());
- }
- //cpLog (LOG_INFO, "Address[%s]", rawHostName.c_str());
- //cpLog (LOG_INFO, "Port[%d]", aPort);
-
- ipAddressSet = false;
- }
- void
- NetworkAddress::setHostName ( const string& hostname )
- {
- string::size_type pos = hostname.find(":");
- rawHostName = hostname.substr(0,pos);
- if (pos != string::npos)
- {
- aPort = atoi(hostname.substr(pos+1, string::npos).c_str());
- }
- //cpLog (LOG_INFO, "Address[%s]", rawHostName.c_str());
- //cpLog (LOG_INFO, "Port[%d]", aPort);
-
- ipAddressSet = false;
- }
- void
- NetworkAddress::setPort( int iPort )
- {
- ipAddressSet = false;
- aPort = iPort;
- }
- string
- NetworkAddress::getHostName( ) const
- {
- cpLog(LOG_DEBUG_STACK, "NetworkAddress::getHostName()");
- initIpAddress();
- return hostName;
- }
- string
- NetworkAddress::getIpName () const
- {
- initIpAddress();
- char hostname[1024];
- string ipName = inet_ntop(AF_INET, &ipAddress, hostname, sizeof(hostname));
- return ipName;
- }
- u_int32_t
- NetworkAddress::getIp4Address () const
- {
- u_int32_t lTmp;
- initIpAddress();
- memcpy((void *) &lTmp, ipAddress, IPV4_LENGTH);
- return lTmp;
- }
- void
- NetworkAddress::getSockAddr (struct sockaddr & socka) const
- {
- short tmp_s = htons (aPort);
- char * tmp_p;
- tmp_p = (char*) &tmp_s;
- socka.sa_family = AF_INET;
- socka.sa_data[0] = tmp_p[0];
- socka.sa_data[1] = tmp_p[1];
- initIpAddress();
- memcpy((void *)&socka.sa_data[2], ipAddress, IPV4_LENGTH);
- return ;
- }
- int
- NetworkAddress::getPort () const
- {
- return aPort;
- }
- bool
- operator < ( const NetworkAddress & xAddress,
- const NetworkAddress & yAddress )
- {
- xAddress.initIpAddress();
- yAddress.initIpAddress();
- for (int i = 0 ; i <= IPV4_LENGTH; i++ )
- {
- if ( xAddress.ipAddress[i] < yAddress.ipAddress[i])
- {
- return true;
- }
- if ( xAddress.ipAddress[i] > yAddress.ipAddress[i])
- {
- return false;
- }
- }
- return xAddress.aPort < yAddress.aPort ;
- }
- bool
- operator == ( const NetworkAddress & xAddress,
- const NetworkAddress & yAddress )
- {
- xAddress.initIpAddress();
- yAddress.initIpAddress();
- for (int i = 0 ; i < IPV4_LENGTH ; i++ )
- {
- if ( xAddress.ipAddress[i] != yAddress.ipAddress[i])
- {
- return false;
- }
- }
- return xAddress.aPort == yAddress.aPort ;
- }
- bool
- operator != ( const NetworkAddress & xAddress,
- const NetworkAddress & yAddress )
- {
- return !(xAddress == yAddress);
- }
- NetworkAddress&
- NetworkAddress::operator=( const NetworkAddress& x )
- {
- this->aPort = x.aPort;
- memcpy( this->ipAddress, x.ipAddress, sizeof(this->ipAddress) );
- ipAddressSet = x.ipAddressSet;
- rawHostName = x.rawHostName;
- hostName = x.hostName;
-
- // strncpy( this->ipAddress, x.ipAddress, IPV4_LENGTH );
- return ( *this );
- }
- NetworkAddress::operator string ()
- {
- string xStr;
- strstream xStream;
- xStream << (*this) << ends;
- xStr = xStream.str();
- xStream.freeze(false);
- return xStr;
- }
- ostream &
- NetworkAddress::print ( ostream & xStr ) const
- {
- initIpAddress();
- char buffer[1024];
- const char* cpBuf=inet_ntop(AF_INET, &ipAddress, buffer, sizeof(buffer));
- xStr << hostName << "(" << cpBuf << ")";
-
- if ( aPort )
- {
- xStr << ":" << aPort;
- }
- return xStr;
- }
- u_int32_t
- NetworkAddress::hashIpPort( )
- {
- u_int32_t ipAddressLocal = getIp4Address ();
- int port = getPort ();
- return (hashIpPort( ipAddressLocal, port )) ;
- }
- u_int32_t
- NetworkAddress::hashIpPort( const string& hostname, const string& port )
- {
- NetworkAddress net;
- net.setHostName ( hostname );
- net.setPort ( atoi(port.c_str()) );
-
- return ( net.hashIpPort() );
- }
- u_int32_t
- NetworkAddress::hashIpPort( const u_int32_t ipAddress, const int port )
- {
- u_int32_t hashKey = 0x0;
- hashKey = (ipAddress << 16) | (port & 0xFF);
- return hashKey;
- }
- void
- NetworkAddress::initIpAddress() const
- {
- if(!ipAddressSet)
- {
- if (true == is_valid_ip_addr(rawHostName) )
- {
- hostName = rawHostName;
- ipAddressSet = true;
- }
- else
- {
- struct hostent hostbuf, *hp;
- size_t hstbuflen;
- char *tmphstbuf;
- int res=0;
- int herr;
-
-
- #if defined(__linux__)
- hstbuflen = 1024;
- tmphstbuf = (char*)malloc (hstbuflen);
- while ((res = gethostbyname_r (rawHostName.c_str(), &hostbuf, tmphstbuf, hstbuflen, &hp, &herr)) == ERANGE)
- {
- /* Enlarge the buffer. */
- hstbuflen *= 2;
- tmphstbuf = (char*)realloc (tmphstbuf, hstbuflen);
- }
- #else
- hstbuflen = 4024;
- tmphstbuf = (char*)malloc (hstbuflen);
- hp = gethostbyname_r (rawHostName.c_str(), &hostbuf, tmphstbuf, hstbuflen, &herr);
- #endif
-
- /* Check for errors. */
- if (res == 0 && hp)
- {
- memcpy((void *)&ipAddress,(void *)hp->h_addr,hp->h_length);
- hostName = hp->h_name;
- ipAddressSet = true;
- free(tmphstbuf);
- }
- else
- {
- cpLog (LOG_ERR, "Could not resolve Address for (%s)", rawHostName.c_str());
- }
- }
- }
- }
- NetworkAddress::NetworkAddress( const NetworkAddress& x)
- {
- aPort = x.aPort;
- ipAddressSet = x.ipAddressSet;
- rawHostName = x.rawHostName;
- hostName = x.hostName;
- memcpy( ipAddress, x.ipAddress, sizeof(ipAddress) );
- }
- int
- NetworkAddress::getHostByName(const char* hostName,
- struct hostent* hEnt,
- char* buf,
- int buflen,
- int* thrErrno)
- {
- #if defined(__linux__)
- struct hostent* x;
- int retval = gethostbyname_r(hostName, hEnt, buf, buflen, &x, thrErrno);
- if (retval == 0)
- return getHostLookupOK;
- cpLog(LOG_DEBUG, "********* Failed to get host by name:%s", hostName);
- return getHostLookupFailed;
- #else
- #if defined(__svr4__) || defined(__FreeBSD__)|| defined (__SUNPRO_CC)
- struct hostent* x;
- x = gethostbyname_r(hostName, hEnt, buf, buflen, thrErrno);
- if (x == 0)
- {
- cpLog(LOG_DEBUG, "********* Failed to get host by name:%s", hostName);
- return getHostLookupFailed;
- }
- return getHostLookupOK;
- #else
- #if defined (WIN32)
- struct hostent* x;
-
- x = gethostbyname(hostName);
- if (x == 0)
- {
- cpLog(LOG_DEBUG, "********* Failed to get host by name:%s", hostName);
- return getHostLookupFailed;
- }
- *hEnt = *x;
- return getHostLookupOK;
-
- #else
- #error no implementation for critical function
- #endif
- #endif
- #endif
- }
- #if defined (WIN32)
- struct hostent FAR *_gethostbyname( const char FAR *hostName )
- {
- struct hostent* x;
- #undef gethostbyname
- x = gethostbyname(hostName);
- if (x == 0)
- {
- int address = inet_addr(hostName);
- if( address != 0xFFFFFFFF )
- {
- // Tried gethostbyaddr, but it did not seem to work...
- // x = gethostbyaddr((char *)&address, IPV4_LENGTH, AF_INET);
- if (x == 0)
- {
- struct hostentex
- : hostent
- {
- char FAR * hex_aliases;
- char hex_alias;
- char FAR * hex_addr_list;
- char hex_addr[IPV4_LENGTH];
- char hex_name[IPV4_LENGTH * 4];
- };
- static struct hostentex entex;
- entex.h_name = entex.hex_name;
- entex.h_aliases = & entex.hex_aliases;
- entex.h_addrtype = AF_INET;
- entex.h_length = IPV4_LENGTH;
- entex.h_addr_list = & entex.hex_addr_list;
- entex.hex_aliases = & entex.hex_alias;
- entex.hex_alias = ' ';
- entex.hex_addr_list = & entex.hex_addr[0];
- memcpy((void *)entex.hex_addr, (void*)& address, IPV4_LENGTH);
- strcpy(entex.hex_name, hostName);
- x = & entex;
- }
- }
- }
- return x;
- }
- #endif
- /**
- * Return TRUE if the address is a valid IP address (dot-decimal form)
- * such as 128.128.128.128. Checks for invalid or ill formed addresses
- * If the address is valid, copy it into ipAddress
- */
- bool
- NetworkAddress::is_valid_ip_addr(const string& addr) const
- {
- #ifdef WIN32
- typedef ULONG ulong;
- #endif
- unsigned long maskcheck = ~255; // mask to check if 'tween 0 and 255
- const char *advancer = addr.c_str();
- unsigned long octet;
- char *nextchar;
- // always check for spaces and right number
- // first and last fields must be 1-255, middle two 0-255
-
- if ((*(advancer) == 0) || (*(advancer) == ' ') || (*(advancer) == 't'))
- {
- return false;
- }
- octet = strtoul(advancer, &nextchar, 10);
- if((*nextchar != '.') || (octet & maskcheck) || (octet == 0))
- {
- return false;
- }
- ipAddress[0] = octet;
- advancer = nextchar+1;
- if ((*(advancer) == 0) || (*(advancer) == ' ') || (*(advancer) == 't'))
- {
- return false;
- }
- octet = strtoul(advancer, &nextchar, 10);
- if((*nextchar != '.') || (octet & maskcheck))
- {
- return false;
- }
- ipAddress[1] = octet;
- advancer = nextchar+1;
- if ((*(advancer) == 0) || (*(advancer) == ' ') || (*(advancer) == 't'))
- {
- return false;
- }
- octet = strtoul(advancer, &nextchar, 10);
- if((*nextchar != '.') || (octet & maskcheck))
- {
- return false;
- }
- ipAddress[2] = octet;
-
- advancer = nextchar+1;
- if ((*(advancer) == 0) || (*(advancer) == ' ') || (*(advancer) == 't'))
- {
- return false;
- }
- octet = strtoul(advancer, &nextchar, 10);
- if((*nextchar) || (octet & maskcheck) || (octet == 0))
- {
- return false;
- }
- ipAddress[3] = octet;
-
- return true;
- }
- // End of File