00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028 #include "geoipresolver.h"
00029
00030
00031
00032
00033 #define GEOIP_HOST "geoip.vidalia-project.net"
00034
00035 #define GEOIP_PAGE "/cgi-bin/geoip"
00036
00037
00038
00039
00040 void
00041 GeoIpResolver::setSocksHost(QHostAddress addr, quint16 port)
00042 {
00043 _socksAddr = addr;
00044 _socksPort = port;
00045 }
00046
00047
00048
00049
00050 bool
00051 GeoIpResolver::resolveFromCache(QHostAddress ip)
00052 {
00053 if (_cache.contains(ip)) {
00054 emit resolved(-1, QList<GeoIp>() << _cache.geoip(ip));
00055 return true;
00056 }
00057 return false;
00058 }
00059
00060
00061
00062 QList<QHostAddress>
00063 GeoIpResolver::resolveFromCache(QList<QHostAddress> ips)
00064 {
00065 QList<GeoIp> cached;
00066
00067
00068 foreach (QHostAddress ip, ips) {
00069 if (_cache.contains(ip)) {
00070 ips.removeAt(ips.indexOf(ip));
00071 cached << _cache.geoip(ip);
00072 }
00073 }
00074
00075
00076 if (cached.size() > 0) {
00077 emit resolved(-1, cached);
00078 }
00079 return ips;
00080 }
00081
00082
00083 int
00084 GeoIpResolver::resolve(QHostAddress ip)
00085 {
00086 return resolve(QList<QHostAddress>() << ip);
00087 }
00088
00089
00090 void
00091 GeoIpResolver::connected()
00092 {
00093
00094 TorSocket *socket = (TorSocket *)sender();
00095 if (!_requestList.contains(socket)) {
00096 return;
00097 }
00098 GeoIpRequest *req = (GeoIpRequest *)_requestList.value(socket);
00099
00100
00101 socket->write(req->request());
00102 }
00103
00104
00105 void
00106 GeoIpResolver::disconnected()
00107 {
00108
00109 TorSocket *socket = (TorSocket *)sender();
00110 if (!_requestList.contains(socket)) {
00111 return;
00112 }
00113 GeoIpRequest *request = (GeoIpRequest *)_requestList.take(socket);
00114
00115
00116 GeoIpResponse response = GeoIpResponse(socket->readAll());
00117
00118
00119 if (response.statusCode() == 200) {
00120
00121 int numCached = 0, i = 0;
00122 QList<GeoIp> geoips = response.geoIps();
00123 foreach (GeoIp geoip, geoips) {
00124 QHostAddress ip = geoip.ip();
00125
00126 if (request->contains(ip)) {
00127
00128
00129 if (!_cache.contains(ip)) {
00130 _cache.cache(geoip);
00131 numCached++;
00132 }
00133 i++;
00134 } else {
00135
00136
00137
00138
00139
00140 geoips.removeAt(i);
00141 }
00142 }
00143
00144 if (numCached > 0) {
00145 _cache.saveToDisk();
00146 }
00147
00148 emit resolved(request->id(), geoips);
00149 } else {
00150
00151
00152 emit resolveFailed(request->id(), response.statusMessage());
00153 }
00154
00155 socket->close();
00156 delete socket;
00157 delete request;
00158 }
00159
00160
00161 void
00162 GeoIpResolver::socketError(QString errorString)
00163 {
00164
00165 TorSocket *socket = (TorSocket *)sender();
00166 if (!_requestList.contains(socket)) {
00167 return;
00168 }
00169
00170
00171
00172 if (socket->error() != QAbstractSocket::RemoteHostClosedError) {
00173
00174 GeoIpRequest *request = (GeoIpRequest *)_requestList.take(socket);
00175 emit resolveFailed(request->id(), errorString);
00176 socket->abort();
00177 delete socket;
00178 delete request;
00179 }
00180 }
00181
00182
00183 GeoIpRequest*
00184 GeoIpResolver::createRequest(QList<QHostAddress> ips)
00185 {
00186 static int id = -1;
00187 GeoIpRequest *request = new GeoIpRequest(++id);
00188 request->setHost(GEOIP_HOST);
00189 request->setPage(GEOIP_PAGE);
00190 request->setRequest(ips);
00191 return request;
00192 }
00193
00194
00195 TorSocket*
00196 GeoIpResolver::createRequestSocket()
00197 {
00198 TorSocket *socket = new TorSocket(_socksAddr, _socksPort);
00199 connect(socket, SIGNAL(connectedToHost()), this, SLOT(connected()),
00200 Qt::QueuedConnection);
00201 connect(socket, SIGNAL(socketError(QString)),
00202 this, SLOT(socketError(QString)),
00203 Qt::QueuedConnection);
00204 connect(socket, SIGNAL(disconnected()), this, SLOT(disconnected()),
00205 Qt::QueuedConnection);
00206 return socket;
00207 }
00208
00209
00210 int
00211 GeoIpResolver::resolve(QList<QHostAddress> ips)
00212 {
00213
00214
00215 QList<QHostAddress> uncached = resolveFromCache(ips);
00216 if (!uncached.size()) {
00217 return -1;
00218 }
00219
00220
00221 TorSocket *socket = createRequestSocket();
00222 GeoIpRequest *request = createRequest(ips);
00223 _requestList.insert(socket, request);
00224
00225
00226 socket->connectToHost(GEOIP_HOST, 80);
00227 return request->id();
00228 }
00229