TCAScheme.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  * University of Waterloo Open Source License
00008  * 
00009  * Copyright (c) 2005 University of Waterloo. 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 University of Waterloo 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 UNIVERSITY
00030  * OF WATERLOO OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
00031  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
00032  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
00033  * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
00034  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
00035  * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
00036  * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00037  */
00038 
00039 
00040 #include <ctype.h>
00041 #include <oasys/debug/Log.h>
00042 #include <oasys/util/URL.h>
00043 
00044 #include "TCAScheme.h"
00045 #include "EndpointID.h"
00046 
00047 namespace dtn {
00048 
00049 template <>
00050 TCAScheme* oasys::Singleton<TCAScheme>::instance_ = 0;
00051 
00059 bool
00060 TCAScheme::validate(const std::string& ssp, bool is_pattern)
00061 {
00062     // DK: This is entirely borrowed from the DTNScheme implementation.
00063     // TODO: Revisit this once we are using email addresses or sha1 hashes
00064     // of email addresses as guids in the scheme. Are these still valid?
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 = "tca:";
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("/scheme/tca",
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 // DK: This is almost entirely copied from the DTNScheme implementation.
00105 // The one exception is a change to the matching logic, to allow for wildcard
00106 // * in either pattern or ssp. (Previously, * was only supported in pattern.)
00107 bool
00108 TCAScheme::match(const EndpointIDPattern& pattern, const EndpointID& eid)
00109 {
00110     // sanity check
00111     ASSERT(pattern.scheme() == this);
00112 
00113     // we only match endpoint ids of the same scheme
00114     if (!eid.known_scheme() || (eid.scheme() != this)) {
00115         return false;
00116     }
00117 
00118     // if the ssp of either string is "none", then nothing should
00119     // match it (ever)
00120     if (pattern.ssp() == "none" || eid.ssp() == "none") {
00121         return false;
00122     }
00123 
00124     // parse the two strings into URLs for easier manipulation
00125     oasys::URL eid_url(eid.str());
00126     oasys::URL pattern_url(pattern.str());
00127 
00128     if (!eid_url.valid()) {
00129         log_warn("/scheme/dtn",
00130                  "match error: eid '%s' not a valid url",
00131                  eid.c_str());
00132         return false;
00133     }
00134 
00135     if (!pattern_url.valid()) {
00136         log_warn("/scheme/dtn",
00137                  "match error: pattern '%s' not a valid url",
00138                  pattern.c_str());
00139         return false;
00140     }
00141 
00142     // check for a wildcard host specifier e.g dtn://*
00143     if (pattern_url.host_ == "*" && pattern_url.path_ == "")
00144     {
00145         return true;
00146     }
00147 
00148     // match the host part of the urls (though if the pattern host is
00149     // "*", fall through to the rest of the comparison)
00150     if ((pattern_url.host_ != "*") &&
00151          (eid_url.host_ != "*") &&                  // DK: added this
00152          (pattern_url.host_ != eid_url.host_))
00153     {
00154         log_debug("/scheme/dtn",
00155                   "match(%s, %s) failed: url hosts not equal ('%s' != '%s')",
00156                   eid_url.c_str(), pattern_url.c_str(),
00157                   pattern_url.host_.c_str(), eid_url.host_.c_str());
00158         return false;
00159     }
00160 
00161     // make sure the ports are equal (or unspecified in which case they're 0)
00162     if (pattern_url.port_ != eid_url.port_)
00163     {
00164         log_debug("/scheme/dtn",
00165                   "match(%s, %s) failed: url ports not equal (%d != %d)",
00166                   eid_url.c_str(), pattern_url.c_str(),
00167                   pattern_url.port_, eid_url.port_);
00168         return false;
00169     }
00170 
00171     // check for a wildcard path or an exact match of the path strings
00172     if ((pattern_url.path_ == "*") ||
00173         (pattern_url.path_ == eid_url.path_))
00174     {
00175         log_debug("/scheme/dtn",
00176                   "match(%s, %s) succeeded: pattern '%s' ssp '%s'",
00177                   eid_url.c_str(), pattern_url.c_str(),
00178                   pattern_url.host_.c_str(), eid_url.host_.c_str());
00179         return true;
00180     }
00181 
00182     // finally, try supporting a trailing * to truncate the path match
00183     size_t patternlen = pattern_url.path_.length();
00184     if (patternlen >= 1 && pattern_url.path_[patternlen-1] == '*') {
00185         patternlen--;
00186 
00187         if (pattern_url.path_.substr(0, patternlen) ==
00188             eid_url.path_.substr(0, patternlen))
00189         {
00190             log_debug("/scheme/dtn",
00191                       "match(%s, %s) substring succeeded: "
00192                       "pattern '%s' ssp '%s'",
00193                       eid_url.c_str(), pattern_url.c_str(),
00194                       pattern_url.host_.c_str(), eid_url.host_.c_str());
00195             return true;
00196         }
00197     }
00198 
00199     // XXX/demmer TODO: support CIDR style matching for explicit
00200     // dotted-quad ip addresses
00201 
00202     return false;
00203 }
00204 
00205 
00213 bool
00214 TCAScheme::append_service_tag(std::string* ssp, const char* tag)
00215 {
00216     if (tag[0] != '/') {
00217         ssp->push_back('/');
00218     }
00219     ssp->append(tag);
00220     return true;
00221 }
00222 
00223 } // namespace dtn

Generated on Fri Dec 22 14:48:01 2006 for DTN Reference Implementation by  doxygen 1.5.1