ksockaddr.cpp

来自「konqueror3 embedded版本, KDE环境下的当家浏览器的嵌入式版」· C++ 代码 · 共 895 行 · 第 1/2 页

CPP
895
字号
/* *  This file is part of the KDE libraries *  Copyright (C) 2000-2002 Thiago Macieira <thiago.macieira@kdemail.net> * *  This library is free software; you can redistribute it and/or *  modify it under the terms of the GNU Library General Public *  License as published by the Free Software Foundation; either *  version 2 of the License, or (at your option) any later version. * *  This library is distributed in the hope that it will be useful, *  but WITHOUT ANY WARRANTY; without even the implied warranty of *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU *  Library General Public License for more details. * *  You should have received a copy of the GNU Library General Public License *  along with this library; see the file COPYING.LIB.  If not, write to *  the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, *  Boston, MA 02110-1301, USA. **/#include "ksockaddr.h"#include <config.h>#include <sys/types.h>#ifdef Q_OS_UNIX#include <arpa/inet.h>#endif#include <netinet/in.h>#include <limits.h>#include <stdlib.h>#include <string.h>#include <sys/un.h>#include <unistd.h>#include <qglobal.h>#include <qfile.h>#include "kdebug.h"#include "klocale.h"//#include "kextsock.h"#ifndef HAVE_STRUCT_SOCKADDR_IN6// The system doesn't have sockaddr_in6// But we can tell netsupp.h to define it for us, according to the RFC#define CLOBBER_IN6#endif#include "netsupp.h"#define V6_CAN_CONVERT_TO_V4(addr)	(KDE_IN6_IS_ADDR_V4MAPPED(addr) || KDE_IN6_IS_ADDR_V4COMPAT(addr))#ifdef HAVE_STRUCT_SOCKADDR_SA_LEN# define MY_MAX(a, b)  			((a) > (b) ? (a) : (b))# define MIN_SOCKADDR_LEN		MY_MAX(offsetof(sockaddr, sa_family) + sizeof(((sockaddr*)0)->sa_family), \					       offsetof(sockaddr, sa_len) + sizeof(((sockaddr*)0)->sa_len))#else# define MIN_SOCKADDR_LEN		(offsetof(sockaddr, sa_family) + sizeof(((sockaddr*)0)->sa_family))#endif// Minimum size accepted for sockaddr_in6 sockets. // The scopeid field is missing from some implementations// that conform to the obsoleted RFC 2133, e.g. Linux glibc 2.1#define	MIN_SOCKADDR_IN6_LEN		(offsetof(sockaddr_in6, sin6_addr) + sizeof(((sockaddr_in6*)0)->sin6_addr))#ifdef offsetof#undef offsetof#endif#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)// This is how it is// 46 == strlen("1234:5678:9abc:def0:1234:5678:255.255.255.255")#ifndef INET6_ADDRSTRLEN#define INET6_ADDRSTRLEN		46#endif/** * Class KSocketAddress */KSocketAddress::KSocketAddress(const sockaddr* sa, ksocklen_t size){    if ( !sa )        init();    else {        data = (sockaddr*)malloc(size);        if (data == NULL)            return;        memcpy(data, sa, size);        datasize = size;        owndata = true;    }}void KSocketAddress::init(){  data = NULL;  datasize = 0;  owndata = false;}KSocketAddress::~KSocketAddress(){  if (owndata && data != NULL)    free(data);}QString KSocketAddress::pretty() const{  return i18n("<unknown socket>");}int KSocketAddress::family() const{  if (data != NULL)    return data->sa_family;  return AF_UNSPEC;}// This creates a new KSocketAddress with given sockaddrKSocketAddress* KSocketAddress::newAddress(const struct sockaddr* sa, ksocklen_t size){  if (size == 0)    {      kdWarning() << "KSocketAddress::newAddress called with size = 0!\n";      return NULL;    }  // make sure we have the right stuff  if (size < MIN_SOCKADDR_LEN)    {      kdWarning() << "KSocketAddress::newAddress called with invalid size\n";      return NULL;    }  switch (sa->sa_family)    {    case AF_INET:      if (size >= sizeof(sockaddr_in))	return new KInetSocketAddress((const sockaddr_in*)sa, size);      return NULL;#ifdef AF_INET6    case AF_INET6:      if (size >= MIN_SOCKADDR_IN6_LEN)	return new KInetSocketAddress((const sockaddr_in6*)sa, size);      return NULL;#endif    case AF_UNIX:		// AF_LOCAL      return new KUnixSocketAddress((const sockaddr_un*)sa, size);    }  return new KSocketAddress(sa, size);}bool KSocketAddress::isEqual(const KSocketAddress& other) const{  switch(family())  {     case AF_INET:        return KInetSocketAddress::areEqualInet(*this, other, false);#ifdef AF_INET6     case AF_INET6:        return KInetSocketAddress::areEqualInet6(*this, other, false);#endif     case AF_UNIX: // AF_LOCAL        return KUnixSocketAddress::areEqualUnix(*this, other, false);  }  // This is not a known socket type  if (other.datasize != datasize)    return false;		// can't be equal  return memcmp(data, other.data, datasize) == 0;}bool KSocketAddress::isCoreEqual(const KSocketAddress& other) const{  switch(family())  {     case AF_INET:        return KInetSocketAddress::areEqualInet(*this, other, true);#ifdef AF_INET6     case AF_INET6:        return KInetSocketAddress::areEqualInet6(*this, other, true);#endif     case AF_UNIX: // AF_LOCAL        return KUnixSocketAddress::areEqualUnix(*this, other, true);  }  return false;}QString KSocketAddress::nodeName() const{  return QString::null;}QString KSocketAddress::serviceName() const{  return QString::null;}int KSocketAddress::ianaFamily(int af){  switch (af)    {    case AF_INET:      return 1;#ifdef AF_INET6    case AF_INET6:      return 2;#endif    default:      return 0;    }}int KSocketAddress::fromIanaFamily(int iana){  switch (iana)    {    case 1:      return AF_INET;#ifdef AF_INET6    case 2:      return AF_INET6;#endif    default:      return AF_UNSPEC;    }}/** * class KInetSocketAddress */class KInetSocketAddressPrivate{public:  int sockfamily;  sockaddr_in sin;#ifdef AF_INET6  sockaddr_in6 sin6;#endif  KInetSocketAddressPrivate() :    sockfamily(AF_UNSPEC)  {    sin.sin_family = AF_INET;    sin.sin_port = 0;#ifdef HAVE_STRUCT_SOCKADDR_SA_LEN    sin.sin_len = sizeof(sin);#endif#ifdef AF_INET6    sin6.sin6_family = AF_INET6;    sin6.sin6_port = 0;    sin6.sin6_flowinfo = 0;# ifdef HAVE_STRUCT_SOCKADDR_IN6_SIN6_SCOPE_ID    sin6.sin6_scope_id = 0;# endif# ifdef HAVE_STRUCT_SOCKADDR_SA_LEN    sin6.sin6_len = sizeof(sin6);# endif#endif  }};KInetSocketAddress::KInetSocketAddress() :  d(new KInetSocketAddressPrivate){}KInetSocketAddress::KInetSocketAddress(const KInetSocketAddress &other) :  KSocketAddress(), d(new KInetSocketAddressPrivate){  setAddress(other);}KInetSocketAddress::KInetSocketAddress(const sockaddr_in* sin, ksocklen_t len) :  d(new KInetSocketAddressPrivate){  setAddress(sin, len);}KInetSocketAddress::KInetSocketAddress(const sockaddr_in6* sin6, ksocklen_t len) :  d(new KInetSocketAddressPrivate){  setAddress(sin6, len);}KInetSocketAddress::KInetSocketAddress(const in_addr& addr, unsigned short port) :  d(new KInetSocketAddressPrivate){  setAddress(addr, port);}KInetSocketAddress::KInetSocketAddress(const in6_addr& addr, unsigned short port) :  d(new KInetSocketAddressPrivate){  setAddress(addr, port);}KInetSocketAddress::KInetSocketAddress(const QString& addr, unsigned short port, int family) :  d(new KInetSocketAddressPrivate){  setAddress(addr, port, family);}KInetSocketAddress::~KInetSocketAddress(){  delete d;  //  KSocketAddress::~KSocketAddress();}bool KInetSocketAddress::setAddress(const KInetSocketAddress &other){  if (other.family() == AF_INET)    return setAddress(other.addressV4(), other.size());#ifdef AF_INET6  else if (other.family() == AF_INET6)    return setAddress(other.addressV6(), other.size());#endif  return false;}bool KInetSocketAddress::setAddress(const sockaddr_in* sin, ksocklen_t len){  // This is supposed to be a AF_INET socket  if ((len < sizeof(sockaddr_in)) || (sin->sin_family != AF_INET))    {      kdWarning() << "KInetSocketAddress::setAddress(sockaddr_in*) called with invalid sockaddr_in\n";      return false;    }  return setHost(sin->sin_addr) && setPort(ntohs(sin->sin_port));}bool KInetSocketAddress::setAddress(const sockaddr_in6* sin6, ksocklen_t len){#ifdef AF_INET6  // should be family AF_INET6  if ((len < MIN_SOCKADDR_IN6_LEN) || (sin6->sin6_family != AF_INET6))    {      kdWarning() << "KInetSocketAddress::setAddress(sockaddr_in6*) called with invalid sockaddr_in6\n";      return 0;    }  memset(&d->sin6, 0, sizeof(d->sin6));  if (len > sizeof(d->sin6))    len = sizeof(d->sin6);  memcpy(&d->sin6, sin6, len);  /* Now make a sanity check */  d->sockfamily = d->sin6.sin6_family = AF_INET6;# ifdef HAVE_STRUCT_SOCKADDR_SA_LEN  d->sin6.sin6_len = sizeof(d->sin6);# endif  fromV6();  return true;#else  // !AF_INET6  return false;#endif}bool KInetSocketAddress::setAddress(const in_addr& addr, unsigned short port){  return setHost(addr) && setPort(port);}bool KInetSocketAddress::setAddress(const in6_addr& addr, unsigned short port){  return setHost(addr) && setPort(port);}bool KInetSocketAddress::setAddress(const QString& addr, unsigned short port, int family){  return setHost(addr, family) && setPort(port);}bool KInetSocketAddress::setHost(const in_addr& addr){  d->sockfamily = AF_INET;	// set address to IPv4 type  d->sin.sin_addr = addr;  fromV4();  return true;}bool KInetSocketAddress::setHost(const in6_addr& addr){#ifdef AF_INET6  d->sockfamily = AF_INET6;	// set address to IPv6 type  d->sin6.sin6_addr = addr;  fromV6();  return true;#else  return false;#endif}bool KInetSocketAddress::setHost(const QString& addr, int family){  // if family == -1, we'll try to guess the host name  if ((family != -1) && (family != AF_INET)#ifdef AF_INET6      && (family != AF_INET6)#endif      )    {      kdWarning() << "KInetSocketAddress::setHost(QString, int) called with unknown family address\n";      return false;    }  if (family == -1)    {      // guess the family type#ifdef AF_INET6      // IPv6 addresses MUST contain colons (:) and IPv4 addresses must not      if (addr.find(':') != -1)	family = AF_INET6;      else	family = AF_INET;#else      // There's only one guess:      family = AF_INET;#endif    }  /*   * FIXME! What is the decoding process for hostnames?   */  if (family == AF_INET)    {      inet_pton(family, addr.latin1(), (void*)&(d->sin.sin_addr));      fromV4();    }#ifdef AF_INET6  else    {      inet_pton(family, addr.latin1(), (void*)&(d->sin6.sin6_addr));      fromV6();    }

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?