torsocket.cpp
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 #include <QDataStream>
00018
00019 #include "torsocket.h"
00020
00021 #define SOCKS_VERSION 0x04
00022 #define SOCKS_CONNECT 0x01
00023 #define SOCKS_FAKE_IP 0x00000001
00024 #define SOCKS_RESPONSE_LEN 0x08
00025 #define SOCKS_RESPONSE_VERSION 0x00
00026 #define SOCKS_CONNECT_STATUS_OK 0x5A
00027
00028
00029
00030 TorSocket::TorSocket(const QHostAddress &socksAddr,
00031 quint16 socksPort, QObject *parent)
00032 : QTcpSocket(parent),
00033 _socksAddr(socksAddr),
00034 _socksPort(socksPort)
00035 {
00036 QObject::connect(this, SIGNAL(error(QAbstractSocket::SocketError)),
00037 this, SLOT(onError(QAbstractSocket::SocketError)));
00038 QObject::connect(this, SIGNAL(readyRead()),
00039 this, SLOT(onHandshakeResponse()));
00040 QObject::connect(this, SIGNAL(connected()),
00041 this, SLOT(connectedToProxy()));
00042 }
00043
00044
00045 void
00046 TorSocket::connectToRemoteHost(const QString &remoteHost, quint16 remotePort)
00047 {
00048 _remoteHost = remoteHost;
00049 _remotePort = remotePort;
00050 QTcpSocket::connectToHost(_socksAddr, _socksPort);
00051 }
00052
00053
00054 void
00055 TorSocket::onError(QAbstractSocket::SocketError error)
00056 {
00057 Q_UNUSED(error);
00058 emit socketError(errorString());
00059 }
00060
00061
00062
00063 void
00064 TorSocket::connectedToProxy()
00065 {
00066 sendSocksHandshake(_remoteHost, _remotePort);
00067 }
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081 void
00082 TorSocket::sendSocksHandshake(const QString &remoteHost, quint16 remotePort)
00083 {
00084 QDataStream sock(this);
00085 sock << (quint8)SOCKS_VERSION;
00086 sock << (quint8)SOCKS_CONNECT;
00087 sock << (quint16)remotePort;
00088 sock << (quint32)SOCKS_FAKE_IP;
00089 sock << (quint8)0;
00090 sock.writeRawData(qPrintable(remoteHost), remoteHost.length());
00091 sock << (quint8)0;
00092 }
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102 void
00103 TorSocket::onHandshakeResponse()
00104 {
00105 QByteArray response;
00106 if (bytesAvailable() >= SOCKS_RESPONSE_LEN) {
00107
00108 QObject::disconnect(this, SIGNAL(readyRead()),
00109 this, SLOT(onHandshakeResponse()));
00110
00111
00112 response = read(SOCKS_RESPONSE_LEN);
00113
00114
00115 if ((uchar)response[0] == (uchar)SOCKS_RESPONSE_VERSION &&
00116 (uchar)response[1] == (uchar)SOCKS_CONNECT_STATUS_OK) {
00117
00118 emit connectedToRemoteHost();
00119 } else {
00120
00121 disconnectFromHost();
00122 }
00123 }
00124 }
00125