servlib/naming/TCAScheme.cc
changeset 0 2b3e5ec03512
equal deleted inserted replaced
-1:000000000000 0:2b3e5ec03512
       
     1 /*
       
     2  *    Copyright 2005-2006 University of Waterloo
       
     3  * 
       
     4  *    Licensed under the Apache License, Version 2.0 (the "License");
       
     5  *    you may not use this file except in compliance with the License.
       
     6  *    You may obtain a copy of the License at
       
     7  * 
       
     8  *        http://www.apache.org/licenses/LICENSE-2.0
       
     9  * 
       
    10  *    Unless required by applicable law or agreed to in writing, software
       
    11  *    distributed under the License is distributed on an "AS IS" BASIS,
       
    12  *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
       
    13  *    See the License for the specific language governing permissions and
       
    14  *    limitations under the License.
       
    15  */
       
    16 
       
    17 #ifdef HAVE_CONFIG_H
       
    18 #  include <dtn-config.h>
       
    19 #endif
       
    20 
       
    21 #include <ctype.h>
       
    22 #include <oasys/debug/Log.h>
       
    23 
       
    24 #include "TCAScheme.h"
       
    25 #include "EndpointID.h"
       
    26 
       
    27 namespace dtn {
       
    28 
       
    29 template <>
       
    30 TCAScheme* oasys::Singleton<TCAScheme>::instance_ = 0;
       
    31 
       
    32 /**
       
    33  * Validate that the SSP in the given URI is legitimate for
       
    34  * this scheme. If the 'is_pattern' parameter is true, then
       
    35  * the ssp is being validated as an EndpointIDPattern.
       
    36  *
       
    37  * @return true if valid
       
    38  */
       
    39 bool
       
    40 TCAScheme::validate(const URI& uri, bool is_pattern)
       
    41 {
       
    42     // DK: This is entirely borrowed from the DTNScheme implementation.
       
    43     // TODO: Revisit this once we are using email addresses or sha1 hashes
       
    44     // of email addresses as guids in the scheme. Are these still valid?
       
    45 
       
    46     (void)is_pattern;
       
    47 
       
    48     if (!uri.valid()) {
       
    49         return false;
       
    50     }
       
    51 
       
    52     return true;
       
    53 }
       
    54 
       
    55 /**
       
    56  * Match the given ssp with the given pattern.
       
    57  *
       
    58  * @return true if it matches
       
    59  */
       
    60 // DK: This is almost entirely copied from the DTNScheme implementation.
       
    61 // The one exception is a change to the matching logic, to allow for wildcard
       
    62 // * in either pattern or ssp. (Previously, * was only supported in pattern.)
       
    63 bool
       
    64 TCAScheme::match(const EndpointIDPattern& pattern, const EndpointID& eid)
       
    65 {
       
    66     // sanity check
       
    67     ASSERT(pattern.scheme() == this);
       
    68 
       
    69     // we only match endpoint ids of the same scheme
       
    70     if (!eid.known_scheme() || (eid.scheme() != this)) {
       
    71         return false;
       
    72     }
       
    73 
       
    74     // if the ssp of either string is "none", then nothing should
       
    75     // match it (ever)
       
    76     if (pattern.ssp() == "none" || eid.ssp() == "none") {
       
    77         return false;
       
    78     }
       
    79 
       
    80     // check for a wildcard host specifier e.g dtn://*
       
    81     if (pattern.uri().host() == "*" && pattern.uri().path() == "")
       
    82     {
       
    83         return true;
       
    84     }
       
    85 
       
    86     // match the host part of the urls (though if the pattern host is
       
    87     // "*", fall through to the rest of the comparison)
       
    88     if ((pattern.uri().host() != "*") &&
       
    89          (eid.uri().host() != "*") &&                  // DK: added this
       
    90          (pattern.uri().host() != eid.uri().host()))
       
    91     {
       
    92         log_debug_p("/scheme/dtn",
       
    93                     "match(%s, %s) failed: url hosts not equal ('%s' != '%s')",
       
    94                     eid.uri().c_str(), pattern.uri().c_str(),
       
    95                     pattern.uri().host().c_str(), eid.uri().host().c_str());
       
    96         return false;
       
    97     }
       
    98 
       
    99     // make sure the ports are equal (or unspecified in which case they're 0)
       
   100     if (pattern.uri().port_num() != eid.uri().port_num())
       
   101     {
       
   102         log_debug_p("/scheme/dtn",
       
   103                     "match(%s, %s) failed: url ports not equal (%d != %d)",
       
   104                     eid.uri().c_str(), pattern.uri().c_str(),
       
   105                     pattern.uri().port_num(), eid.uri().port_num());
       
   106         return false;
       
   107     }
       
   108 
       
   109     // check for a wildcard path or an exact match of the path strings
       
   110     if ((pattern.uri().path() == "*") ||
       
   111         (pattern.uri().path() == eid.uri().path()))
       
   112     {
       
   113         log_debug_p("/scheme/dtn",
       
   114                     "match(%s, %s) succeeded: pattern '%s' ssp '%s'",
       
   115                     eid.uri().c_str(), pattern.uri().c_str(),
       
   116                     pattern.uri().host().c_str(), eid.uri().host().c_str());
       
   117         return true;
       
   118     }
       
   119 
       
   120     // finally, try supporting a trailing * to truncate the path match
       
   121     size_t patternlen = pattern.uri().path().length();
       
   122     if (patternlen >= 1 && pattern.uri().path()[patternlen-1] == '*') {
       
   123         patternlen--;
       
   124 
       
   125         if (pattern.uri().path().substr(0, patternlen) ==
       
   126             eid.uri().path().substr(0, patternlen))
       
   127         {
       
   128             log_debug_p("/scheme/dtn",
       
   129                         "match(%s, %s) substring succeeded: "
       
   130                         "pattern '%s' ssp '%s'",
       
   131                         eid.uri().c_str(), pattern.uri().c_str(),
       
   132                         pattern.uri().host().c_str(), eid.uri().host().c_str());
       
   133             return true;
       
   134         }
       
   135     }
       
   136 
       
   137     // XXX/demmer TODO: support CIDR style matching for explicit
       
   138     // dotted-quad ip addresses
       
   139 
       
   140     return false;
       
   141 }
       
   142 
       
   143 
       
   144 /**
       
   145  * Append the given service tag to the ssp in a scheme-specific
       
   146  * manner.
       
   147  *
       
   148  * @return true if this scheme is capable of service tags and the
       
   149  * tag is a legal one, false otherwise.
       
   150  */
       
   151 bool
       
   152 TCAScheme::append_service_tag(URI* uri, const char* tag)
       
   153 {
       
   154     if (tag[0] != '/') {
       
   155         uri->set_path(std::string("/") + tag);
       
   156     } else {
       
   157         uri->set_path(tag);
       
   158     }
       
   159     return true;
       
   160 }
       
   161 
       
   162 //----------------------------------------------------------------------
       
   163 Scheme::singleton_info_t
       
   164 TCAScheme::is_singleton(const URI& uri)
       
   165 {
       
   166     // if there's a * in the hostname part of the URI, then it's not a
       
   167     // singleton endpoint
       
   168     if (uri.host().find('*') != std::string::npos) {
       
   169         return EndpointID::MULTINODE;
       
   170     }
       
   171     
       
   172     return EndpointID::SINGLETON;
       
   173 }
       
   174 
       
   175 } // namespace dtn