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 + -
显示快捷键?