/**
** File ......... Socket.h
** Published .... 2004-02-13
** Author ....... grymse@alhem.net
**/
/*
Copyright (C) 2004,2005 Anders Hedstrom
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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#ifndef _SOCKETBASE_H
#define _SOCKETBASE_H
#include <string>
#include <vector>
#include <list>
#include "socket_include.h"
#include <time.h>
class SocketHandler;
class SocketThread;
// typedef std::list<std::string> string_v;
class Socket
{
friend class SocketHandler;
public:
/** "Default" constructor */
Socket(SocketHandler&);
virtual ~Socket();
/** Socket class instantiation method. Used when a "non-standard" constructor
* needs to be used for the socket class. Note: the socket class still needs
* the "default" constructor with one SocketHandler& as input parameter.
*/
virtual Socket *Create() { return NULL; }
/** Init: CTcpSocket uses this to create its ICrypt member variable.
* The ICrypt member variable is created by a virtual method, therefore
* it can't be called directly from the CTcpSocket constructor.
* Also used to determine if incoming HTTP connection is normal (port 80)
* or ssl (port 443).
*/
virtual void Init();
void Attach(SOCKET s);
SOCKET GetSocket();
virtual int Close();
SOCKET CreateSocket4(int type,const std::string& protocol = "");
SOCKET CreateSocket6(int type,const std::string& protocol = "");
void Set(bool bRead,bool bWrite,bool bException = true);
bool Ready();
/** Called when there is something to be read from the file descriptor. */
virtual void OnRead();
/** Called when there is room for another write on the file descriptor. */
virtual void OnWrite();
/** Called on socket exception. */
virtual void OnException();
/** Called before a socket class is deleted by the SocketHandler. */
virtual void OnDelete();
/** Called when a connection has completed. */
virtual void OnConnect();
/** Called when an incoming connection has been completed. */
virtual void OnAccept();
/** Called when a complete line has been read and the socket is in
* line protocol mode. */
virtual void OnLine(const std::string& );
/** Used internally by SSLSocket. */
virtual void OnSSLInitDone();
/** Called on connect timeout (5s). */
virtual void OnConnectFailed();
/** Called when a socket is created, to set socket options. */
virtual void OnOptions(int family,int type,int protocol,SOCKET);
/** Socks4 client support internal use. @see TcpSocket */
virtual void OnSocks4Connect();
/** Socks4 client support internal use. @see TcpSocket */
virtual void OnSocks4ConnectFailed();
/** Socks4 client support internal use. @see TcpSocket */
virtual bool OnSocks4Read();
/** Called when the last write caused the tcp output buffer to
* become empty. */
// virtual void OnWriteComplete();
/** SSL client/server support - internal use. @see TcpSocket */
virtual void OnSSLConnect() {}
/** SSL client/server support - internal use. @see TcpSocket */
virtual void OnSSLAccept() {}
virtual bool CheckConnect();
virtual void ReadLine();
/** OLD SSL support. */
virtual bool SSLCheckConnect();
/** new SSL support */
virtual bool SSLNegotiate() { return false; }
void SetSSLConnecting(bool = true);
bool SSLConnecting();
/** Enable the OnLine callback. Do not create your own OnRead
* callback when using this. */
void SetLineProtocol(bool = true);
bool LineProtocol();
void SetDeleteByHandler(bool = true);
bool DeleteByHandler();
void SetCloseAndDelete(bool = true);
bool CloseAndDelete();
void SetConnecting(bool = true);
bool Connecting();
time_t GetConnectTime();
/** ipv4 and ipv6 */
bool isip(const std::string&);
/** ipv4 */
bool u2ip(const std::string&, ipaddr_t&);
/** ipv6 */
#ifdef IPPROTO_IPV6
bool u2ip(const std::string&, struct in6_addr&);
#endif
/** ipv4 */
void l2ip(const ipaddr_t,std::string& );
/** ipv6 */
#ifdef IPPROTO_IPV6
void l2ip(const struct in6_addr&,std::string& ,bool mixed = false);
#endif
/** ipv4 and ipv6 */
void SetRemoteAddress(struct sockaddr* sa,socklen_t);
void GetRemoteSocketAddress(struct sockaddr& sa,socklen_t& sa_len);
/** ipv4 */
ipaddr_t GetRemoteIP4();
/** ipv6 */
#ifdef IPPROTO_IPV6
struct in6_addr GetRemoteIP6();
#endif
/** ipv4 and ipv6 */
port_t GetRemotePort();
/** ipv4 and ipv6 */
std::string GetRemoteAddress();
/** ipv4 and ipv6(not implemented) */
std::string GetRemoteHostname();
SocketHandler& Handler() const;
bool SetNonblocking(bool);
bool SetNonblocking(bool, SOCKET);
time_t Uptime() { return time(NULL) - m_tCreate; }
/*
void SetTimeout(time_t x) { m_timeout = x; }
time_t Timeout() { return m_timeout; }
void Touch() { m_tActive = time(NULL); }
time_t Inactive() { return time(NULL) - m_tActive; }
*/
virtual void OnDetached() {} // Threading
void SetDetach(bool x = true) { m_detach = x; }
bool IsDetach() { return m_detach; }
void SetDetached(bool x = true) { m_detached = x; }
bool IsDetached() { return m_detached; }
bool Detach();
void SetIpv6(bool x = true) { m_ipv6 = x; }
bool IsIpv6() { return m_ipv6; }
/** Returns pointer to ListenSocket that created this instance
* on an incoming connections. */
Socket *GetParent();
/** Used by ListenSocket to set parent pointer of newly created
* socket instance. */
void SetParent(Socket *);
/** Get listening port from ListenSocket<>. */
virtual port_t GetPort();
// pooling
void SetIsClient() { m_bClient = true; }
void SetSocketType(int x) { m_socket_type = x; }
int GetSocketType() { return m_socket_type; }
void SetSocketProtocol(const std::string& x) { m_socket_protocol = x; }
const std::string& GetSocketProtocol() { return m_socket_protocol; }
void SetClientRemoteAddr(ipaddr_t a) { m_client_remote_addr = a; }
ipaddr_t& GetClientRemoteAddr() { return m_client_remote_addr; }
void SetClientRemotePort(port_t p) { m_client_remote_port = p; }
port_t GetClientRemotePort() { return m_client_remote_port; }
void SetRetain() { if (m_bClient) m_bRetain = true; }
bool Retain() { return m_bRetain; }
void SetLost() { m_bLost = true; }
bool Lost() { return m_bLost; }
void SetCallOnConnect(bool x = true) { m_call_on_connect = x; }
bool CallOnConnect() { return m_call_on_connect; }
// copy connection parameters from sock
void CopyConnection(Socket *sock);
void SetReuse(bool x) { m_opt_reuse = x; }
void SetKeepalive(bool x) { m_opt_keepalive = x; }
// dns
int Resolve(const std::string& host,port_t port);
virtual void Resolved(int id,ipaddr_t,port_t);
/** socket still in socks4 negotiation mode */
bool Socks4() { return m_bSocks4; }
void SetSocks4(bool x = true) { m_bSocks4 = x; }
void SetSocks4Host(ipaddr_t a) { m_socks4_host = a; }
void SetSocks4Host(const std::string& );
void SetSocks4Port(port_t p) { m_socks4_port = p; }
void SetSocks4Userid(const std::string& x) { m_socks4_userid = x; }
ipaddr_t GetSocks4Host() { return m_socks4_host; }
port_t GetSocks4Port() { return m_socks4_port; }
const std::string& GetSocks4Userid() { return m_socks4_userid; }
void SetConnectTimeout(int x) { m_connect_timeout = x; }
int GetConnectTimeout() { return m_connect_timeout; }
/** SSL Enabled */
bool IsSSL() { return m_b_enable_ssl; }
void EnableSSL(bool x = true) { m_b_enable_ssl = x; }
/** Still negotiating ssl connection */
bool IsSSLNegotiate() { return m_b_ssl; }
void SetSSLNegotiate(bool x = true) { m_b_ssl = x; }
/** OnAccept called with SSL Enabled */
bool IsSSLServer() { return m_b_ssl_server; }
void SetSSLServer(bool x = true) { m_b_ssl_server = x; }
void DisableRead(bool x = true) { m_b_disable_read = x; }
bool IsDisableRead() { return m_b_disable_read; }
protected:
Socket(const Socket& ); // do not allow use of copy constructor
void DetachSocket(); // protected, friend class SocketHandler;
private:
/** default constructor not available */
Socket() : m_handler(Handler()) {}
#ifdef _WIN32
static WSAInitializer m_winsock_init;
#endif
Socket& operator=(const Socket& ) { return *this; }
//
SocketHandler& m_handler;
SOCKET m_socket;
bool m_bDel;
bool m_bClose;
bool m_bConnecting;
time_t m_tConnect;
time_t m_tCreate;
bool m_line_protocol;
bool m_ssl_connecting;
// time_t m_tActive;
// time_t m_timeout;
bool m_detach;
bool m_detached;
SocketThread *m_pThread;
bool m_ipv6;
struct sockaddr m_sa; // remote, from accept
socklen_t m_sa_len;
Socket *m_parent;
// pooling, ipv4
int m_socket_type;
std::string m_socket_protocol;
bool m_bClient; // only client connections are pooled
ipaddr_t m_client_remote_addr;
port_t m_client_remote_port;
bool m_bRetain; // keep connection on close
bool m_bLost; // connection lost
bool m_call_on_connect;
bool m_opt_reuse;
bool m_opt_keepalive;
bool m_bSocks4; // socks4 negotiation mode (TcpSocket)
ipaddr_t m_socks4_host;
port_t m_socks4_port;
std::string m_socks4_userid;
int m_connect_timeout;
bool m_b_enable_ssl;
bool m_b_ssl; // ssl negotiation mode (TcpSocket)
bool m_b_ssl_server;
bool m_b_disable_read;
};
#endif // _SOCKETBASE_H
syntax highlighted by Code2HTML, v. 0.9.1