net.cpp

Go to the documentation of this file.
00001 /****************************************************************
00002  *  Vidalia is distributed under the following license:
00003  *
00004  *  Copyright (C) 2006,  Matt Edman, Justin Hipple
00005  *
00006  *  This program is free software; you can redistribute it and/or
00007  *  modify it under the terms of the GNU General Public License
00008  *  as published by the Free Software Foundation; either version 2
00009  *  of the License, or (at your option) any later version.
00010  *
00011  *  This program is distributed in the hope that it will be useful,
00012  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014  *  GNU General Public License for more details.
00015  *
00016  *  You should have received a copy of the GNU General Public License
00017  *  along with this program; if not, write to the Free Software
00018  *  Foundation, Inc., 51 Franklin Street, Fifth Floor, 
00019  *  Boston, MA  02110-1301, USA.
00020  ****************************************************************/
00021 
00022 /** 
00023  * \file net.cpp
00024  * \version $Id: net.cpp 1563 2006-12-26 06:06:04Z edmanm $
00025  * \brief Common network I/O and utility functions
00026  */
00027 
00028 #include <QTcpSocket>
00029 #include <QHostInfo>
00030 #include <QList>
00031 #include <QUrl>
00032 
00033 #include "net.h"
00034 #include "http.h"
00035 
00036 
00037 /** Returns the IP address of the local machine. */
00038 QHostAddress
00039 net_local_address()
00040 {
00041   QHostInfo localInfo = QHostInfo::fromName(QHostInfo::localHostName());
00042   if (localInfo.error() == QHostInfo::NoError) {
00043     foreach (QHostAddress addr, localInfo.addresses()) {
00044       if (addr.protocol() == QAbstractSocket::IPv4Protocol &&
00045           !(addr == QHostAddress::LocalHost)) {
00046         return addr;
00047       }
00048     }
00049   }
00050   return QHostAddress::LocalHost;
00051 }
00052 
00053 /** Returns true if the given address is a private IP address. */
00054 bool
00055 net_is_private_address(QHostAddress addr)
00056 {
00057   quint32 ip = addr.toIPv4Address();
00058   /* Based on RFC1918 and Tor's util.c */
00059   return (((ip & 0xFF000000) == 0x00000000) || /*        0/8 */
00060           ((ip & 0xFF000000) == 0x0A000000) || /*       10/8 */
00061           ((ip & 0xFF000000) == 0x7F000000) || /*      127/8 */
00062           ((ip & 0xFFF00000) == 0xAC100000) || /*  172.16/12 */
00063           ((ip & 0xFFFF0000) == 0xA9FE0000) || /* 169.254/16 */
00064           ((ip & 0xFFFF0000) == 0xC0A80000));  /* 192.168/16 */
00065 }
00066 
00067 /** Returns true if the given string representation of an IP 
00068  * address is valid. */
00069 bool
00070 net_is_valid_ip(QString ip)
00071 {
00072   return QHostAddress().setAddress(ip);
00073 }
00074 
00075 /** Returns a pre-defined, static list of servers whom we can ask for our 
00076  * public IP address. */
00077 QList<QUrl>
00078 get_check_ip_sites()
00079 {
00080   static QList<QUrl> sites;
00081   if (sites.count() == 0) {
00082     sites.append(QUrl("http://ipid.shat.net/iponly/"));
00083     sites.append(QUrl("http://freehaven.net/~edmanm/ip.php"));
00084     sites.append(QUrl("http://vidalia-project.net/iptest/ip.php"));
00085   } else {
00086     sites.append(sites.takeFirst());
00087   }
00088   return sites;
00089 }
00090 
00091 /** Asks a pre-defined list of servers what they think this machine's public
00092  * IP address is.
00093  * \param ip Stores the ip after a successful request
00094  * \return false if none of the requests were successful
00095  */
00096 bool
00097 net_get_public_ip(QString &ip)
00098 {
00099   QList<QUrl> sites = get_check_ip_sites();
00100   foreach (QUrl site, sites) {
00101     Http http(site.host());
00102     if (http.request(site.path())) {
00103       if (net_is_valid_ip(http.body())) {
00104         ip = http.body();
00105         return true;
00106       }
00107     }
00108   }
00109   return false;
00110 }
00111 
00112 /** Attempts a connection to <b>host</b> on <b>port</b>. Returns true if the
00113  * connection was successful, or false if the connection attempt failed. */
00114 bool
00115 net_test_connect(QHostAddress host, quint16 port, int timeout)
00116 {
00117   QTcpSocket sock;
00118   sock.connectToHost(host, port);
00119   if (!sock.waitForConnected(timeout)) {
00120     return false;
00121   }
00122   sock.disconnectFromHost();
00123   return true;
00124 }
00125 

Generated on Wed Sep 5 15:49:27 2007 for Vidalia by  doxygen 1.5.3