Crypto++

- Main Page
- Namespaces
- Classes
- Files

- File List
- File Members

socketft.h

    00001 #ifndef CRYPTOPP_SOCKETFT_H
    00002 #define CRYPTOPP_SOCKETFT_H
    00003
    00004 #include "config.h"
    00005
    00006 #ifdef SOCKETS_AVAILABLE
    00007
    00008 #include "network.h"
    00009 #include "queue.h"
    00010
    00011 #ifdef USE_WINDOWS_STYLE_SOCKETS
    00012 #   if defined(_WINSOCKAPI_) && !defined(_WINSOCK2API_)
    00013 #       error Winsock 1 is not supported by this library. Please include this file or winsock2.h before windows.h.
    00014 #   endif
    00015 #include <winsock2.h>
    00016 #include "winpipes.h"
    00017 #else
    00018 #include <sys/time.h>
    00019 #include <sys/types.h>
    00020 #include <sys/socket.h>
    00021 #include <unistd.h>
    00022 #endif
    00023
    00024 NAMESPACE_BEGIN(CryptoPP)
    00025
    00026 #ifdef USE_WINDOWS_STYLE_SOCKETS
    00027 typedef ::SOCKET socket_t;
    00028 #else
    00029 typedef int socket_t;
    00030 const socket_t INVALID_SOCKET = -1;
    00031 // cygwin 1.1.4 doesn't have SHUT_RD
    00032 const int SD_RECEIVE = 0;
    00033 const int SD_SEND = 1;
    00034 const int SD_BOTH = 2;
    00035 const int SOCKET_ERROR = -1;
    00036 #endif
    00037
    00038 #ifndef socklen_t
    00039 typedef TYPE_OF_SOCKLEN_T socklen_t;    // see config.h
    00040 #endif
    00041
    00042 //! wrapper for Windows or Berkeley Sockets
    00043 class Socket
    00044 {
    00045 public:
    00046     //! exception thrown by Socket class
    00047     class Err : public OS_Error
    00048     {
    00049     public:
    00050         Err(socket_t s, const std::string& operation, int error);
    00051         socket_t GetSocket() const {return m_s;}
    00052
    00053     private:
    00054         socket_t m_s;
    00055     };
    00056
    00057     Socket(socket_t s = INVALID_SOCKET, bool own=false) : m_s(s), m_own(own) {}
    00058     Socket(const Socket &s) : m_s(s.m_s), m_own(false) {}
    00059     virtual ~Socket();
    00060
    00061     bool GetOwnership() const {return m_own;}
    00062     void SetOwnership(bool own) {m_own = own;}
    00063
    00064     operator socket_t() {return m_s;}
    00065     socket_t GetSocket() const {return m_s;}
    00066     void AttachSocket(socket_t s, bool own=false);
    00067     socket_t DetachSocket();
    00068     void CloseSocket();
    00069
    00070     void Create(int nType = SOCK_STREAM);
    00071     void Bind(unsigned int port, const char *addr=NULL);
    00072     void Bind(const sockaddr* psa, socklen_t saLen);
    00073     void Listen(int backlog=5);
    00074     // the next three functions return false if the socket is in nonblocking mode
    00075     // and the operation cannot be completed immediately
    00076     bool Connect(const char *addr, unsigned int port);
    00077     bool Connect(const sockaddr* psa, socklen_t saLen);
    00078     bool Accept(Socket& s, sockaddr *psa=NULL, socklen_t *psaLen=NULL);
    00079     void GetSockName(sockaddr *psa, socklen_t *psaLen);
    00080     void GetPeerName(sockaddr *psa, socklen_t *psaLen);
    00081     unsigned int Send(const byte* buf, size_t bufLen, int flags=0);
    00082     unsigned int Receive(byte* buf, size_t bufLen, int flags=0);
    00083     void ShutDown(int how = SD_SEND);
    00084
    00085     void IOCtl(long cmd, unsigned long *argp);
    00086     bool SendReady(const timeval *timeout);
    00087     bool ReceiveReady(const timeval *timeout);
    00088
    00089     virtual void HandleError(const char *operation) const;
    00090     void CheckAndHandleError_int(const char *operation, int result) const
    00091         {if (result == SOCKET_ERROR) HandleError(operation);}
    00092     void CheckAndHandleError(const char *operation, socket_t result) const
    00093         {if (result == SOCKET_ERROR) HandleError(operation);}
    00094 #ifdef USE_WINDOWS_STYLE_SOCKETS
    00095     void CheckAndHandleError(const char *operation, BOOL result) const
    00096         {assert(result==TRUE || result==FALSE); if (!result) HandleError(operation);}
    00097     void CheckAndHandleError(const char *operation, bool result) const
    00098         {if (!result) HandleError(operation);}
    00099 #endif
    00100
    00101     //! look up the port number given its name, returns 0 if not found
    00102     static unsigned int PortNameToNumber(const char *name, const char *protocol="tcp");
    00103     //! start Windows Sockets 2
    00104     static void StartSockets();
    00105     //! calls WSACleanup for Windows Sockets
    00106     static void ShutdownSockets();
    00107     //! returns errno or WSAGetLastError
    00108     static int GetLastError();
    00109     //! sets errno or calls WSASetLastError
    00110     static void SetLastError(int errorCode);
    00111
    00112 protected:
    00113     virtual void SocketChanged() {}
    00114
    00115     socket_t m_s;
    00116     bool m_own;
    00117 };
    00118
    00119 class SocketsInitializer
    00120 {
    00121 public:
    00122     SocketsInitializer() {Socket::StartSockets();}
    00123     ~SocketsInitializer() {try {Socket::ShutdownSockets();} catch (...) {}}
    00124 };
    00125
    00126 class SocketReceiver : public NetworkReceiver
    00127 {
    00128 public:
    00129     SocketReceiver(Socket &s);
    00130
    00131 #ifdef USE_BERKELEY_STYLE_SOCKETS
    00132     bool MustWaitToReceive() {return true;}
    00133 #else
    00134     ~SocketReceiver();
    00135     bool MustWaitForResult() {return true;}
    00136 #endif
    00137     bool Receive(byte* buf, size_t bufLen);
    00138     unsigned int GetReceiveResult();
    00139     bool EofReceived() const {return m_eofReceived;}
    00140
    00141     unsigned int GetMaxWaitObjectCount() const {return 1;}
    00142     void GetWaitObjects(WaitObjectContainer &container, CallStack const& callStack);
    00143
    00144 private:
    00145     Socket &m_s;
    00146     bool m_eofReceived;
    00147
    00148 #ifdef USE_WINDOWS_STYLE_SOCKETS
    00149     WindowsHandle m_event;
    00150     OVERLAPPED m_overlapped;
    00151     bool m_resultPending;
    00152     DWORD m_lastResult;
    00153 #else
    00154     unsigned int m_lastResult;
    00155 #endif
    00156 };
    00157
    00158 class SocketSender : public NetworkSender
    00159 {
    00160 public:
    00161     SocketSender(Socket &s);
    00162
    00163 #ifdef USE_BERKELEY_STYLE_SOCKETS
    00164     bool MustWaitToSend() {return true;}
    00165 #else
    00166     ~SocketSender();
    00167     bool MustWaitForResult() {return true;}
    00168     bool MustWaitForEof() { return true; }
    00169     bool EofSent();
    00170 #endif
    00171     void Send(const byte* buf, size_t bufLen);
    00172     unsigned int GetSendResult();
    00173     void SendEof();
    00174
    00175     unsigned int GetMaxWaitObjectCount() const {return 1;}
    00176     void GetWaitObjects(WaitObjectContainer &container, CallStack const& callStack);
    00177
    00178 private:
    00179     Socket &m_s;
    00180 #ifdef USE_WINDOWS_STYLE_SOCKETS
    00181     WindowsHandle m_event;
    00182     OVERLAPPED m_overlapped;
    00183     bool m_resultPending;
    00184     DWORD m_lastResult;
    00185 #else
    00186     unsigned int m_lastResult;
    00187 #endif
    00188 };
    00189
    00190 //! socket-based implementation of NetworkSource
    00191 class SocketSource : public NetworkSource, public Socket
    00192 {
    00193 public:
    00194     SocketSource(socket_t s = INVALID_SOCKET, bool pumpAll = false, BufferedTransformation *attachment = NULL)
    00195         : NetworkSource(attachment), Socket(s), m_receiver(*this)
    00196     {
    00197         if (pumpAll)
    00198             PumpAll();
    00199     }
    00200
    00201 private:
    00202     NetworkReceiver & AccessReceiver() {return m_receiver;}
    00203     SocketReceiver m_receiver;
    00204 };
    00205
    00206 //! socket-based implementation of NetworkSink
    00207 class SocketSink : public NetworkSink, public Socket
    00208 {
    00209 public:
    00210     SocketSink(socket_t s=INVALID_SOCKET, unsigned int maxBufferSize=0, unsigned int autoFlushBound=16*1024)
    00211         : NetworkSink(maxBufferSize, autoFlushBound), Socket(s), m_sender(*this) {}
    00212
    00213     void SendEof() {ShutDown(SD_SEND);}
    00214
    00215 private:
    00216     NetworkSender & AccessSender() {return m_sender;}
    00217     SocketSender m_sender;
    00218 };
    00219
    00220 NAMESPACE_END
    00221
    00222 #endif  // #ifdef SOCKETS_AVAILABLE
    00223
    00224 #endif