DTNScheme.cc

Go to the documentation of this file.
00001 /*
00002  * IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. By
00003  * downloading, copying, installing or using the software you agree to
00004  * this license. If you do not agree to this license, do not download,
00005  * install, copy or use the software.
00006  * 
00007  * Intel Open Source License 
00008  * 
00009  * Copyright (c) 2004 Intel Corporation. All rights reserved. 
00010  * 
00011  * Redistribution and use in source and binary forms, with or without
00012  * modification, are permitted provided that the following conditions are
00013  * met:
00014  * 
00015  *   Redistributions of source code must retain the above copyright
00016  *   notice, this list of conditions and the following disclaimer.
00017  * 
00018  *   Redistributions in binary form must reproduce the above copyright
00019  *   notice, this list of conditions and the following disclaimer in the
00020  *   documentation and/or other materials provided with the distribution.
00021  * 
00022  *   Neither the name of the Intel Corporation nor the names of its
00023  *   contributors may be used to endorse or promote products derived from
00024  *   this software without specific prior written permission.
00025  *  
00026  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
00027  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
00028  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
00029  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE INTEL OR
00030  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
00031  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
00032  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
00033  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
00034  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
00035  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
00036  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00037  */
00038 
00039 #include <ctype.h>
00040 #include <oasys/debug/Log.h>
00041 #include <oasys/util/URL.h>
00042 
00043 #include "DTNScheme.h"
00044 #include "EndpointID.h"
00045 
00046 namespace dtn {
00047 
00048 template <>
00049 DTNScheme* oasys::Singleton<DTNScheme>::instance_ = 0;
00050 
00058 bool
00059 DTNScheme::validate(const std::string& ssp, bool is_pattern)
00060 {
00061     // first check for the special ssp that is simply "none"
00062     if (ssp == "none") {
00063         return true;
00064     }
00065     
00066     // use the oasys builtin class for URLs, though we need to re-add
00067     // the dtn: since it was stripped by the basic endpoint id parsing
00068     std::string url_str = "dtn:";
00069     url_str.append(ssp);
00070     oasys::URL url(url_str);
00071     if (! url.valid()) {
00072         return false;
00073     }
00074 
00075     // validate that the hostname contains only legal chars.
00076     // XXX/demmer we could be better about making sure it's really a
00077     // legal hostname, i.e. doesn't contain two dots in a row,
00078     // something like like www.foo..com 
00079     std::string::iterator iter;
00080     for (iter = url.host_.begin(); iter != url.host_.end(); ++iter) {
00081         char c = *iter;
00082         
00083         if (isalnum(c) || (c == '_') || (c == '-') || (c == '.'))
00084             continue;
00085 
00086         if (is_pattern && (c == '*'))
00087             continue;
00088 
00089         log_debug("/dtn/scheme/dtn",
00090                   "ssp '%s' contains invalid hostname character '%c'",
00091                   ssp.c_str(), c);
00092 
00093         return false;
00094     }
00095     
00096     return true;
00097 }
00098 
00104 bool
00105 DTNScheme::match(const EndpointIDPattern& pattern, const EndpointID& eid)
00106 {
00107     // sanity check
00108     ASSERT(pattern.scheme() == this);
00109 
00110     // we only match endpoint ids of the same scheme
00111     if (!eid.known_scheme() || (eid.scheme() != this)) {
00112         return false;
00113     }
00114     
00115     // if the ssp of either string is "none", then nothing should
00116     // match it (ever)
00117     if (pattern.ssp() == "none" || eid.ssp() == "none") {
00118         return false;
00119     }
00120     
00121     // parse the two strings into URLs for easier manipulation
00122     oasys::URL eid_url(eid.str());
00123     oasys::URL pattern_url(pattern.str());
00124     
00125     if (!eid_url.valid()) {
00126         log_warn("/dtn/scheme/dtn",
00127                  "match error: eid '%s' not a valid url",
00128                  eid.c_str());
00129         return false;
00130     }
00131     
00132     if (!pattern_url.valid()) {
00133         log_warn("/dtn/scheme/dtn",
00134                  "match error: pattern '%s' not a valid url",
00135                  pattern.c_str());
00136         return false;
00137     }
00138     
00139     // check for a wildcard host specifier e.g dtn://*
00140     if (pattern_url.host_ == "*" && pattern_url.path_ == "")
00141     {
00142         return true;
00143     }
00144     
00145     // match the host part of the urls (though if the pattern host is
00146     // "*", fall through to the rest of the comparison)
00147     if ((pattern_url.host_ != "*") &&
00148         (pattern_url.host_ != eid_url.host_))
00149     {
00150         log_debug("/dtn/scheme/dtn",
00151                   "match(%s, %s) failed: url hosts not equal ('%s' != '%s')",
00152                   eid_url.c_str(), pattern_url.c_str(),
00153                   pattern_url.host_.c_str(), eid_url.host_.c_str());
00154         return false;
00155     }
00156 
00157     // make sure the ports are equal (or unspecified in which case they're 0)
00158     if (pattern_url.port_ != eid_url.port_)
00159     {
00160         log_debug("/dtn/scheme/dtn",
00161                   "match(%s, %s) failed: url ports not equal (%d != %d)",
00162                   eid_url.c_str(), pattern_url.c_str(),
00163                   pattern_url.port_, eid_url.port_);
00164         return false;
00165     }
00166 
00167     // check for a wildcard path or an exact match of the path strings
00168     if ((pattern_url.path_ == "*") ||
00169         (pattern_url.path_ == eid_url.path_))
00170     {
00171         log_debug("/dtn/scheme/dtn",
00172                   "match(%s, %s) succeeded: pattern '%s' ssp '%s'",
00173                   eid_url.c_str(), pattern_url.c_str(),
00174                   pattern_url.host_.c_str(), eid_url.host_.c_str());
00175         return true;
00176     }
00177 
00178     // finally, try supporting a trailing * to truncate the path match
00179     size_t patternlen = pattern_url.path_.length();
00180     if (patternlen >= 1 && pattern_url.path_[patternlen-1] == '*') {
00181         patternlen--;
00182         
00183         if (pattern_url.path_.substr(0, patternlen) ==
00184             eid_url.path_.substr(0, patternlen))
00185         {
00186             log_debug("/dtn/scheme/dtn",
00187                       "match(%s, %s) substring succeeded: "
00188                       "pattern '%s' ssp '%s'",
00189                       eid_url.c_str(), pattern_url.c_str(),
00190                       pattern_url.host_.c_str(), eid_url.host_.c_str());
00191             return true;
00192         }
00193     }
00194     
00195     // XXX/demmer TODO: support CIDR style matching for explicit
00196     // dotted-quad ip addresses
00197     
00198     return false;
00199 }
00200 
00208 bool
00209 DTNScheme::append_service_tag(std::string* ssp, const char* tag)
00210 {
00211     if (tag[0] != '/') {
00212         ssp->push_back('/');
00213     }
00214     ssp->append(tag);
00215     return true;
00216 }
00217 
00218 } // namespace dtn

Generated on Fri Dec 22 14:47:58 2006 for DTN Reference Implementation by  doxygen 1.5.1