Vidalia 0.2.10
|
00001 /* 00002 ** This file is part of Vidalia, and is subject to the license terms in the 00003 ** LICENSE file, found in the top level directory of this distribution. If 00004 ** you did not receive the LICENSE file with this file, you may obtain it 00005 ** from the Vidalia source package distributed by the Vidalia Project at 00006 ** http://www.vidalia-project.net/. No part of Vidalia, including this file, 00007 ** may be copied, modified, propagated, or distributed except according to 00008 ** the terms described in the LICENSE file. 00009 */ 00010 00011 /* 00012 ** \file RouterStatus.cpp 00013 ** \version $Id: RouterStatus.cpp 3735 2009-04-28 20:28:01Z edmanm $ 00014 ** \brief Parses a blob of router status text from Tor 00015 */ 00016 00017 #include "RouterStatus.h" 00018 00019 #include "stringutil.h" 00020 00021 /** Defines the time format used when parsing the published date and time from 00022 * a router's status. */ 00023 #define TIME_FORMAT "yyyy-MM-dd HH:mm:ss" 00024 00025 00026 /** Constructor. Parses <b>status</b> for router status information. The given 00027 * string should match the router status entry format from Tor's dir-spec.txt. 00028 * The currently recognized lines are: 00029 * 00030 * "r" SP nickname SP identity SP digest SP publication SP IP SP ORPort 00031 * SP DirPort NL 00032 * "s" SP Flags NL 00033 * 00034 * Unrecognized lines are currently ignored. 00035 * 00036 * */ 00037 RouterStatus::RouterStatus(const QStringList &status) 00038 { 00039 bool ok; 00040 00041 _valid = false; 00042 _flags = 0; 00043 00044 foreach (QString line, status) { 00045 if (line.startsWith("r ")) { 00046 QStringList parts = line.split(" ", QString::SkipEmptyParts); 00047 if (parts.size() < 9) 00048 return; 00049 00050 /* Nickname */ 00051 _name = parts.at(1); 00052 /* Identity key digest */ 00053 _id = base16_encode(QByteArray::fromBase64(parts.at(2).toAscii())); 00054 if (_id.isEmpty()) 00055 return; 00056 /* Most recent descriptor digest */ 00057 _digest = base16_encode(QByteArray::fromBase64(parts.at(3).toAscii())); 00058 if (_digest.isEmpty()) 00059 return; 00060 /* Most recent publication date */ 00061 _published = QDateTime::fromString(parts.at(4) + " " + parts.at(5), 00062 TIME_FORMAT); 00063 if (!_published.isValid()) 00064 return; 00065 /* IP address */ 00066 _ipAddress = QHostAddress(parts.at(6)); 00067 if (_ipAddress.isNull()) 00068 return; 00069 /* ORPort */ 00070 _orPort = parts.at(7).toUInt(&ok); 00071 if (!ok) 00072 return; 00073 /* DirPort */ 00074 _dirPort = parts.at(8).toUInt(&ok); 00075 if (!ok) 00076 return; 00077 00078 _valid = true; 00079 } else if (line.startsWith("s ")) { 00080 /* Status flags */ 00081 QStringList flags = line.split(" ", QString::SkipEmptyParts); 00082 flags.removeFirst(); /* Remove the "s" */ 00083 00084 foreach (QString flag, flags) { 00085 _flags |= flagValue(flag); 00086 } 00087 } 00088 } 00089 } 00090 00091 /** Returns a Flags enum value for the given router status <b>flag</b>. If 00092 * <b>flag</b> is not recognized, then <i>Unknown</i> is returned. */ 00093 RouterStatus::Flag 00094 RouterStatus::flagValue(const QString &flag) 00095 { 00096 if (!flag.compare("Authority", Qt::CaseInsensitive)) 00097 return Authority; 00098 if (!flag.compare("BadExit", Qt::CaseInsensitive)) 00099 return BadExit; 00100 if (!flag.compare("BadDirectory", Qt::CaseInsensitive)) 00101 return BadDirectory; 00102 if (!flag.compare("Exit", Qt::CaseInsensitive)) 00103 return Exit; 00104 if (!flag.compare("Fast", Qt::CaseInsensitive)) 00105 return Fast; 00106 if (!flag.compare("Guard", Qt::CaseInsensitive)) 00107 return Guard; 00108 if (!flag.compare("HSDir", Qt::CaseInsensitive)) 00109 return HSDir; 00110 if (!flag.compare("Named", Qt::CaseInsensitive)) 00111 return Named; 00112 if (!flag.compare("Running", Qt::CaseInsensitive)) 00113 return Running; 00114 if (!flag.compare("Stable", Qt::CaseInsensitive)) 00115 return Stable; 00116 if (!flag.compare("Valid", Qt::CaseInsensitive)) 00117 return Valid; 00118 if (!flag.compare("V2Dir", Qt::CaseInsensitive)) 00119 return V2Dir; 00120 if (!flag.compare("V3Dir", Qt::CaseInsensitive)) 00121 return V3Dir; 00122 return Unknown; /* Unknown status flag */ 00123 } 00124