// This may look like C code, but it is really -*- C++ -*-
// 
// <copyright> 
//  
//  Copyright (c) 1996
//  Institute for Information Processing and Computer Supported New Media (IICM), 
//  Graz University of Technology, Austria. 
//  
// </copyright> 
// 
// 
// <file> 
// 
// Name:        tifsocks4.h
// 
// Purpose:     
// 
// Created:     6 Jan 1997   Joerg Faschingbauer
// 
// Modified:    
// 
// Description: 
// 
// $Id: tifsocks4.h,v 1.3 1997/02/21 16:23:13 jfasch Exp $
// 
// $Log: tifsocks4.h,v $
// Revision 1.3  1997/02/21 16:23:13  jfasch
// SOCKS4Match --> TCPMatch (in utils)
//
// Revision 1.2  1997/02/12 23:13:11  jfasch
// moved from HgDcCommon
//
// Revision 1.1  1997/02/04 13:48:16  jfasch
// Initial revision
//
// 
// </file> 
#ifndef hg_dispatch_tifsocks4_h
#define hg_dispatch_tifsocks4_h

#include "tifdirect.h"

#include <hyperg/utils/buffer.h>
#include <hyperg/utils/inetaddr.h>
#include <hyperg/utils/str.h>
#include <hyperg/utils/tcpmatch.h>

class TIOINETFactorySOCKS4 : public TIOINETFactory, public TIOINETFactoryUser, public TransparentIOHandler {
public:
   TIOINETFactorySOCKS4 (const INETAddress& server, const TCPMatch&, const RString& userid) ;
   virtual ~TIOINETFactorySOCKS4() ;

   virtual void start() {}
   virtual void stop() {}

   virtual TIOINETResponsePtr connect (const TIOINETRequestPtr&) ;

private:
   // TIOINETFactoryUser: I am the user of the "direct maker" of mine
   // which I use to connect to the socks server.
   virtual void tioInetResponse (const TIOINETResponsePtr&) ;

   // TransparentIOHandler stuff: I write the SOCKS4 requests out onto
   // the connections, and read their associated replies.
   virtual void inputReady (const TransparentIO*) ;
   virtual void outputReady (const TransparentIO*) ;

   // utilities 
   TIOINETResponsePtr make_blocking_(const TIOINETRequestPtr&) ;
   TIOINETResponsePtr make_nonblocking_(const TIOINETRequestPtr&) ;

   // the cancel routine, abstractly inherited from TIOINETFactory.
   virtual void do_cancel_(const TIOINETRequest*) ;

private:
   const INETAddress server_ ;
   const TCPMatch match_ ;
   const RString uid_ ;

   // to establish the connection to the SOCKS server
   TIOINETFactoryDirect to_server_ ;

   // these lists (or whatever it is) reflect the "states" of my
   // requests.

   // herein the "first stage requests" are stored. i.e. a mapping
   // between the original requests (issued by my users) on one side,
   // and the requests issued by me at my "direct maker" on the other
   // side.
   class ConnWait* conn_wait_ ;

   // the second stage. the original request on one side (I have to
   // have it searchable at every point in time because my user may
   // want to cancel it), and the TIO with the output buffer (the
   // formatted SOCKS request) on the other side.
   class OutWait* out_wait_ ;

   // the tihrd stage. again the original request; on the other side
   // there\'s again the TIO, this time with a SOCKS reply that has to
   // be filled.
   class InWait* in_wait_ ;

   // a helper for my blocking stuff.
   OBuffer buf_ ;

private:
   TIOINETFactorySOCKS4 (const TIOINETFactorySOCKS4&) {}
   TIOINETFactorySOCKS4& operator = (const TIOINETFactorySOCKS4&) { return *this; }
                                
public:
   static Verbose verbose ;
   // link time assertion 
   static const char* version1 ;
} ;
static const char* TIOINETFactorySOCKS4_version = TIOINETFactorySOCKS4::version1 ;

#endif
