//
// C++ Interface: c6proxysocket
//
// Description:
//
//
// Author: Giorgio A. <openc6@hotmail.com>, (C) 2005
//
// Copyright: See COPYING file that comes with this distribution
//
//
#ifndef C6PROXYSOCKET_H
#define C6PROXYSOCKET_H

#include <qsocket.h>
#include <qstring.h>

/**
Partial implementation of socks4/5 
 
@author Giorgio A.
*/

class C6ProxySocket : public QSocket
  {
    Q_OBJECT
  public:

    static const int SOCKS_VERSION_V5 = 5;
    static const int SOCKS_VERSION_V4 = 4;
    
    enum SOCKS4_COMMANDS
    {
            SOCKS4_CONNECT = 1,
            SOCKS4_BIND = 2    
    };             
    
    enum SOCKS4_REPLY
    {
            SOCKSV4_REQUEST_GRANTED = 90
    };

    enum METHODS
    {
      NO_AUTHENTICATION_REQUIRED = 0,
      GSSAPI = 1,
      USERNAME_PASSWORD = 2,
      NO_ACCEPTABLE_METHODS = 0xff
    };

    enum COMMANDS
    {
      CONNECT = 1,
      BIND = 2,
      UDP_ASSOCIATE =3
    };

    enum ATYP
    {
      IP_V4 = 1,
      DOMAIN_NAME = 3,
      IP_V6 = 4
    };

    enum PROXY_ERROR
    {
      SUCCESS = 0,
      FAILURE = 1,
      NOT_ALLOWED,
      NETWORK_UNREACHABLE,
      HOST_UNREACHABLE,
      CONNECTION_REFUSED,
      TTL_EXPIRED,
      COMMAND_NOT_SUPPORTED,
      ADDRESS_NOT_SUPPORTED,
      UNASSIGNED
    };

    enum SOCKET_ERROR
    {
      SOCK_SUCCESS = 0,
      METHOD_ERROR,
      BAD_ANSWER,
      BAD_AUTH 
    };
    
    enum AUTH
    {
        AUTH_SUCCESS,
        AUTH_NO = 1
    };

    C6ProxySocket(QObject *parent=0,bool isSock4 = false,bool hasPw=false,const char* login=0,const char* pw=0);
    void setDestConnection(QString const &ip,QString const &port,COMMANDS command = CONNECT);
    virtual void connectToHost ( const QString & host, Q_UINT16 port );

  private:
    void socketRequestV5();
    void socketRequestV4();   
    void sendLoginPassword();
    void abortConnection(QString mess, SOCKET_ERROR err);
  private slots:
    void socket_Connected();
    void socket_ReadyRead();


  private:
    int _sockState;
    int _localPort;
    QString _localIP;
    QString _login;
    QString _password; 
    bool _hasLogin; 
    bool _isSocks4;        
    bool _bind;    
    
  signals:
    void proxyConnected(const QString &ip = QString::null,int port = -1);
    void proxyError(int error);
  };

#endif
