DTNScheme.cc

Go to the documentation of this file.
00001 /*
00002  *    Copyright 2004-2006 Intel Corporation
00003  * 
00004  *    Licensed under the Apache License, Version 2.0 (the "License");
00005  *    you may not use this file except in compliance with the License.
00006  *    You may obtain a copy of the License at
00007  * 
00008  *        http://www.apache.org/licenses/LICENSE-2.0
00009  * 
00010  *    Unless required by applicable law or agreed to in writing, software
00011  *    distributed under the License is distributed on an "AS IS" BASIS,
00012  *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00013  *    See the License for the specific language governing permissions and
00014  *    limitations under the License.
00015  */
00016 
00017 
00018 #include <ctype.h>
00019 #include <oasys/debug/Log.h>
00020 #include <oasys/util/URL.h>
00021 
00022 #include "DTNScheme.h"
00023 #include "EndpointID.h"
00024 
00025 namespace dtn {
00026 
00027 template <>
00028 DTNScheme* oasys::Singleton<DTNScheme>::instance_ = 0;
00029 
00037 bool
00038 DTNScheme::validate(const std::string& ssp, bool is_pattern)
00039 {
00040     // first check for the special ssp that is simply "none"
00041     if (ssp == "none") {
00042         return true;
00043     }
00044     
00045     // use the oasys builtin class for URLs, though we need to re-add
00046     // the dtn: since it was stripped by the basic endpoint id parsing
00047     std::string url_str = "dtn:";
00048     url_str.append(ssp);
00049     oasys::URL url(url_str);
00050     if (! url.valid()) {
00051         return false;
00052     }
00053 
00054     // validate that the hostname contains only legal chars.
00055     // XXX/demmer we could be better about making sure it's really a
00056     // legal hostname, i.e. doesn't contain two dots in a row,
00057     // something like like www.foo..com 
00058     std::string::iterator iter;
00059     for (iter = url.host_.begin(); iter != url.host_.end(); ++iter) {
00060         char c = *iter;
00061         
00062         if (isalnum(c) || (c == '_') || (c == '-') || (c == '.'))
00063             continue;
00064 
00065         if (is_pattern && (c == '*'))
00066             continue;
00067 
00068         log_debug_p("/dtn/scheme/dtn",
00069                     "ssp '%s' contains invalid hostname character '%c'",
00070                     ssp.c_str(), c);
00071 
00072         return false;
00073     }
00074     
00075     return true;
00076 }
00077 
00083 bool
00084 DTNScheme::match(const EndpointIDPattern& pattern, const EndpointID& eid)
00085 {
00086     // sanity check
00087     ASSERT(pattern.scheme() == this);
00088 
00089     // we only match endpoint ids of the same scheme
00090     if (!eid.known_scheme() || (eid.scheme() != this)) {
00091         return false;
00092     }
00093     
00094     // if the ssp of either string is "none", then nothing should
00095     // match it (ever)
00096     if (pattern.ssp() == "none" || eid.ssp() == "none") {
00097         return false;
00098     }
00099     
00100     // parse the two strings into URLs for easier manipulation
00101     oasys::URL eid_url(eid.str());
00102     oasys::URL pattern_url(pattern.str());
00103     
00104     if (!eid_url.valid()) {
00105         log_warn_p("/dtn/scheme/dtn",
00106                    "match error: eid '%s' not a valid url",
00107                    eid.c_str());
00108         return false;
00109     }
00110     
00111     if (!pattern_url.valid()) {
00112         log_warn_p("/dtn/scheme/dtn",
00113                    "match error: pattern '%s' not a valid url",
00114                    pattern.c_str());
00115         return false;
00116     }
00117     
00118     // check for a wildcard host specifier e.g dtn://*
00119     if (pattern_url.host_ == "*" && pattern_url.path_ == "")
00120     {
00121         return true;
00122     }
00123     
00124     // match the host part of the urls (though if the pattern host is
00125     // "*", fall through to the rest of the comparison)
00126     if ((pattern_url.host_ != "*") &&
00127         (pattern_url.host_ != eid_url.host_))
00128     {
00129         log_debug_p("/dtn/scheme/dtn",
00130                     "match(%s, %s) failed: url hosts not equal ('%s' != '%s')",
00131                     eid_url.c_str(), pattern_url.c_str(),
00132                     pattern_url.host_.c_str(), eid_url.host_.c_str());
00133         return false;
00134     }
00135 
00136     // make sure the ports are equal (or unspecified in which case they're 0)
00137     if (pattern_url.port_ != eid_url.port_)
00138     {
00139         log_debug_p("/dtn/scheme/dtn",
00140                     "match(%s, %s) failed: url ports not equal (%d != %d)",
00141                     eid_url.c_str(), pattern_url.c_str(),
00142                     pattern_url.port_, eid_url.port_);
00143         return false;
00144     }
00145 
00146     // check for a wildcard path or an exact match of the path strings
00147     if ((pattern_url.path_ == "*") ||
00148         (pattern_url.path_ == eid_url.path_))
00149     {
00150         log_debug_p("/dtn/scheme/dtn",
00151                     "match(%s, %s) succeeded: pattern '%s' ssp '%s'",
00152                     eid_url.c_str(), pattern_url.c_str(),
00153                     pattern_url.host_.c_str(), eid_url.host_.c_str());
00154         return true;
00155     }
00156 
00157     // finally, try supporting a trailing * to truncate the path match
00158     size_t patternlen = pattern_url.path_.length();
00159     if (patternlen >= 1 && pattern_url.path_[patternlen-1] == '*') {
00160         patternlen--;
00161         
00162         if (pattern_url.path_.substr(0, patternlen) ==
00163             eid_url.path_.substr(0, patternlen))
00164         {
00165             log_debug_p("/dtn/scheme/dtn",
00166                         "match(%s, %s) substring succeeded: "
00167                         "pattern '%s' ssp '%s'",
00168                         eid_url.c_str(), pattern_url.c_str(),
00169                         pattern_url.host_.c_str(), eid_url.host_.c_str());
00170             return true;
00171         }
00172     }
00173     
00174     // XXX/demmer TODO: support CIDR style matching for explicit
00175     // dotted-quad ip addresses
00176     
00177     return false;
00178 }
00179 
00187 bool
00188 DTNScheme::append_service_tag(std::string* ssp, const char* tag)
00189 {
00190     if (tag[0] != '/') {
00191         ssp->push_back('/');
00192     }
00193     ssp->append(tag);
00194     return true;
00195 }
00196 
00197 } // namespace dtn

Generated on Sat Sep 8 08:43:27 2007 for DTN Reference Implementation by  doxygen 1.5.3