]> git.ipfire.org Git - thirdparty/squid.git/blobdiff - src/ip/Address.cc
Source Format Enforcement (#763)
[thirdparty/squid.git] / src / ip / Address.cc
index 59942d1151c48297cffd6aa0ceec9190638f672c..95aa7323d5741bb7f18c4883d3c9812c5b83ead2 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * 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.
@@ -67,7 +67,7 @@ Ip::Address::cidr() const
             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)
@@ -101,6 +101,13 @@ Ip::Address::applyMask(Ip::Address const &mask_addr)
     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)
 {
@@ -165,7 +172,7 @@ Ip::Address::isAnyAddr() const
     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()
 {
@@ -349,13 +356,6 @@ Ip::Address::getReverseString(char buf[MAX_IPSTRLEN], int show_type) const
     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();
@@ -440,7 +440,7 @@ Ip::Address::operator =(const struct sockaddr_storage &s)
 {
     /* 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;
@@ -458,8 +458,7 @@ Ip::Address::Address(struct sockaddr_in6 const &s)
 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;
 };
 
@@ -486,19 +485,12 @@ Ip::Address::Address(struct in6_addr const &s)
 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();
@@ -815,7 +807,7 @@ Ip::Address::toStr(char* buf, const unsigned int blen, int force) const
     }
 
     /* 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));
@@ -912,13 +904,39 @@ Ip::Address::toUrl(char* buf, unsigned int blen) const
     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);
     }
@@ -957,7 +975,7 @@ Ip::Address::getSockAddr(struct sockaddr_in &buf) const
 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;
 
@@ -1005,7 +1023,7 @@ Ip::Address::map6to4(const struct in6_addr &in, struct in_addr &out) const
 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