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 QList<QHostAddress>
00041 GeoIpResolver::resolveFromCache(QList<QHostAddress> ips)
00042 {
00043 QList<GeoIp> cached;
00044
00045
00046 foreach (QHostAddress ip, ips) {
00047 if (_cache.contains(ip)) {
00048 ips.removeAt(ips.indexOf(ip));
00049 cached << _cache.geoip(ip);
00050 }
00051 }
00052
00053
00054 if (cached.size() > 0) {
00055 emit resolved(-1, cached);
00056 }
00057 return ips;
00058 }
00059
00060
00061 int
00062 GeoIpResolver::resolve(QHostAddress ip)
00063 {
00064 return resolve(QList<QHostAddress>() << ip);
00065 }
00066
00067
00068 void
00069 GeoIpResolver::connected()
00070 {
00071
00072 TorSocket *socket = (TorSocket *)sender();
00073 if (!_requestList.contains(socket)) {
00074 return;
00075 }
00076 GeoIpRequest *req = (GeoIpRequest *)_requestList.value(socket);
00077
00078
00079 socket->write(req->request());
00080 }
00081
00082
00083 void
00084 GeoIpResolver::disconnected()
00085 {
00086
00087 TorSocket *socket = (TorSocket *)sender();
00088 if (!_requestList.contains(socket)) {
00089 return;
00090 }
00091 GeoIpRequest *request = (GeoIpRequest *)_requestList.take(socket);
00092
00093
00094 GeoIpResponse response = GeoIpResponse(socket->readAll());
00095
00096
00097 if (response.statusCode() == 200) {
00098
00099 int numCached = 0;
00100 QList<GeoIp> geoips = response.geoIps();
00101 foreach (GeoIp geoip, geoips) {
00102 if (!_cache.contains(geoip.ip())) {
00103 _cache.cache(geoip);
00104 numCached++;
00105 }
00106 }
00107
00108 if (numCached > 0) {
00109 _cache.saveToDisk();
00110 }
00111
00112 emit resolved(request->id(), geoips);
00113 } else {
00114
00115
00116 emit resolveFailed(request->id(), response.statusMessage());
00117 }
00118
00119 socket->close();
00120 delete socket;
00121 delete request;
00122 }
00123
00124
00125 void
00126 GeoIpResolver::socketError(QString errorString)
00127 {
00128
00129 TorSocket *socket = (TorSocket *)sender();
00130 if (!_requestList.contains(socket)) {
00131 return;
00132 }
00133
00134
00135
00136 if (socket->error() != QAbstractSocket::RemoteHostClosedError) {
00137
00138 GeoIpRequest *request = (GeoIpRequest *)_requestList.take(socket);
00139 emit resolveFailed(request->id(), errorString);
00140 socket->abort();
00141 delete socket;
00142 delete request;
00143 }
00144 }
00145
00146
00147 GeoIpRequest*
00148 GeoIpResolver::createRequest(QList<QHostAddress> ips)
00149 {
00150 static int id = -1;
00151 GeoIpRequest *request = new GeoIpRequest(++id);
00152 request->setHost(GEOIP_HOST);
00153 request->setPage(GEOIP_PAGE);
00154 request->setRequest(ips);
00155 return request;
00156 }
00157
00158
00159 TorSocket*
00160 GeoIpResolver::createRequestSocket()
00161 {
00162 TorSocket *socket = new TorSocket(QHostAddress::LocalHost, 9050);
00163 connect(socket, SIGNAL(connectedToHost()), this, SLOT(connected()),
00164 Qt::QueuedConnection);
00165 connect(socket, SIGNAL(socketError(QString)),
00166 this, SLOT(socketError(QString)),
00167 Qt::QueuedConnection);
00168 connect(socket, SIGNAL(disconnected()), this, SLOT(disconnected()),
00169 Qt::QueuedConnection);
00170 return socket;
00171 }
00172
00173
00174 int
00175 GeoIpResolver::resolve(QList<QHostAddress> ips)
00176 {
00177
00178
00179 QList<QHostAddress> uncached = resolveFromCache(ips);
00180 if (!uncached.size()) {
00181 return -1;
00182 }
00183
00184
00185 TorSocket *socket = createRequestSocket();
00186 GeoIpRequest *request = createRequest(ips);
00187 _requestList.insert(socket, request);
00188
00189
00190 socket->connectToHost(GEOIP_HOST, 80);
00191 return request->id();
00192 }
00193