# Bazaar merge directive format 2 (Bazaar 0.90)
# revision_id: kinkie@squid-cache.org-20150113102356-6to483ek292grtch
# target_branch: file:///home/kinkie/squid/workspace/trunk/
# testament_sha1: 36de81768633fa7022034f999943dcbe5725dede
# timestamp: 2015-01-13 11:24:33 +0100
# base_revision_id: squid3@treenet.co.nz-20150113082255-\
#   dy6r9b5dn4j2oo2v
# 
# Begin patch
=== modified file 'src/acl/Acl.cc'
--- src/acl/Acl.cc	2015-01-13 07:25:36 +0000
+++ src/acl/Acl.cc	2015-01-13 08:42:16 +0000
@@ -378,7 +378,7 @@
 
 ACL::~ACL()
 {
-    debugs(28, 3, "ACL::~ACL: '" << cfgline << "'");
+    debugs(28, 3, "freeing ACL " << name);
     safe_free(cfgline);
     AclMatchedName = NULL; // in case it was pointing to our name
 }

=== modified file 'src/acl/Arp.cc'
--- src/acl/Arp.cc	2015-01-13 07:25:36 +0000
+++ src/acl/Arp.cc	2015-01-13 10:23:56 +0000
@@ -20,9 +20,7 @@
 #include "globals.h"
 #include "ip/Address.h"
 
-static void aclParseArpList(Splay<Eui::Eui48 *> **curlist);
-static int aclMatchArp(Splay<Eui::Eui48 *> **dataptr, Ip::Address &c);
-static Splay<Eui::Eui48 *>::SPLAYCMP aclArpCompare;
+#include <algorithm>
 
 ACL *
 ACLARP::clone() const
@@ -30,21 +28,11 @@
     return new ACLARP(*this);
 }
 
-ACLARP::ACLARP (char const *theClass) : data (NULL), class_ (theClass)
+ACLARP::ACLARP (char const *theClass) : class_ (theClass)
 {}
 
-ACLARP::ACLARP (ACLARP const & old) : data (NULL), class_ (old.class_)
-{
-    /* we don't have copy constructors for the data yet */
-    assert (!old.data);
-}
-
-ACLARP::~ACLARP()
-{
-    if (data) {
-        data->destroy();
-        delete data;
-    }
+ACLARP::ACLARP (ACLARP const & old) : class_ (old.class_), aclArpData(old.aclArpData)
+{
 }
 
 char const *
@@ -56,7 +44,7 @@
 bool
 ACLARP::empty () const
 {
-    return data->empty();
+    return aclArpData.empty();
 }
 
 /* ==== BEGIN ARP ACL SUPPORT ============================================= */
@@ -114,14 +102,6 @@
 void
 ACLARP::parse()
 {
-    if (!data)
-        data = new Splay<Eui::Eui48 *>();
-    aclParseArpList(&data);
-}
-
-void
-aclParseArpList(Splay<Eui::Eui48 *> **curlist)
-{
     char *t = NULL;
     Eui::Eui48 *q = NULL;
 
@@ -129,8 +109,10 @@
         if ((q = aclParseArpData(t)) == NULL)
             continue;
 
-        (*curlist)->insert(q, aclArpCompare);
+        aclArpData.insert(*q);
+        safe_free(q);
     }
+
 }
 
 int
@@ -144,47 +126,21 @@
         return 0;
     }
 
-    return aclMatchArp(&data, checklist->src_addr);
-}
-
-/***************/
-/* aclMatchArp */
-/***************/
-int
-aclMatchArp(Splay<Eui::Eui48 *> **dataptr, Ip::Address &c)
-{
     Eui::Eui48 lookingFor;
-    if (lookingFor.lookup(c)) {
-        Eui::Eui48 * const* lookupResult = (*dataptr)->find(&lookingFor,aclArpCompare);
-        debugs(28, 3, "aclMatchArp: '" << c << "' " << (lookupResult ? "found" : "NOT found"));
-        return (lookupResult != NULL);
-    }
-    debugs(28, 3, "aclMatchArp: " << c << " NOT found");
-    return 0;
-}
-
-static int
-aclArpCompare(Eui::Eui48 * const &a, Eui::Eui48 * const &b)
-{
-    return memcmp(a, b, sizeof(Eui::Eui48));
-}
-
-// visitor functor to collect the contents of the Arp Acl
-struct ArpAclDumpVisitor {
-    SBufList contents;
-    void operator() (const Eui::Eui48 * v) {
-        static char buf[48];
-        v->encode(buf,48);
-        contents.push_back(SBuf(buf));
-    }
-};
+    lookingFor.lookup(checklist->src_addr);
+    return (aclArpData.find(lookingFor) != aclArpData.end());
+}
 
 SBufList
 ACLARP::dump() const
 {
-    ArpAclDumpVisitor visitor;
-    data->visit(visitor);
-    return visitor.contents;
+    SBufList sl;
+    for (auto i = aclArpData.cbegin(); i != aclArpData.cend(); ++i) {
+        char buf[48];
+        i->encode(buf,48);
+        sl.push_back(SBuf(buf));
+    }
+    return sl;
 }
 
 /* ==== END ARP ACL SUPPORT =============================================== */

