SWIipAddress.cpp
上传用户:xqtpzdz
上传日期:2022-05-21
资源大小:1764k
文件大小:15k
源码类别:

xml/soap/webservice

开发平台:

Visual C++

  1. /****************License************************************************
  2.  * Vocalocity OpenVXI
  3.  * Copyright (C) 2004-2005 by Vocalocity, Inc. All Rights Reserved.
  4.  * This program is free software; you can redistribute it and/or
  5.  * modify it under the terms of the GNU General Public License
  6.  * as published by the Free Software Foundation; either version 2
  7.  * of the License, or (at your option) any later version.
  8.  *  
  9.  * This program is distributed in the hope that it will be useful,
  10.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12.  * GNU General Public License for more details.
  13.  *
  14.  * You should have received a copy of the GNU General Public License
  15.  * along with this program; if not, write to the Free Software
  16.  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
  17.  * Vocalocity, the Vocalocity logo, and VocalOS are trademarks or 
  18.  * registered trademarks of Vocalocity, Inc. 
  19.  * OpenVXI is a trademark of Scansoft, Inc. and used under license 
  20.  * by Vocalocity.
  21.  ***********************************************************************/
  22. #include <string.h>
  23. #include "SWIipAddress.hpp"
  24. #ifdef _WIN32
  25. #include <winsock2.h>
  26. #else
  27. #include <netinet/in.h>
  28. #include <netdb.h>
  29. #include <arpa/inet.h>
  30. #include <stdlib.h>
  31. #include <errno.h>
  32. #include <unistd.h>
  33. #endif
  34. #if defined(WIN32) || defined(_decunix_)
  35. /* These OSes are thread safe by using thread local storage for the hostent */
  36. static int my_gethostbyaddr_r (const char * addr, socklen_t len,
  37.        int type,
  38.        struct hostent * result_buf,
  39.        char * buf, size_t buflen,
  40.        struct hostent ** result,
  41.        int * h_errnop) {
  42.   *result = gethostbyaddr(addr, len, type);
  43.   return (result ? 0 : -1);
  44. }
  45. static int my_gethostbyname_r (const char * name,
  46.        struct hostent * result_buf,
  47.        char * buf, size_t buflen,
  48.        struct hostent ** result,
  49.        int * h_errnop) {
  50.   *result = gethostbyname(name);
  51.   return (result ? 0 : -1);
  52. }
  53. #elif defined(_solaris_)
  54. static int my_gethostbyaddr_r (const char * addr, socklen_t len,
  55.        int type,
  56.        struct hostent * result_buf,
  57.        char * buf, size_t buflen,
  58.        struct hostent ** result,
  59.        int * h_errnop) {
  60.   *result = gethostbyaddr_r(addr, len, type, result_buf, buf, buflen,
  61.     h_errnop);
  62.   return (result ? 0 : -1);
  63. }
  64. static int my_gethostbyname_r (const char * name,
  65.        struct hostent * result_buf,
  66.        char * buf, size_t buflen,
  67.        struct hostent ** result,
  68.        int * h_errnop) {
  69.   *result = gethostbyname_r(name, result_buf, buf, buflen, h_errnop);
  70.   return (result ? 0 : -1);
  71. }
  72. #else
  73. /* Linux, maybe others */
  74. #define my_gethostbyaddr_r gethostbyaddr_r
  75. #define my_gethostbyname_r gethostbyname_r
  76. #endif
  77. #ifdef _WIN32
  78. // Class used for static initialization of mutex or WSA layer.
  79. class SWIipAddressInit
  80. {
  81.  public:
  82.   SWIipAddressInit();
  83.   ~SWIipAddressInit();
  84. };
  85. SWIipAddressInit::SWIipAddressInit()
  86. {
  87.   WSADATA wsaData;
  88.   WSAStartup(MAKEWORD(2, 2), &wsaData);
  89. }
  90. SWIipAddressInit::~SWIipAddressInit()
  91. {
  92.   WSACleanup();
  93. }
  94. static SWIipAddressInit G_netInit;
  95. #endif
  96. #define SOCK_ERROR(classname, msg) 
  97. do { 
  98.   if (_logger) 
  99.   { 
  100.     if (errno) 
  101.       _logger->Error(500, L"%s%S%s%S%s%S%s%d", L"class", classname, L"msg", msg, 
  102.   L"errnoStr", strerror(errno), L"errno", errno); 
  103.     else 
  104.       _logger->Error(500, L"%s%S%s%S", L"class", classname, L"msg", msg); 
  105.   } 
  106. } while(0)
  107. SWIipAddress::SWIipAddress(const SWIipAddress &sina)
  108. {
  109.   _logger         = sina._logger;
  110.   sin_family      = sina.sin_family;
  111.   sin_addr.s_addr = sina.sin_addr.s_addr;
  112.   sin_port   = sina.sin_port;
  113. }
  114. SWIipAddress::SWIipAddress(SWIutilLogger *logger)
  115. {
  116.   _logger =       logger;
  117.   sin_family   = AF_INET;
  118.   sin_addr.s_addr = htonl(INADDR_ANY);
  119.   sin_port   = 0;
  120. }
  121. SWIipAddress::SWIipAddress(unsigned long addr,
  122.    int port_no,
  123.                            SWIutilLogger *logger)
  124. {
  125. // addr and port_no are in host byte order
  126.   _logger         = logger;
  127.   sin_family      = AF_INET;
  128.   sin_addr.s_addr = htonl(addr);
  129.   sin_port   = htons(port_no);
  130. }
  131. SWIipAddress::SWIipAddress(unsigned long addr,
  132.    const char* sn,
  133.                            const char* pn,
  134.                            SWIutilLogger *logger)
  135. {
  136.   // addr is in host byte order
  137.   _logger         = logger;
  138.   sin_family      = AF_INET;
  139.   sin_addr.s_addr = htonl (addr);
  140.   setport(sn, pn);
  141. }
  142. SWIipAddress::SWIipAddress(const char* host_name,
  143.                            int port_no,
  144.                            SWIutilLogger *logger)
  145. {
  146. // port_no is in host byte order
  147.   _logger = logger;
  148.   sethostname(host_name);
  149.   sin_port = htons(port_no);
  150. }
  151. SWIipAddress::SWIipAddress(const char* hn,
  152.    const char* sn,
  153.                            const char* pn,
  154.                            SWIutilLogger *logger)
  155. {
  156.   _logger = logger;
  157.   sethostname(hn);
  158.   setport(sn, pn);
  159. }
  160. void SWIipAddress::setport(int port_no)
  161. {
  162.   sin_port = htons(port_no);
  163. }
  164. int SWIipAddress::setport(const char* sn, const char* pn)
  165. {
  166.   servent* sp = getservbyname(sn, pn);
  167.   if (sp == 0)
  168.   {
  169.     SOCK_ERROR("SWIipAddress", "invalid service name");
  170.     return -1;
  171.   }
  172.   sin_port = sp->s_port;
  173.   return 0;
  174. }
  175. int SWIipAddress::getport() const
  176. {
  177.   return ntohs (sin_port);
  178. }
  179. int SWIipAddress::sethostname(const char* host_name)
  180. {
  181.   if ( (sin_addr.s_addr = inet_addr(host_name)) == (in_addr_t) -1) {
  182.     int hostErrno;
  183.     struct hostent hostResult;
  184.     char hostBuffer[4096];
  185.     hostent* hp;
  186.     if ((my_gethostbyname_r(host_name, &hostResult, hostBuffer,
  187.     2048, &hp, &hostErrno) != 0) ||
  188. (hp == 0))
  189.     {
  190.       return -1;
  191.     }
  192.     memcpy(&sin_addr, hp->h_addr, hp->h_length);
  193.     sin_family = hp->h_addrtype;
  194.   }
  195.   else
  196.     sin_family = AF_INET;
  197.   return 0;
  198. }
  199. int SWIipAddress::gethostname(char *hostname, size_t hostnameLen) const
  200. {
  201.   hostname[0] = '';
  202.   if (sin_addr.s_addr == htonl(INADDR_ANY)) {
  203.     if (::gethostname(hostname, hostnameLen) == -1) {
  204.       SOCK_ERROR("SWIipAddress", "gethostname");
  205.       hostname[0] = '';
  206.       return -1;
  207.     }
  208.     return 0;
  209.   }
  210.   int hostErrno;
  211.   struct hostent hostResult;
  212.   char hostBuffer[4096];
  213.   hostent* hp;
  214.   if ((my_gethostbyaddr_r((const char*) &sin_addr, sizeof(sin_addr),
  215.   family(), &hostResult, hostBuffer, 2048, &hp,
  216.   &hostErrno) != 0) ||
  217.       (hp == 0))
  218.   {
  219.     SWIipAddress::herror("gethostbyaddr");
  220.     return -1;
  221.   }
  222.   if ((hp->h_name) && (strlen(hp->h_name) < hostnameLen)) {
  223.     strcpy (hostname, hp->h_name);
  224.     return 0;
  225.   }
  226.   return -1;
  227. }
  228. unsigned int SWIipAddress::hashCode() const
  229. {
  230.   unsigned int h = (unsigned int) ntohl(sin_addr.s_addr);
  231.   h <<= 16;
  232.   h |= ntohs(sin_port) & 0xFF;
  233.   return h;
  234. }
  235. bool SWIipAddress::operator==(const SWIipAddress& rhs) const
  236. {
  237.   if (this == &rhs) return true;
  238.   return sin_addr.s_addr == rhs.sin_addr.s_addr &&
  239.     sin_port == rhs.sin_port;
  240. }
  241. SWIHashable *SWIipAddress::clone() const
  242. {
  243.   return new SWIipAddress(*this);
  244. }
  245. bool SWIipAddress::equals(const SWIHashable *rhs) const
  246. {
  247.   return operator==(*((const SWIipAddress *) rhs));
  248. }
  249. #ifdef _WIN32
  250. static char* errmsg[] = {
  251.   "No error",
  252.   "Host not found",
  253.   "Try again",
  254.   "No recovery",
  255.   "No address"
  256.   "Unknown error"
  257. };
  258. /* Winsock.h maps h_errno to WSAGetLastError() function call */
  259. void SWIipAddress::herror(const char* em) const
  260. {
  261.   int err;
  262.   switch(h_errno) { /* calls WSAGetLastError() */
  263.    case HOST_NOT_FOUND:
  264.      err = 1;
  265.      break;
  266.    case TRY_AGAIN:
  267.      err = 2;
  268.      break;
  269.    case NO_RECOVERY:
  270.      err = 3;
  271.      break;
  272.    case NO_ADDRESS:
  273.      err = 4;
  274.      break;
  275.    default:
  276.      err = 5;
  277.      break;
  278.   }
  279.   SOCK_ERROR(em, errmsg[err]);
  280. }
  281. #else // !_WIN32
  282. /* Use the native UNIX call */
  283. void SWIipAddress::herror(const char* em) const
  284. {
  285. #ifdef _decunix_
  286.   if (_logger)
  287.   {
  288.     if (errno)
  289.       Error(500, L"%s%S%s%d%s%S%s%d", L"class", em, L"h_errno", h_errno,
  290.             L"errnoStr", strerror(errno), L"errno", errno);
  291.     else
  292.       Error(500, L"%s%S%s%d", L"class", em, L"h_errno", h_errno);
  293.   }
  294. #else
  295.   SOCK_ERROR(em, hstrerror(h_errno));
  296. #endif
  297. }
  298. #endif // !_WIN32
  299. #if 0
  300. SWIipAddress::SWIipAddress (int port)
  301.    : ipAddressSet(false)
  302. {
  303.   char *localHost = "localhost";
  304.   sethostname(localHost); // assuming it is localhost first
  305.   aPort = port;
  306. }
  307. SWIipAddress::SWIipAddress ( const char * hostName, int port)
  308.   : ipAddressSet(false)
  309. {
  310.   setport(port);
  311.   setHostName(hostName);
  312. }
  313. int SWIipAddress::setHostName ( const char * theAddress)
  314. {
  315.   //
  316.   // Look for semicolon which means the port address is appended
  317.   //
  318.   int colonPos = -1;
  319.   const char * cstrAddress = theAddress;
  320.   while (*cstrAddress)
  321.   {
  322.     if (*cstrAddress == ':')
  323.     {
  324.       colonPos = cstrAddress - theAddress;
  325.       break;
  326.     }
  327.     cstrAddress++;
  328.   }
  329.   //
  330.   // Found the port address so get it
  331.   //
  332.   if (colonPos != -1)
  333.   {
  334.     aPort = atoi(theAddress + (colonPos + 1));
  335.     if (aPort)
  336.     {
  337.       strncpy(rawHostName, theAddress, colonPos - 1);
  338.       rawHostName[colonPos] = '';
  339.     }
  340.     else
  341.     {
  342.       return -1;
  343.     }
  344.   }
  345.   else // No ':' in input string;
  346.   {
  347.     strcpy(rawHostName,theAddress);
  348.   }
  349.   ipAddressSet = false;
  350.   return 0;
  351. }
  352. void SWIipAddress::setport( int iPort )
  353. {
  354.     ipAddressSet = false;
  355.     aPort = iPort;
  356. }
  357. char * SWIipAddress::getHostName( ) const
  358. {
  359.   char * hostName;
  360.   struct hostent * pxHostEnt = NULL;
  361.   initIpAddress();
  362.   if ((my_gethostbyaddr_r(
  363.   {
  364.   }
  365.   LOCK();
  366.   pxHostEnt = gethostbyaddr(ipAddress, IPV4_LENGTH, AF_INET);
  367.   if (pxHostEnt)
  368.   {
  369.     hostName = pxHostEnt->h_name;
  370.     UNLOCK();
  371.   }
  372.   else
  373.   {
  374.     UNLOCK();
  375.     hostName = getIpName();
  376.   }
  377.   return hostName;
  378. }
  379. char * SWIipAddress::getIpName () const
  380. {
  381.     char * ipName;
  382.     struct in_addr temp;
  383.     initIpAddress();
  384.     memcpy((void *)&temp.s_addr, ipAddress, IPV4_LENGTH);
  385.     LOCK();
  386.     // $$$ This returns a pointer to a static char[]
  387.     ipName = inet_ntoa(temp);
  388.     UNLOCK();
  389.     return ipName;
  390. }
  391. unsigned int SWIipAddress::getIp4Address () const
  392. {
  393.     unsigned lTmp;
  394.     initIpAddress();
  395.     memcpy((void *) &lTmp, ipAddress, IPV4_LENGTH);
  396.     return lTmp;
  397. }
  398. void SWIipAddress::getSockAddr (struct sockaddr & socka) const
  399. {
  400.     short tmp_s = htons (aPort);
  401.     char * tmp_p;
  402.     tmp_p = (char*) &tmp_s;
  403.     socka.sa_family = AF_INET;
  404.     socka.sa_data[0] = tmp_p[0];
  405.     socka.sa_data[1] = tmp_p[1];
  406.     initIpAddress();
  407.     memcpy((void *)&socka.sa_data[2], ipAddress, IPV4_LENGTH);
  408.     return ;
  409. }
  410. int SWIipAddress::getPort () const
  411. {
  412.     return aPort;
  413. }
  414. bool operator < ( const SWIipAddress & xAddress, const SWIipAddress & yAddress )
  415. {
  416.     xAddress.initIpAddress();
  417.     yAddress.initIpAddress();
  418.     for (int i = 0 ; i <= IPV4_LENGTH; i++ )
  419.     {
  420.         if ( xAddress.ipAddress[i] < yAddress.ipAddress[i])
  421.         {
  422.             return true;
  423.         }
  424.         if ( xAddress.ipAddress[i] > yAddress.ipAddress[i])
  425.         {
  426.             return false;
  427.         }
  428.     }
  429.     return xAddress.aPort < yAddress.aPort ;
  430. }
  431. bool operator == ( const SWIipAddress & xAddress, const SWIipAddress & yAddress )
  432. {
  433.     xAddress.initIpAddress();
  434.     yAddress.initIpAddress();
  435.     for (int i = 0 ; i < IPV4_LENGTH ; i++ )
  436.     {
  437.         if ( xAddress.ipAddress[i] != yAddress.ipAddress[i])
  438.         {
  439.             return false;
  440.         }
  441.     }
  442.     return xAddress.aPort == yAddress.aPort ;
  443. }
  444. bool operator != ( const SWIipAddress & xAddress, const SWIipAddress & yAddress )
  445. {
  446.     return !(xAddress == yAddress);
  447. }
  448. SWIipAddress & SWIipAddress::operator=( const SWIipAddress& x )
  449. {
  450.     this->aPort = x.aPort;
  451.     memcpy( this->ipAddress, x.ipAddress, sizeof(this->ipAddress) );
  452.     ipAddressSet = x.ipAddressSet;
  453.     memcpy(this->rawHostName, x.rawHostName, sizeof(this->rawHostName));
  454.     // xraf rawHostName = x.rawHostName;
  455.     //   strncpy( this->ipAddress, x.ipAddress, IPV4_LENGTH );
  456.     return ( *this );
  457. }
  458. unsigned int SWIipAddress::hashIpPort( )
  459. {
  460.     unsigned int ipAddressLocal = getIp4Address ();
  461.     int port = getPort ();
  462.     return (hashIpPort( ipAddressLocal, port )) ;
  463. }
  464. unsigned int SWIipAddress::hashIpPort( const char * theAddress, const char * port )
  465. {
  466.     SWIipAddress net;
  467.     net.setHostName ( theAddress );
  468.     net.setport ( atoi(port) );
  469.     return ( net.hashIpPort() );
  470. }
  471. unsigned int SWIipAddress::hashIpPort( const unsigned int ipAddress, const int port )
  472. {
  473.     unsigned int hashKey = 0x0;
  474.     hashKey = (ipAddress << 16) | (port & 0xFF);
  475.     return hashKey;
  476. }
  477. int SWIipAddress::initIpAddress() const
  478. {
  479.   int status = 0;
  480.   if (!ipAddressSet)
  481.   {
  482.     if (is_valid_ip_addr(rawHostName) )
  483.     {
  484.       ipAddressSet = true;
  485.     }
  486.     else
  487.     {
  488.       LOCK();
  489.       struct hostent * pxHostEnt = 0;
  490.       pxHostEnt = gethostbyname(rawHostName);
  491.       if (pxHostEnt)
  492.       {
  493.         memcpy((void *)&ipAddress,
  494.                (void *)pxHostEnt->h_addr,
  495.                pxHostEnt->h_length);
  496.         ipAddressSet = true;
  497.       }
  498.       else
  499.       {
  500.         status = -1;
  501.       }
  502.       UNLOCK();
  503.     }
  504.   }
  505.   return status;
  506. }
  507. /**
  508.   * Return TRUE if the address is a valid IP address (dot-decimal form)
  509.   * such as 128.128.128.128. Checks for invalid or ill formed addresses
  510.   * If the address is valid, copy it into ipAddress
  511.   */
  512. bool SWIipAddress::is_valid_ip_addr(const char * addr) const
  513. {
  514.     unsigned long maskcheck = ~255; // mask to check if 'tween 0 and 255
  515.     const char *advancer = addr;
  516.     unsigned long octet;
  517.     char *nextchar;
  518.     // always check for spaces and right number
  519.     // first and last fields must be 1-255, middle two 0-255
  520.     if ((*(advancer) == 0) || (*(advancer) == ' ') || (*(advancer) == 't'))
  521.     {
  522.         return false;
  523.     }
  524.     octet = strtoul(advancer, &nextchar, 10);
  525.     if((*nextchar != '.') || (octet & maskcheck) || (octet == 0))
  526.     {
  527.         return false;
  528.     }
  529.     ipAddress[0] = (char) octet;
  530.     advancer = nextchar+1;
  531.     if ((*(advancer) == 0) || (*(advancer) == ' ') || (*(advancer) == 't'))
  532.     {
  533.         return false;
  534.     }
  535.     octet = strtoul(advancer, &nextchar, 10);
  536.     if((*nextchar != '.') || (octet & maskcheck))
  537.     {
  538.         return false;
  539.     }
  540.     ipAddress[1] = (char) octet;
  541.     advancer = nextchar+1;
  542.     if ((*(advancer) == 0) || (*(advancer) == ' ') || (*(advancer) == 't'))
  543.     {
  544.         return false;
  545.     }
  546.     octet = strtoul(advancer, &nextchar, 10);
  547.     if((*nextchar != '.') || (octet & maskcheck))
  548.     {
  549.         return false;
  550.     }
  551.     ipAddress[2] = (char) octet;
  552.     advancer = nextchar+1;
  553.     if ((*(advancer) == 0) || (*(advancer) == ' ') || (*(advancer) == 't'))
  554.     {
  555.         return false;
  556.     }
  557.     octet = strtoul(advancer, &nextchar, 10);
  558.     if((*nextchar) || (octet & maskcheck) || (octet == 0))
  559.     {
  560.         return false;
  561.     }
  562.     ipAddress[3] = (char) octet;
  563.     return true;
  564. }
  565. #endif
  566. // End of File