/*
- * Copyright (C) 1996-2014 The Squid Software Foundation and contributors
+ * Copyright (C) 1996-2021 The Squid Software Foundation and contributors
*
* Squid software is distributed under GPLv2+ license and includes
* contributions from numerous individuals and organizations.
continue ; /* A short-cut */
}
- for (caught = 0 , bit= 7 ; !caught && (bit <= 7); --bit) {
+ for (caught = 0, bit= 7 ; !caught && (bit <= 7); --bit) {
caught = ((ipbyte & 0x80) == 0x00); /* Found a '0' at 'bit' ? */
if (!caught)
return changes;
}
+void
+Ip::Address::applyClientMask(const Address &mask)
+{
+ if (!isLocalhost() && isIPv4())
+ (void)applyMask(mask);
+}
+
bool
Ip::Address::applyMask(const unsigned int cidrMask, int mtype)
{
return IN6_IS_ADDR_UNSPECIFIED(&mSocketAddr_.sin6_addr) || IN6_ARE_ADDR_EQUAL(&mSocketAddr_.sin6_addr, &v4_anyaddr);
}
-/// NOTE: Does NOT clear the Port stored. Ony the Address and Type.
+/// NOTE: Does NOT clear the Port stored. Only the Address and Type.
void
Ip::Address::setAnyAddr()
{
return false;
}
-Ip::Address&
-Ip::Address::operator =(const Ip::Address &s)
-{
- memcpy(this, &s, sizeof(Ip::Address));
- return *this;
-};
-
Ip::Address::Address(const char*s)
{
setEmpty();
{
/* some AF_* magic to tell socket types apart and what we need to do */
if (s.ss_family == AF_INET6) {
- memcpy(&mSocketAddr_, &s, sizeof(struct sockaddr_in6));
+ memmove(&mSocketAddr_, &s, sizeof(struct sockaddr_in6));
} else { // convert it to our storage mapping.
struct sockaddr_in *sin = (struct sockaddr_in*)&s;
mSocketAddr_.sin6_port = sin->sin_port;
Ip::Address &
Ip::Address::operator =(struct sockaddr_in6 const &s)
{
- memcpy(&mSocketAddr_, &s, sizeof(struct sockaddr_in6));
-
+ memmove(&mSocketAddr_, &s, sizeof(struct sockaddr_in6));
return *this;
};
Ip::Address &
Ip::Address::operator =(struct in6_addr const &s)
{
-
- memcpy(&mSocketAddr_.sin6_addr, &s, sizeof(struct in6_addr));
+ memmove(&mSocketAddr_.sin6_addr, &s, sizeof(struct in6_addr));
mSocketAddr_.sin6_family = AF_INET6;
return *this;
};
-Ip::Address::Address(const Ip::Address &s)
-{
- setEmpty();
- operator=(s);
-}
-
Ip::Address::Address(const struct hostent &s)
{
setEmpty();
}
/* some external code may have blindly memset a parent. */
- /* thats okay, our default is known */
+ /* that's okay, our default is known */
if ( isAnyAddr() ) {
if (isIPv6())
memcpy(buf,"::\0", min(static_cast<unsigned int>(3),blen));
return buf;
}
+bool
+Ip::Address::fromHost(const char *host)
+{
+ setEmpty();
+
+ if (!host)
+ return false;
+
+ if (host[0] != '[')
+ return lookupHostIP(host, true); // no brackets
+
+ /* unwrap a bracketed [presumably IPv6] address, presumably without port */
+
+ const char *start = host + 1;
+ if (!*start)
+ return false; // missing address after an opening bracket
+
+ // XXX: Check that there is a closing bracket and no trailing garbage.
+
+ char *tmp = xstrdup(start); // XXX: Slow. TODO: Bail on huge strings and use an on-stack buffer.
+ tmp[strlen(tmp)-1] = '\0'; // XXX: Wasteful: xstrdup() just did strlen().
+ const bool result = lookupHostIP(tmp, true);
+ xfree(tmp);
+ return result;
+}
+
void
Ip::Address::getSockAddr(struct sockaddr_storage &addr, const int family) const
{
struct sockaddr_in *sin = NULL;
if ( family == AF_INET && !isIPv4()) {
- // FIXME INET6: caller using the wrong socket type!
+ // TODO INET6: caller using the wrong socket type!
debugs(14, DBG_CRITICAL, HERE << "Ip::Address::getSockAddr : Cannot convert non-IPv4 to IPv4. from " << *this);
assert(false);
}
void
Ip::Address::getSockAddr(struct sockaddr_in6 &buf) const
{
- memcpy(&buf, &mSocketAddr_, sizeof(struct sockaddr_in6));
+ memmove(&buf, &mSocketAddr_, sizeof(struct sockaddr_in6));
/* maintain address family. It may have changed inside us. */
buf.sin6_family = AF_INET6;
void
Ip::Address::getInAddr(struct in6_addr &buf) const
{
- memcpy(&buf, &mSocketAddr_.sin6_addr, sizeof(struct in6_addr));
+ memmove(&buf, &mSocketAddr_.sin6_addr, sizeof(struct in6_addr));
}
bool