=== modified file 'src/acl/Arp.h'
--- src/acl/Arp.h	2015-01-13 07:25:36 +0000
+++ src/acl/Arp.h	2015-01-13 10:23:56 +0000
@@ -11,7 +11,8 @@
 
 #include "acl/Acl.h"
 #include "acl/Checklist.h"
-#include "splay.h"
+
+#include <set>
 
 namespace Eui
 {
@@ -26,7 +27,7 @@
 public:
     ACLARP(char const *);
     ACLARP(ACLARP const &);
-    ~ACLARP();
+    ~ACLARP() {}
     ACLARP&operator=(ACLARP const &);
 
     virtual ACL *clone()const;
@@ -39,8 +40,9 @@
 protected:
     static Prototype RegistryProtoype;
     static ACLARP RegistryEntry_;
-    Splay<Eui::Eui48 *> *data;
     char const *class_;
+    typedef std::set<Eui::Eui48> AclArpData_t;
+    AclArpData_t aclArpData;
 };
 
 #endif /* SQUID_ACLARP_H */

=== modified file 'src/acl/CertificateData.cc'
--- src/acl/CertificateData.cc	2015-01-13 07:25:36 +0000
+++ src/acl/CertificateData.cc	2015-01-13 10:23:56 +0000
@@ -71,13 +71,6 @@
     return values.match(value);
 }
 
-struct CertificateDataAclDumpVisitor {
-    SBufList contents;
-    void operator() (char * const & node_data) {
-        contents.push_back(SBuf(node_data));
-    }
-};
-
 SBufList
 ACLCertificateData::dump() const
 {
@@ -85,9 +78,7 @@
     if (validAttributesStr)
         sl.push_back(SBuf(attribute));
 
-    CertificateDataAclDumpVisitor visitor;
-    values.values->visit(visitor);
-    sl.splice(sl.end(),visitor.contents);
+    sl.splice(sl.end(),values.dump());
     return sl;
 }
 

=== modified file 'src/acl/Eui64.cc'
--- src/acl/Eui64.cc	2015-01-13 07:25:36 +0000
+++ src/acl/Eui64.cc	2015-01-13 10:23:56 +0000
@@ -20,31 +20,17 @@
 #include "globals.h"
 #include "ip/Address.h"
 
-static void aclParseEuiList(Splay<Eui::Eui64 *> **curlist);
-static int aclMatchEui(Splay<Eui::Eui64 *> **dataptr, Ip::Address &c);
-static Splay<Eui::Eui64 *>::SPLAYCMP aclEui64Compare;
-
 ACL *
 ACLEui64::clone() const
 {
     return new ACLEui64(*this);
 }
 
-ACLEui64::ACLEui64 (char const *theClass) : data (NULL), class_ (theClass)
+ACLEui64::ACLEui64 (char const *theClass) : class_ (theClass)
 {}
 
