You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
186 lines
5.5 KiB
186 lines
5.5 KiB
/***************************************************************************
|
|
* Copyright (C) 2005 by Joris Guisson *
|
|
* joris.guisson@gmail.com *
|
|
* *
|
|
* This program is free software; you can redistribute it and/or modify *
|
|
* it under the terms of the GNU General Public License as published by *
|
|
* the Free Software Foundation; either version 2 of the License, or *
|
|
* (at your option) any later version. *
|
|
* *
|
|
* This program is distributed in the hope that it will be useful, *
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
|
* GNU General Public License for more details. *
|
|
* *
|
|
* You should have received a copy of the GNU General Public License *
|
|
* along with this program; if not, write to the *
|
|
* Free Software Foundation, Inc., *
|
|
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
|
|
***************************************************************************/
|
|
#ifndef MSESTREAMSOCKET_H
|
|
#define MSESTREAMSOCKET_H
|
|
|
|
#include <qobject.h>
|
|
#include <util/constants.h>
|
|
#include <net/bufferedsocket.h>
|
|
|
|
class QString;
|
|
|
|
using bt::Uint8;
|
|
using bt::Uint16;
|
|
using bt::Uint32;
|
|
|
|
namespace bt
|
|
{
|
|
class SHA1Hash;
|
|
class Peer;
|
|
class AuthenticateBase;
|
|
}
|
|
|
|
namespace mse
|
|
{
|
|
class RC4Encryptor;
|
|
|
|
|
|
|
|
|
|
/**
|
|
* @author Joris Guisson <joris.guisson@gmail.com>
|
|
*
|
|
* Wrapper around a TCP socket which handles RC4 encryption.
|
|
* Once authentication is done, the sendData and readData interfaces should
|
|
* not be used anymore, a SocketReader and SocketWriter should be provided,
|
|
* so that reading and writing is controlled from the monitor thread.
|
|
*/
|
|
class StreamSocket : public QObject,public net::SocketReader,public net::SocketWriter
|
|
{
|
|
Q_OBJECT
|
|
public:
|
|
StreamSocket();
|
|
StreamSocket(int fd);
|
|
virtual ~StreamSocket();
|
|
|
|
/**
|
|
* Send a chunk of data. (Does not encrypt the data)
|
|
* @param data The data
|
|
* @param len The length
|
|
* @return Number of bytes written
|
|
*/
|
|
Uint32 sendData(const Uint8* data,Uint32 len);
|
|
|
|
/**
|
|
* Reads data from the peer.
|
|
* @param buf The buffer to store the data
|
|
* @param len The maximum number of bytes to read
|
|
* @return The number of bytes read
|
|
*/
|
|
Uint32 readData(Uint8* buf,Uint32 len);
|
|
|
|
/// Get the number of bytes available to read.
|
|
Uint32 bytesAvailable() const;
|
|
|
|
/// Are we using encryption
|
|
bool encrypted() const {return enc != 0;}
|
|
|
|
/**
|
|
* Initialize the RC4 encryption algorithm.
|
|
* @param dkey
|
|
* @param ekey
|
|
*/
|
|
void initCrypt(const bt::SHA1Hash & dkey,const bt::SHA1Hash & ekey);
|
|
|
|
/// Set the encryptor
|
|
void setRC4Encryptor(RC4Encryptor* enc);
|
|
|
|
/// Disables encryption. All data will be sent over as plain text.
|
|
void disableCrypt();
|
|
|
|
/// Close the socket
|
|
void close();
|
|
|
|
/// Connect the socket to a remote host
|
|
bool connectTo(const QString & ip,Uint16 port);
|
|
|
|
/// Get the IP address of the remote peer
|
|
QString getRemoteIPAddress() const;
|
|
|
|
/// Get the port of the remote peer
|
|
bt::Uint16 getRemotePort() const;
|
|
|
|
/// Get the full address
|
|
net::Address getRemoteAddress() const;
|
|
|
|
/**
|
|
* Reinsert data, this is needed when we read to much during the crypto handshake.
|
|
* This data will be the first to read out. The data will be copied to a temporary buffer
|
|
* which will be destroyed when the reinserted data has been read.
|
|
*/
|
|
void reinsert(const Uint8* d,Uint32 size);
|
|
|
|
/// see if the socket is still OK
|
|
bool ok() const;
|
|
|
|
/// Get the file descriptor
|
|
int fd() const {return sock->fd();}
|
|
|
|
/// Start monitoring of this socket by the monitor thread
|
|
void startMonitoring(net::SocketReader* rdr,net::SocketWriter* wrt);
|
|
|
|
/// Is this socket connecting to a remote host
|
|
bool connecting() const;
|
|
|
|
/// See if a connect was success full
|
|
bool connectSuccesFull() const;
|
|
|
|
/// Get the current download rate
|
|
float getDownloadRate() const;
|
|
|
|
/// Get the current download rate
|
|
float getUploadRate() const;
|
|
|
|
/**
|
|
* Set the TOS byte for new sockets.
|
|
* @param t TOS value
|
|
*/
|
|
static void setTOS(Uint8 t) {tos = t;}
|
|
|
|
/**
|
|
* Set the download and upload group ID's
|
|
* @param up Upload group ID
|
|
* @param down Download group ID
|
|
*/
|
|
void setGroupIDs(Uint32 up,Uint32 down);
|
|
|
|
/**
|
|
* Check if we are allowed to initiate another outgoing connection.
|
|
*/
|
|
static bool canInitiateNewConnection() {return num_connecting < max_connecting;}
|
|
|
|
/**
|
|
* Set the maximum number of connecting sockets we are allowed to have.
|
|
*/
|
|
static void setMaxConnecting(Uint32 mc) {max_connecting = mc;}
|
|
private:
|
|
virtual void onDataReady(Uint8* buf,Uint32 size);
|
|
virtual Uint32 onReadyToWrite(Uint8* data,Uint32 max_to_write);
|
|
virtual bool hasBytesToWrite() const;
|
|
|
|
private:
|
|
net::BufferedSocket* sock;
|
|
RC4Encryptor* enc;
|
|
Uint8* reinserted_data;
|
|
Uint32 reinserted_data_size;
|
|
Uint32 reinserted_data_read;
|
|
bool monitored;
|
|
net::SocketReader* rdr;
|
|
net::SocketWriter* wrt;
|
|
|
|
static Uint8 tos;
|
|
static Uint32 num_connecting; // the number of connections we have in SYN_SENT state
|
|
static Uint32 max_connecting;
|
|
};
|
|
|
|
}
|
|
|
|
#endif
|