/** ** 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 #include #include #include "socket_include.h" #include class SocketHandler; class SocketThread; // typedef std::list 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