-ACLEui64::ACLEui64 (ACLEui64 const & old) : data (NULL), class_ (old.class_)
-{
-    /* we don't have copy constructors for the data yet */
-    assert (!old.data);
-}
-
-ACLEui64::~ACLEui64()
-{
-    if (data) {
-        data->destroy();
-        delete data;
-    }
+ACLEui64::ACLEui64 (ACLEui64 const & old) : eui64Data(old.eui64Data), class_ (old.class_)
+{
 }
 
 char const *
@@ -56,7 +42,7 @@
 bool
 ACLEui64::empty () const
 {
-    return data->empty();
+    return eui64Data.empty();
 }
 
 Eui::Eui64 *
@@ -88,22 +74,11 @@
 void
 ACLEui64::parse()
 {
-    if (!data)
-        data = new Splay<Eui::Eui64 *>();
-    aclParseEuiList(&data);
-}
-
-void
-aclParseEuiList(Splay<Eui::Eui64 *> **curlist)
-{
-    char *t = NULL;
-    Eui::Eui64 *q = NULL;
-
-    while ((t = strtokFile())) {
-        if ((q = aclParseEuiData(t)) == NULL)
-            continue;
-
-        (*curlist)->insert(q, aclEui64Compare);
+    while (const char * t = strtokFile()) {
+        if (Eui::Eui64 * q = aclParseEuiData(t)) {
+            eui64Data.insert(*q);
+            safe_free(q);
+        }
     }
 }
 
@@ -118,51 +93,27 @@
         return 0;
     }
 
-    return aclMatchEui(&data, checklist->src_addr);
-}
-
-/***************/
-/* aclMatchEui */
-/***************/
-int
-aclMatchEui(Splay<Eui::Eui64 *> **dataptr, Ip::Address &c)
-{
     Eui::Eui64 lookingFor;
-
-    if (lookingFor.lookup(c)) {
-        Eui::Eui64 * const * lookupResult = (*dataptr)->find(&lookingFor, aclEui64Compare);
-        debugs(28, 3, "aclMatchEui: '" << c << "' " << (lookupResult ? "found" : "NOT found"));
-        return (lookupResult != NULL);
+    if (lookingFor.lookup(checklist->src_addr)) {
+        bool found = (eui64Data.find(lookingFor) != eui64Data.end());
+        debugs(28, 3,  checklist->src_addr << "' " << (found ? "found" : "NOT found"));
+        return found;
     }
 
-    /*
-     * Address was not found on any interface
-     */
-    debugs(28, 3, "aclMatchEui: " << c << " NOT found");
+    debugs(28, 3, checklist->src_addr << " NOT found");
     return 0;
 }
 
-static int
-aclEui64Compare(Eui::Eui64 * const &a, Eui::Eui64 * const &b)
-{
-    return memcmp(a, b, sizeof(Eui::Eui64));
-}
-
-struct AclEui64DumpVisitor {
-    SBufList contents;
-    void operator() ( const Eui::Eui64 * v) {
-        static char buf[48];
-        v->encode(buf, 48);
-        contents.push_back(SBuf(buf));
-    }
-};
-
 SBufList
 ACLEui64::dump() const
 {
-    AclEui64DumpVisitor visitor;
-    data->visit(visitor);
-    return visitor.contents;
+    SBufList sl;
+    for (auto i = eui64Data.cbegin(); i != eui64Data.end(); ++i) {
+        static char buf[48];
+        i->encode(buf,48);
+        sl.push_back(SBuf(buf));
+    }
+    return sl;
 }
 
 #endif /* USE_SQUID_EUI */

=== modified file 'src/acl/Eui64.h'
--- src/acl/Eui64.h	2015-01-13 07:25:36 +0000
+++ src/acl/Eui64.h	2015-01-13 10:23:56 +0000
@@ -11,7 +11,8 @@
 
 #include "acl/Acl.h"
 #include "acl/Checklist.h"
-#include "splay.h"
+
+#include <set>
 
 namespace Eui
 {
@@ -25,7 +26,7 @@
 public:
     ACLEui64(char const *);
     ACLEui64(ACLEui64 const &);
-    ~ACLEui64();
+    ~ACLEui64() {}
     ACLEui64&operator=(ACLEui64 const &);
 
     virtual ACL *clone()const;
@@ -38,7 +39,8 @@
 protected:
     static Prototype RegistryProtoype;
     static ACLEui64 RegistryEntry_;
-    Splay<Eui::Eui64 *> *data;
+    typedef std::set<Eui::Eui64> Eui64Data_t;
+    Eui64Data_t eui64Data;
     char const *class_;
 };
 

=== modified file 'src/acl/StringData.cc'
--- src/acl/StringData.cc	2015-01-13 07:25:36 +0000
+++ src/acl/StringData.cc	2015-01-13 10:23:56 +0000
@@ -14,94 +14,57 @@
 #include "cache_cf.h"
 #include "Debug.h"
 
-ACLStringData::ACLStringData() : values (NULL)
-{}
-
-ACLStringData::ACLStringData(ACLStringData const &old) : values (NULL)
-{
-    assert (!old.values);
-}
-
-template<class T>
-inline void
-xRefFree(T &thing)
-{
-    xfree (thing);
-}
-
-ACLStringData::~ACLStringData()
-{
-    if (values) {
-        values->destroy(xRefFree);
-        delete values;
-    }
-}
-
-static int
-splaystrcmp (char * const &l, char * const &r)
-{
-    return strcmp (l,r);
+ACLStringData::ACLStringData(ACLStringData const &old) : stringValues(old.stringValues)
+{
 }
 
 void
 ACLStringData::insert(const char *value)
 {
-    values->insert(xstrdup(value), splaystrcmp);
+    stringValues.insert(SBuf(value));
 }
 
 bool
 ACLStringData::match(char const *toFind)
 {
-    if (!values || !toFind)
+    if (stringValues.empty() || !toFind)
         return 0;
 
-    debugs(28, 3, "aclMatchStringList: checking '" << toFind << "'");
-
-    char * const * result = values->find(const_cast<char *>(toFind), splaystrcmp);
-
-    debugs(28, 3, "aclMatchStringList: '" << toFind << "' " << (result ? "found" : "NOT found"));
-
-    return (result != NULL);
+    SBuf tf(toFind);
+    debugs(28, 3, "aclMatchStringList: checking '" << tf << "'");
+
+    bool found = (stringValues.find(tf) != stringValues.end());
+    debugs(28, 3, "aclMatchStringList: '" << tf << "' " << (found ? "found" : "NOT found"));
+
+    return found;
 }
 
-// visitor functor to collect the contents of the Arp Acl
-struct StringDataAclDumpVisitor {
-    SBufList contents;
-    void operator() (char * const& node_data) {
-        contents.push_back(SBuf(node_data));
-    }
-};
-
 SBufList
 ACLStringData::dump() const
 {
-    StringDataAclDumpVisitor visitor;
-    values->visit(visitor);
-    return visitor.contents;
+    SBufList sl;
+    sl.insert(sl.end(), stringValues.begin(), stringValues.end());
+    return sl;
 }
 
 void
 ACLStringData::parse()
 {
-    if (!values)
-        values = new Splay<char *>();
-
     char *t;
     while ((t = strtokFile()))
-        values->insert(xstrdup(t), splaystrcmp);
+        stringValues.insert(SBuf(t));
 }
 
 bool
 ACLStringData::empty() const
 {
-    return values->empty();
+    return stringValues.empty();
 }
 
 ACLData<char const *> *
 ACLStringData::clone() const
 {
     /* Splay trees don't clone yet. */
-    assert (!values);
     return new ACLStringData(*this);
 }
 

=== modified file 'src/acl/StringData.h'
--- src/acl/StringData.h	2015-01-13 07:25:36 +0000
+++ src/acl/StringData.h	2015-01-13 10:23:56 +0000
@@ -11,17 +11,19 @@
 
 #include "acl/Acl.h"
 #include "acl/Data.h"
-#include "splay.h"
+#include "SBuf.h"
+
+#include <set>
 
 class ACLStringData : public ACLData<char const *>
 {
     MEMPROXY_CLASS(ACLStringData);
 
 public:
-    ACLStringData();
+    ACLStringData() {}
     ACLStringData(ACLStringData const &);
     ACLStringData &operator= (ACLStringData const &);
-    virtual ~ACLStringData();
+    virtual ~ACLStringData() {}
     bool match(char const *);
     virtual SBufList dump() const;
     virtual void parse();
@@ -30,7 +32,9 @@
     /// Insert a string data value
     void insert(const char *);
 
-    Splay<char *> *values;
+private:
+    typedef std::set<SBuf> StringValues_t;
+    StringValues_t stringValues;
 };
 
 #endif /* SQUID_ACLSTRINGDATA_H */

=== modified file 'src/acl/UserData.cc'
--- src/acl/UserData.cc	2015-01-13 07:25:36 +0000
+++ src/acl/UserData.cc	2015-01-13 10:23:56 +0000
@@ -13,39 +13,14 @@
 #include "acl/UserData.h"
 #include "ConfigParser.h"
 #include "Debug.h"
+#include "globals.h"
+#include "SBufAlgos.h"
 #include "util.h"
 
-template<class T>
-inline void
-xRefFree(T &thing)
-{
-    xfree (thing);
-}
-
-ACLUserData::~ACLUserData()
-{
-    if (names) {
-        names->destroy(xRefFree);
-        delete names;
-    }
-}
-
-static int
-splaystrcasecmp (char * const &l, char * const &r)
-{
-    return strcasecmp ((char *)l,(char *)r);
-}
-
-static int
-splaystrcmp (char * const &l, char * const &r)
-{
-    return strcmp ((char *)l,(char *)r);
-}
-
 bool
 ACLUserData::match(char const *user)
 {
-    debugs(28, 7, "aclMatchUser: user is " << user << ", case_insensitive is " << flags.case_insensitive);
+    debugs(28, 7, "user is " << user << ", case_insensitive is " << flags.case_insensitive);
 
     if (user == NULL || strcmp(user, "-") == 0)
         return 0;
@@ -55,26 +30,11 @@
         return 1;
     }
 
-    char * const *result;
-
-    if (flags.case_insensitive)
-        result = names->find(const_cast<char *>(user), splaystrcasecmp);
-    else
-        result = names->find(const_cast<char *>(user), splaystrcmp);
-
-    /* Top=splay_splay(user,Top,(splayNode::SPLAYCMP *)dumping_strcmp); */
-    debugs(28, 7, "aclMatchUser: returning " << (result != NULL));
-
-    return (result != NULL);
+    bool result = (userDataNames.find(SBuf(user)) != userDataNames.end());
+    debugs(28, 7, "returning " << result);
+    return result;
 }
 
-struct UserDataAclDumpVisitor {
-    SBufList contents;
-    void operator() (char * const & node_data) {
-        contents.push_back(SBuf(node_data));
-    }
-};
-
 SBufList
 ACLUserData::dump() const
 {
@@ -88,71 +48,84 @@
     if (flags.case_insensitive)
         sl.push_back(SBuf("-i"));
 
-    /* damn this is VERY inefficient for long ACL lists... filling
-     * a SBufList this way costs Sum(1,N) iterations. For instance
-     * a 1000-elements list will be filled in 499500 iterations.
-     */
-    if (names) {
-        UserDataAclDumpVisitor visitor;
-        names->visit(visitor);
-        sl.splice(sl.end(),visitor.contents);
-    }
+    sl.insert(sl.end(), userDataNames.cbegin(), userDataNames.cend());
 
+    debugs(28,5, "ACLUserData dump output: " << SBufContainerJoin(userDataNames,SBuf(" ")));
     return sl;
 }
 
+static bool
+CaseInsensitveSBufCompare(const SBuf &lhs, const SBuf &rhs)
+{
+    return (lhs.caseCmp(rhs) < 0);
+}
+
 void
 ACLUserData::parse()
 {
-    debugs(28, 2, "aclParseUserList: parsing user list");
-
-    if (!names)
-        names = new Splay<char *>();
+    debugs(28, 2, "parsing user list");
 
     char *t = NULL;
     if ((t = ConfigParser::strtokFile())) {
-        debugs(28, 5, "aclParseUserList: First token is " << t);
+        SBuf s(t);
+        debugs(28, 5, "first token is " << s);
 
-        if (strcmp("-i", t) == 0) {
-            debugs(28, 5, "aclParseUserList: Going case-insensitive");
+        if (s.cmp("-i",2) == 0) {
+            debugs(28, 5, "Going case-insensitive");
             flags.case_insensitive = true;
-        } else if (strcmp("REQUIRED", t) == 0) {
-            debugs(28, 5, "aclParseUserList: REQUIRED-type enabled");
+            // due to how the std::set API work, if we want to change
+            // the comparison function we have to create a new std::set
+            UserDataNames_t newUdn(CaseInsensitveSBufCompare);
+            newUdn.insert(userDataNames.begin(), userDataNames.end());
+            swap(userDataNames,newUdn);
+        } else if (s.cmp("REQUIRED") == 0) {
+            debugs(28, 5, "REQUIRED-type enabled");
             flags.required = true;
         } else {
             if (flags.case_insensitive)
-                Tolower(t);
+                s.toLower();
 
-            names->insert(xstrdup(t), splaystrcmp);
+            debugs(28, 6, "Adding user " << s);
+            userDataNames.insert(s);
         }
     }
 
-    debugs(28, 3, "aclParseUserList: Case-insensitive-switch is " << flags.case_insensitive);
+    debugs(28, 3, "Case-insensitive-switch is " << flags.case_insensitive);
     /* we might inherit from a previous declaration */
 
-    debugs(28, 4, "aclParseUserList: parsing user list");
+    debugs(28, 4, "parsing following tokens");
 
     while ((t = ConfigParser::strtokFile())) {
-        debugs(28, 6, "aclParseUserList: Got token: " << t);
+        SBuf s(t);
+        debugs(28, 6, "Got token: " << s);
 
         if (flags.case_insensitive)
-            Tolower(t);
-
-        names->insert(xstrdup(t), splaystrcmp);
-    }
+            s.toLower();
+
+        debugs(28, 6, "Adding user " << s);
+        userDataNames.insert(s);
+    }
+
+    if (flags.required && !userDataNames.empty()) {
+        debugs(28, DBG_PARSE_NOTE(1), "WARNING: detected attempt to add usernames to an acl of type REQUIRED");
+        userDataNames.clear();
+    }
+
+    debugs(28,4, "ACL contains " << userDataNames.size() << " users");
 }
 
 bool
 ACLUserData::empty() const
 {
-    return (!names || names->empty()) && !flags.required;
+    debugs(28,6,"required: " << flags.required << ", number of users: " << userDataNames.size());
+    if (flags.required)
+        return false;
+    return userDataNames.empty();
 }
 
 ACLData<char const *> *
 ACLUserData::clone() const
 {
-    /* Splay trees don't clone yet. */
-    assert (!names);
     return new ACLUserData;
 }
 

=== modified file 'src/acl/UserData.h'
--- src/acl/UserData.h	2015-01-13 07:25:36 +0000
+++ src/acl/UserData.h	2015-01-13 10:23:56 +0000
@@ -11,26 +11,32 @@
 
 #include "acl/Acl.h"
 #include "acl/Data.h"
-#include "splay.h"
+#include "SBuf.h"
+
+#include <set>
 
 class ACLUserData : public ACLData<char const *>
 {
     MEMPROXY_CLASS(ACLUserData);
 
 public:
-    virtual ~ACLUserData();
+    virtual ~ACLUserData() {}
     bool match(char const *user);
     virtual SBufList dump() const;
     void parse();
     bool empty() const;
     virtual ACLData<char const *> *clone() const;
 
-    Splay<char *> *names;
+private:
+
+    typedef std::set<SBuf,bool(*)(const SBuf&, const SBuf&)> UserDataNames_t;
+    UserDataNames_t userDataNames;
 
     struct {
         bool case_insensitive;
         bool required;
     } flags;
+
 };
 
 #endif /* SQUID_ACLUSERDATA_H */

=== modified file 'src/eui/Eui48.h'
--- src/eui/Eui48.h	2015-01-13 07:25:36 +0000
+++ src/eui/Eui48.h	2015-01-13 08:42:16 +0000
@@ -30,6 +30,8 @@
 public:
     Eui48() { clear(); }
     Eui48(const Eui48 &t) { memcpy(this, &t, sizeof(Eui48)); }
+    bool operator== (const Eui48 &t) const { return memcmp(eui, t.eui, SZ_EUI48_BUF) == 0; }
+    bool operator< (const Eui48 &t) const { return memcmp(eui, t.eui, SZ_EUI48_BUF) < 0; }
     ~Eui48() {}
 
     const unsigned char *get(void);

=== modified file 'src/eui/Eui64.h'
--- src/eui/Eui64.h	2015-01-13 07:25:36 +0000
+++ src/eui/Eui64.h	2015-01-13 08:42:16 +0000
@@ -37,6 +37,9 @@
 public:
     Eui64() { clear(); }
     Eui64(const Eui64 &t) { memcpy(this, &t, sizeof(Eui64)); }
+    Eui64& operator= (const Eui64 &t) {memcpy(this, &t, sizeof(Eui64)); return *this;}
+    bool operator== (const Eui64 &t) const { return (memcmp(eui,t.eui,SZ_EUI64_BUF) == 0); }
+    bool operator< (const Eui64 &t) const { return (memcmp(eui,t.eui,SZ_EUI64_BUF) < 0); }
     ~Eui64() {}
 
     const unsigned char *get(void);

# Begin bundle
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
CDKB/8XckU4UJDEj9PZA
