Vidalia 0.2.15
|
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.torproject.org/projects/vidalia.html. No part of Vidalia, 00007 ** including this file, may be copied, modified, propagated, or distributed 00008 ** except according to the terms described in the LICENSE file. 00009 */ 00010 00011 /* 00012 ** \file Stream.cpp 00013 ** \brief Object representing a Tor stream 00014 */ 00015 00016 #include "Stream.h" 00017 #include "Circuit.h" 00018 00019 #include <QStringList> 00020 00021 00022 /** Default constructor. */ 00023 Stream::Stream() 00024 { 00025 _status = Unknown; 00026 _port = 0; 00027 } 00028 00029 /** Constructor */ 00030 Stream::Stream(const StreamId &streamId, Status status, 00031 const CircuitId &circuitId, const QString &address, 00032 quint16 port) 00033 { 00034 _streamId = streamId; 00035 _status = status; 00036 _circuitId = circuitId; 00037 _address = address; 00038 _port = port; 00039 } 00040 00041 /** Constructor */ 00042 Stream::Stream(const StreamId &streamId, Status status, 00043 const CircuitId &circuitId, const QString &target) 00044 { 00045 _streamId = streamId; 00046 _status = status; 00047 _circuitId = circuitId; 00048 _port = 0; 00049 00050 int i = target.indexOf(":"); 00051 if (i >= 0) 00052 _address = target.mid(0, i); 00053 if (i + 1 < target.length()) 00054 _port = target.mid(i+1).toUInt(); 00055 } 00056 00057 /** Parses the given string for stream information, given in Tor control 00058 * protocol format. The format is: 00059 * 00060 * StreamID SP StreamStatus SP CircID SP Target 00061 */ 00062 Stream 00063 Stream::fromString(const QString &stream) 00064 { 00065 QStringList parts = stream.split(" ", QString::SkipEmptyParts); 00066 if (parts.size() >= 4) { 00067 /* Get the stream ID */ 00068 StreamId streamId = parts.at(0); 00069 /* Get the stream status value */ 00070 Stream::Status status = Stream::toStatus(parts.at(1)); 00071 /* Get the ID of the circuit on which this stream travels */ 00072 CircuitId circId = parts.at(2); 00073 /* Get the target address for this stream */ 00074 QString target = parts.at(3); 00075 00076 return Stream(streamId, status, circId, target); 00077 } 00078 return Stream(); 00079 } 00080 00081 /** Returns true iff <b>streamId</b> consists of only between 1 and 16 00082 * (inclusive) ASCII-encoded letters and numbers. */ 00083 bool 00084 Stream::isValidStreamId(const StreamId &streamId) 00085 { 00086 int length = streamId.length(); 00087 if (length < 1 || length > 16) 00088 return false; 00089 00090 for (int i = 0; i < length; i++) { 00091 char c = streamId[i].toAscii(); 00092 if (c < '0' && c > '9' && c < 'A' && c > 'Z' && c < 'a' && c > 'z') 00093 return false; 00094 } 00095 return true; 00096 } 00097 00098 /** Converts a string description of a stream's status to its enum value */ 00099 Stream::Status 00100 Stream::toStatus(const QString &strStatus) 00101 { 00102 if (!strStatus.compare("NEW", Qt::CaseInsensitive)) 00103 return New; 00104 if (!strStatus.compare("NEWRESOLVE", Qt::CaseInsensitive)) 00105 return NewResolve; 00106 if (!strStatus.compare("SENTCONNECT", Qt::CaseInsensitive)) 00107 return SentConnect; 00108 if (!strStatus.compare("SENTRESOLVE", Qt::CaseInsensitive)) 00109 return SentResolve; 00110 if (!strStatus.compare("SUCCEEDED", Qt::CaseInsensitive)) 00111 return Succeeded; 00112 if (!strStatus.compare("FAILED", Qt::CaseInsensitive)) 00113 return Failed; 00114 if (!strStatus.compare("CLOSED", Qt::CaseInsensitive)) 00115 return Closed; 00116 if (!strStatus.compare("DETACHED", Qt::CaseInsensitive)) 00117 return Detached; 00118 if (!strStatus.compare("REMAP", Qt::CaseInsensitive)) 00119 return Remap; 00120 return Unknown; 00121 } 00122 00123 /** Returns a human-understandable string representation of this 00124 * stream's status. */ 00125 QString 00126 Stream::statusString() const 00127 { 00128 QString status; 00129 switch (_status) { 00130 case New: status = tr("New"); break; 00131 case NewResolve: 00132 case SentResolve: status = tr("Resolving"); break; 00133 case SentConnect: status = tr("Connecting"); break; 00134 case Succeeded: status = tr("Open"); break; 00135 case Failed: status = tr("Failed"); break; 00136 case Closed: status = tr("Closed"); break; 00137 case Detached: status = tr("Retrying"); break; 00138 case Remap: status = tr("Remapped"); break; 00139 default: status = tr("Unknown"); break; 00140 } 00141 return status; 00142 } 00143 00144 /** Returns true if all fields in this Stream object are valid. */ 00145 bool 00146 Stream::isValid() const 00147 { 00148 return (isValidStreamId(_streamId) 00149 && Circuit::isValidCircuitId(_circuitId) 00150 && (_status != Unknown) 00151 && !_address.isEmpty()); 00152 } 00153