--------------------- PatchSet 4083 Date: 2007/03/05 11:27:00 Author: amosjeffries Branch: squid3-ipv6 Tag: (none) Log: Nothing like a good run-time test to bring out the bugs. Members: NOTES-IPv6:1.1.2.4->1.1.2.5 src/IPAddress.cc:1.1.2.5->1.1.2.6 src/IPAddress.h:1.1.2.5->1.1.2.6 Index: squid3/NOTES-IPv6 =================================================================== RCS file: /cvsroot/squid-sf//squid3/Attic/NOTES-IPv6,v retrieving revision 1.1.2.4 retrieving revision 1.1.2.5 diff -u -r1.1.2.4 -r1.1.2.5 --- squid3/NOTES-IPv6 4 Feb 2007 07:27:43 -0000 1.1.2.4 +++ squid3/NOTES-IPv6 5 Mar 2007 11:27:00 -0000 1.1.2.5 @@ -1,45 +1,16 @@ +$Id: NOTES-IPv6,v 1.1.2.5 2007/03/05 11:27:00 amosjeffries Exp $ -$Id: NOTES-IPv6,v 1.1.2.4 2007/02/04 07:27:43 amosjeffries Exp $ +TODO: -DONE: -1 Get the branch synchronised with recent updates to HEAD - - Thanks Henrik. - -2 Determin what the 'compile errors' mentioned by xuan were - - Found and fixed for "./configure && make" - -Feb 2007: The more I look at the existing code and the problems to be fixed - the more it appears that converting the in*_addr handling code to - full C++ instead of a mix of C structures will simplify the process - and reduce the amount of complexity to the branch. - Am thus in the process of spec'ing out an IPAddr class. - -Objective: - To produce a class that can seamlessly and invisibly handle - any protocol of IPA. - To have the ONLY code differences between --enable/disable-ipv6 - occur as: - - code blocks in IPAddr.cc (or virtual classes) - - where sockets are opened (explicit AF types?) - - other branch core files where IPv6 is non-compatible - (ie snmp, wccp) +1.0 Complete coding of IPAddress.cc (marked TODO or FIXME in comments) -TODO: +1.1 Migrate code to using IPAddress object over any other method of struct storage 2.1 Find and Fix Request Denied Error (due to DNS timeout) in IPv4 build. 2.2 Compile Errors: from "./configure --enable-ipv6 && make" - (see C++ notes above) - -3 Determin what plumbing in HEAD now obviates branch changes - -4 Determin what plumbing can still be passed up immediately to simplify - -5 ??? Create object to handle address manipulation actions -6 Update to Dual IPv6-IPv4 - not as hard as it seemed, prticularly after the C++ object upgrade - maybe do this as part of 3 and 4 +3 Determin what plumbing can still be passed up immediately to simplify -7 ??? +4 find more, bugs etc ??? Index: squid3/src/IPAddress.cc =================================================================== RCS file: /cvsroot/squid-sf//squid3/src/Attic/IPAddress.cc,v retrieving revision 1.1.2.5 retrieving revision 1.1.2.6 diff -u -r1.1.2.5 -r1.1.2.6 --- squid3/src/IPAddress.cc 4 Mar 2007 07:04:08 -0000 1.1.2.5 +++ squid3/src/IPAddress.cc 5 Mar 2007 11:27:01 -0000 1.1.2.6 @@ -1,7 +1,6 @@ /* - * $Id: IPAddress.cc,v 1.1.2.5 2007/03/04 07:04:08 amosjeffries Exp $ + * $Id: IPAddress.cc,v 1.1.2.6 2007/03/05 11:27:01 amosjeffries Exp $ */ -// #include "squid.h" #include "IPAddress.h" #include @@ -9,9 +8,8 @@ #include #include /* inet Macros */ #include /* inet_ntoa() */ -#include /* min() */ -#include "util.h" +// #include "util.h" /* enum IPAddressType { @@ -24,6 +22,11 @@ struct sockaddr m_SocketAddr; */ +IPAddress::IPAddress() +{ + memset(this,0,sizeof(IPAddress)); + m_Type = IPv64; +} IPAddress::~IPAddress() { if(m_cacheStringValue) delete m_cacheStringValue; @@ -31,7 +34,7 @@ } bool IPAddress::IsAnyAddr() { -#if INET6 +#ifdef INET6 return (0 == memcmp(&(m_SocketAddr.sin6_addr), &in6addr_any, sizeof(in6addr_any)) ); #else return (INADDR_ANY == m_SocketAddr.sin_addr.s_addr); @@ -39,90 +42,117 @@ } void IPAddress::SetAnyAddr() { -#if INET6 +#ifdef INET6 memcpy(&(m_SocketAddr.sin6_addr), &in6addr_any, sizeof(in6addr_any)); #else m_SocketAddr.sin_addr.s_addr = INADDR_ANY; #endif + m_Type = IPv64; } bool IPAddress::IsNoAddr() { // IFF the address = 0xffffffffff...fffff (all ones) -#if INET6 - return (0 == memcmp(&(m_SocketAddr.sin6_addr), &in6addr_none, sizeof(in6addr_any)) ); +#ifdef INET6 + return (0 == memcmp(&(m_SocketAddr.sin6_addr),&"\0xffffffff\0xffffffff\0xffffffff\0xffffffff", sizeof(in6addr_any))); #else return (0xFFFFFFFF == m_SocketAddr.sin_addr.s_addr); #endif } void IPAddress::SetNoAddr() { -#if INET6 - memset(&(m_SocketAddr.sin6_addr),255, sizeof(in6_addr)); +#ifdef INET6 + memset(&(m_SocketAddr.sin6_addr),255,sizeof(in6_addr)); #else m_SocketAddr.sin_addr.s_addr = 0xFFFFFFFF; #endif + m_Type = IPv64; } -#if INET6 -bool IPAddress::GetReverseString6(char buf[MAX_IPSTRLEN], struct in_addr &dat) +#ifdef INET6 +bool IPAddress::GetReverseString6(char buf[MAX_IPSTRLEN], struct in6_addr &dat) { - // FIXME: code. - assert(false); + char *p = buf; + unsigned char *r = dat.s6_addr; - return false; + /* RFC1886 says: */ + /* 4321:0:1:2:3:4:567:89ab */ + /* must be sent */ + /* b.a.9.8.7.6.5.0.4.0.0.0.3.0.0.0.2.0.0.0.1.0.0.0.0.0.0.0.1.2.3.4.ip6.int. */ + + /* Work from the binary field. Anything else may have representation changes. */ + /* The sin6_port and sin6_addr members shall be in network byte order. */ + + /* Compile Err: 'Too many arguments for format. */ + for(int i = 15; i >= 0; i--, p+=4) + { + snprintf(p, 5, "%x.%x.", (((r[i])>>4)&0xf), ((r[i])&0xf) ); + } + + /* RFC3152 says: */ + /* ip6.int is now deprecated TLD, use ip6.arpa instead. */ + snprintf(p,10,"ip6.arpa."); + + return true; } #endif bool IPAddress::GetReverseString4(char buf[MAX_IPSTRLEN], struct in_addr &dat) { - // FIXME: code it! - assert(false); - + unsigned int i = (unsigned int) ntohl(dat.s_addr); + snprintf(buf, 32, "%u.%u.%u.%u.in-addr.arpa.", + i & 255, + (i >> 8) & 255, + (i >> 16) & 255, + (i >> 24) & 255); return false; } bool IPAddress::GetReverseString(char buf[MAX_IPSTRLEN], IPAddressType show_type) { - void* ip4_ptr = NULL; -#if INET6 - void* ip6_ptr = NULL; + in_addr* ip4_ptr = NULL; +#ifdef INET6 + in6_addr* ip6_ptr = NULL; in6_addr tmp_buf; #endif if(m_Type == None) return false; -#if INET6 +#ifdef INET6 if(show_type == None) show_type = IPv6; #else if(show_type == None) show_type = IPv4; #endif - switch(m_Type && IPv64) // What we do depends on how we stored it. + switch(m_Type & IPv64) // What we do depends on how we stored it. { case IPv4: +#ifndef INET6 ip4_ptr = &m_SocketAddr.sin_addr; -#if INET6 /* otherwise we don't need to bother converting it. */ - ip6_ptr = tmp_buf; - Map4to6(ip4_ptr, ip6_ptr); +#else /* INET6 */ + ip4_ptr = (in_addr*)&m_SocketAddr.sin6_addr.s6_addr[12]; + ip6_ptr = &tmp_buf; + Map4to6(*ip4_ptr, *ip6_ptr); #endif break; -#if INET6 case IPv64: - ip4_ptr = &m_SocketAddr.sin6_addr.s6_addr32[3]); +#ifndef INET6 + ip4_ptr = &m_SocketAddr.sin_addr; +#else + ip4_ptr = (in_addr*)&m_SocketAddr.sin6_addr.s6_addr32[3]; // Fall through to setup IPv6 output ptr case IPv6: ip6_ptr = &m_SocketAddr.sin6_addr; - break; #endif + break; } if(show_type == IPv4 && ip4_ptr != NULL) { return GetReverseString4(buf, *(in_addr*)ip4_ptr); } -#if INET6 +#ifdef INET6 if(show_type == IPv6 && ip6_ptr != NULL) { return GetReverseString6(buf, *(in6_addr*)ip6_ptr); @@ -130,13 +160,16 @@ #endif /* FIXME: an error occured. invalid address type */ + // return an empty string for the buffer, and log an error + buf[0] = '\0'; + return false; } IPAddress::IPAddress(struct sockaddr_in const &s) { memset(this,0,sizeof(IPAddress)); -#if INET6 - Map4to6(&s.sin_addr, &m_SockAddr.sin6_addr); +#ifdef INET6 + Map4to6((const in_addr)s.sin_addr, m_SocketAddr.sin6_addr); m_SocketAddr.sin6_port = s.sin_port; m_SocketAddr.sin6_family = AF_INET6; m_Type=(IPAddressType)(IPv64 | SockAddr); @@ -146,8 +179,8 @@ #endif }; IPAddress& IPAddress::operator =(struct sockaddr_in const &s) { -#if INET6 - Map4to6(&s.sin_addr, &m_SockAddr.sin6_addr); +#ifdef INET6 + Map4to6((const in_addr)s.sin_addr, m_SocketAddr.sin6_addr); m_SocketAddr.sin6_port = s.sin_port; m_SocketAddr.sin6_family = AF_INET6; m_Type=(IPAddressType)(IPv64 | SockAddr); @@ -159,7 +192,7 @@ return *this; }; -#if INET6 +#ifdef INET6 IPAddress::IPAddress(sockaddr_in6 const &s) { memset(this,0,sizeof(IPAddress)); memcpy(&m_SocketAddr, &s, sizeof(struct sockaddr_in6)); @@ -187,8 +220,8 @@ IPAddress::IPAddress(in_addr const &s) { memset(this,0,sizeof(IPAddress)); -#if INET6 - Map4to6(&s, &m_SockAddr.sin6_addr)); +#ifdef INET6 + Map4to6((const in_addr)s, m_SocketAddr.sin6_addr); m_SocketAddr.sin6_port = 0; m_SocketAddr.sin6_family = AF_INET6; m_Type=IPv64; @@ -201,8 +234,8 @@ RebuildStringCache(); }; IPAddress& IPAddress::operator =(in_addr const &s) { -#if INET6 - Map4to6(&s, &m_SockAddr.sin6_addr)); +#ifdef INET6 + Map4to6((const in_addr)s, m_SocketAddr.sin6_addr); m_SocketAddr.sin6_port = 0; m_SocketAddr.sin6_family = AF_INET6; m_Type=IPv64; @@ -216,19 +249,19 @@ return *this; }; -#if INET6 +#ifdef INET6 IPAddress::IPAddress(struct in6_addr const &s) { memset(this,0,sizeof(IPAddress)); memcpy(&m_SocketAddr.sin6_addr, &s, sizeof(struct in6_addr)); m_SocketAddr.sin6_port = 0; - m_SocketAddr.sin6_famly = AF_INET6; + m_SocketAddr.sin6_family = AF_INET6; m_Type=IPv6; }; IPAddress& IPAddress::operator =(struct in6_addr const &s) { // FIXME: convert properly from in6_addr to the storage method. memcpy(&m_SocketAddr.sin6_addr, &s, sizeof(struct in6_addr)); m_SocketAddr.sin6_port = 0; - m_SocketAddr.sin6_famly = AF_INET6; + m_SocketAddr.sin6_family = AF_INET6; m_Type=IPv6; RebuildStringCache(); return *this; @@ -249,7 +282,7 @@ char buf[MAX_IPSTRLEN+1]; GetString(buf,MAX_IPSTRLEN+1); // Dump the Current [Address]:Port to the debug stream. -#if INET6 +#ifdef INET6 os << "[" << buf << "]:" << m_SocketAddr.sin6_port; #else os << buf << ":" << m_SocketAddr.sin_port; @@ -265,12 +298,20 @@ u_short IPAddress::GetPort() { - return ntohs( ((sockaddr_in)m_SocketAddr).sin_port ); +#ifdef INET6 + return ntohs( m_SocketAddr.sin6_port ); +#else + return ntohs( m_SocketAddr.sin_port ); +#endif } u_short IPAddress::SetPort(u_short prt) { - ((sockaddr_in)m_SocketAddr).sin_port = htons(prt); +#ifdef INET6 + m_SocketAddr.sin6_port = htons(prt); +#else + m_SocketAddr.sin_port = htons(prt); +#endif if(m_Type != None) m_Type = (IPAddressType)(m_Type | SockAddr); RebuildStringCache(); return prt; @@ -278,14 +319,37 @@ void IPAddress::RebuildStringCache() { - if(!m_cacheStringValue) + if(m_cacheStringValue == NULL) + { + m_cacheStringValue = new char[MAX_IPSTRLEN]; + memset(m_cacheStringValue,0,MAX_IPSTRLEN); + } +#ifdef INET6 + if(m_SocketAddr.sin6_port > 0) { - m_cacheStringValue = new char[MAX_IPSTRLEN]; + char t[MAX_IPSTRLEN]; + if(inet_ntop(AF_INET6, &m_SocketAddr.sin6_addr, t, MAX_IPSTRLEN )) + { + sprintf(m_cacheStringValue,"[%s]:%d",t, ntohs(m_SocketAddr.sin6_port) ); + } + } + else + { + inet_ntop(AF_INET6, &m_SocketAddr.sin6_addr, m_cacheStringValue, STRLEN_IP6A); } -#if INET6 - xstrncpy(m_cacheStringValue, inet6_ntoa(m_SocketAddr.sin6_addr), MAX_IPSTRLEN); #else - xstrncpy(m_cacheStringValue, inet_ntoa(m_SocketAddr.sin_addr), MAX_IPSTRLEN); + if(m_SocketAddr.sin_port > 0) + { + char t[MAX_IPSTRLEN]; + if(inet_ntop(AF_INET6, &m_SocketAddr.sin6_addr, t, MAX_IPSTRLEN)) + { + sprintf(m_cacheStringValue,"%s:%d",t, ntohs(m_SocketAddr.sin_port) ); + } + } + else + { + xstrncpy(m_cacheStringValue, inet_ntoa(m_SocketAddr.sin_addr), STRLEN_IP4A); + } #endif } const char* IPAddress::NtoA() @@ -309,13 +373,13 @@ void IPAddress::GetSockAddr(struct sockaddr_in &buf) { -#if INET6 +#ifdef INET6 // FIXME: Hmm, how to convert down?? if(m_Type & IPv4) // if can be converted down. { buf.sin_family = AF_INET; buf.sin_port = m_SocketAddr.sin6_port; - memcpy(&buf.sin_addr, &m_SocketAddr.sin6_addr.s6_addr32[3], sizeof(uint32)); + memcpy(&buf.sin_addr, &m_SocketAddr.sin6_addr.s6_addr32[3], sizeof(uint32_t) ); } else // no conversion. set it to NO_ADDRESS instead { @@ -326,55 +390,46 @@ #endif } -#if INET6 +#ifdef INET6 void IPAddress::GetSockAddr(struct sockaddr_in6 &buf) { - memcpy(&buf, &m_SockAddr, sizeof(struct sockaddr_in6)); + memcpy(&buf, &m_SocketAddr, sizeof(struct sockaddr_in6)); } #endif -#if INET6 -void IPAddress::Map4to6(struct in_addr &in, struct in6_addr &out) +#ifdef INET6 +void IPAddress::Map4to6(const struct in_addr &in, struct in6_addr &out) { memset(&out, 0, sizeof(struct in6_addr)); out.s6_addr32[3] = in.s_addr; out.s6_addr16[5] = (unsigned short)0xFFFF; - return out; } -void IPAddress::Map6to4(struct in6_addr &in, struct in_addr &out) +void IPAddress::Map6to4(const struct in6_addr &in, struct in_addr &out) { memset(&out, 0, sizeof(struct in_addr)); out.s_addr = in.s6_addr32[3]; } #endif -#if INET6 +#ifdef INET6 void IPAddress::GetInAddr(in6_addr &buf) { - assert(false); - if(m_Type & IPv6) - { - memcpy(&buf, &m_SocketAddr.sin6_addr, sizeof(struct in6_addr)); - } - else // its an IPv4-Native Structure - { - // convert to an IPv6-mapped IPA - Map4to6(&m_SocketAddr.sin_addr, &buf); - } + assert(m_Type & IPv6); + memcpy(&buf, &m_SocketAddr.sin6_addr, sizeof(struct in6_addr)); } #endif bool IPAddress::GetInAddr(struct in_addr &buf) { switch(m_Type & IPv64) { -#if INET6 +#ifdef INET6 case IPv64: // IPv4-Compatible IPv6 Address - Map6to4(&m_SocketAddr.sin6_addr, &buf); + Map6to4((const in6_addr)m_SocketAddr.sin6_addr, buf); return true; -#endif - +#else case IPv4: // Pure IPv4 Address. memcpy(&buf, &m_SocketAddr.sin_addr, sizeof(struct in_addr)); return true; +#endif case IPv6: // non-compatible IPv6 Pure Address default: Index: squid3/src/IPAddress.h =================================================================== RCS file: /cvsroot/squid-sf//squid3/src/Attic/IPAddress.h,v retrieving revision 1.1.2.5 retrieving revision 1.1.2.6 diff -u -r1.1.2.5 -r1.1.2.6 --- squid3/src/IPAddress.h 4 Mar 2007 07:04:08 -0000 1.1.2.5 +++ squid3/src/IPAddress.h 5 Mar 2007 11:27:01 -0000 1.1.2.6 @@ -6,16 +6,13 @@ * * Intended for use by the DNS, ACLs, and Client-Server connection parts of Squid3. * - * $Id: IPAddress.h,v 1.1.2.5 2007/03/04 07:04:08 amosjeffries Exp $ + * $Id: IPAddress.h,v 1.1.2.6 2007/03/05 11:27:01 amosjeffries Exp $ */ #ifndef _INC_IPADDRESS_H #define _INC_IPADDRESS_H #include #include -#if INET6 -#include -#endif #include enum IPAddressType { @@ -26,10 +23,17 @@ IPv64 =6 // Dual-Address Stored (can return either IPv6 OR IPv4) }; -static const unsigned int MAX_IP4_STRLEN = 16; -#if INET6 -static const unsigned int MAX_IP6_STRLEN = 74; -static const unsigned int MAX_IPSTRLEN = 75; +static const unsigned int STRLEN_IP4A = 16; // aaa.bbb.ccc.ddd\0 +static const unsigned int STRLEN_IP4R = 28; // ddd.ccc.bbb.aaa.in-addr.arpa.\0 +static const unsigned int STRLEN_IP4S = 21; // ddd.ccc.bbb.aaa:ppppp\0 +static const unsigned int MAX_IP4_STRLEN = STRLEN_IP4R; +#ifdef INET6 +static const unsigned int STRLEN_IP6A = 42; // [ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff]/0 +static const unsigned int STRLEN_IP6R = 75; // f.f.f.f f.f.f.f f.f.f.f f.f.f.f f.f.f.f f.f.f.f f.f.f.f f.f.f.f ipv6.arpa./0 +static const unsigned int STRLEN_IP6S = 48; // [ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff]:00000/0 + /* not certain yet how much space extn. ports will use */ +static const unsigned int MAX_IP6_STRLEN = STRLEN_IP6R; +static const unsigned int MAX_IPSTRLEN = STRLEN_IP6R; #else static const unsigned int MAX_IPSTRLEN = MAX_IP4_STRLEN; #endif @@ -37,11 +41,11 @@ class IPAddress { public: - IPAddress() {}; + IPAddress(); IPAddress(const IPAddress &dat); IPAddress(const struct in_addr &dat); IPAddress(const struct sockaddr_in &dat); -#if INET6 +#ifdef INET6 IPAddress(const struct in6_addr &dat); IPAddress(const struct sockaddr_in6 &dat); #endif @@ -51,9 +55,9 @@ IPAddress& operator =(const IPAddress &s); IPAddress& operator =(struct sockaddr_in const &s); IPAddress& operator =(struct in_addr const &s); -#if INET6 +#ifdef INET6 IPAddress& operator =(struct in6_addr const &s); - IPAddress& operator =(struct sockaddr_in const &s); + IPAddress& operator =(struct sockaddr_in6 const &s); #endif /* Boolean Operators */ @@ -65,7 +69,11 @@ inline bool IsIPv4() { return (m_Type & IPv4); }; inline bool IsIPv6() { return (m_Type & IPv6); }; - bool GetReverseString(char buf[MAX_IPSTRLEN], IPAddressType show_type = None); +#ifdef INET6 + bool GetReverseString(char buf[MAX_IPSTRLEN], IPAddressType show_type = IPv6); +#else + bool GetReverseString(char buf[MAX_IPSTRLEN], IPAddressType show_type = IPv4); +#endif u_short GetPort(); u_short SetPort(u_short port); bool IsAnyAddr(); @@ -93,7 +101,7 @@ void GetSockAddr(struct sockaddr_in &); bool GetInAddr(struct in_addr &); /* false if could not convert IPv6 down to IPv4 */ -#if INET6 +#ifdef INET6 void GetSockAddr(struct sockaddr_in6 &); void GetInAddr(struct in6_addr &); #endif @@ -103,15 +111,15 @@ /* Conversion for dual-type internals */ bool GetReverseString4(char buf[], struct in_addr &); void RebuildStringCache(); -#if INET6 +#ifdef INET6 bool GetReverseString6(char buf[], struct in6_addr &); - void Map4to6(struct in_addr &src, struct in6_addr &dest); - void Map6to4(struct in6_addr &src, struct in_addr &dest); + void Map4to6(const struct in_addr &src, struct in6_addr &dest); + void Map6to4(const struct in6_addr &src, struct in_addr &dest); #endif /* variables */ IPAddressType m_Type; -#if INET6 +#ifdef INET6 struct sockaddr_in6 m_SocketAddr; #else struct sockaddr_in m_SocketAddr;