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 #endif
00098 
00099         //! look up the port number given its name, returns 0 if not found
00100         static unsigned int PortNameToNumber(const char *name, const char *protocol="tcp");
00101         //! start Windows Sockets 2
00102         static void StartSockets();
00103         //! calls WSACleanup for Windows Sockets
00104         static void ShutdownSockets();
00105         //! returns errno or WSAGetLastError
00106         static int GetLastError();
00107         //! sets errno or calls WSASetLastError
00108         static void SetLastError(int errorCode);
00109 
00110 protected:
00111         virtual void SocketChanged() {}
00112 
00113         socket_t m_s;
00114         bool m_own;
00115 };
00116 
00117 class SocketsInitializer
00118 {
00119 public:
00120         SocketsInitializer() {Socket::StartSockets();}
00121         ~SocketsInitializer() {try {Socket::ShutdownSockets();} catch (...) {}}
00122 };
00123 
00124 class SocketReceiver : public NetworkReceiver
00125 {
00126 public:
00127         SocketReceiver(Socket &s);
00128 
00129 #ifdef USE_BERKELEY_STYLE_SOCKETS
00130         bool MustWaitToReceive() {return true;}
00131 #else
00132         ~SocketReceiver();
00133         bool MustWaitForResult() {return true;}
00134 #endif
00135         bool Receive(byte* buf, size_t bufLen);
00136         unsigned int GetReceiveResult();
00137         bool EofReceived() const {return m_eofReceived;}
00138 
00139         unsigned int GetMaxWaitObjectCount() const {return 1;}
00140         void GetWaitObjects(WaitObjectContainer &container, CallStack const& callStack);
00141 
00142 private:
00143         Socket &m_s;
00144         bool m_eofReceived;
00145 
00146 #ifdef USE_WINDOWS_STYLE_SOCKETS
00147         WindowsHandle m_event;
00148         OVERLAPPED m_overlapped;
00149         bool m_resultPending;
00150         DWORD m_lastResult;
00151 #else
00152         unsigned int m_lastResult;
00153 #endif
00154 };
00155 
00156 class SocketSender : public NetworkSender
00157 {
00158 public:
00159         SocketSender(Socket &s);
00160 
00161 #ifdef USE_BERKELEY_STYLE_SOCKETS
00162         bool MustWaitToSend() {return true;}
00163 #else
00164         ~SocketSender();
00165         bool MustWaitForResult() {return true;}
00166         bool MustWaitForEof() { return true; }
00167         bool EofSent();
00168 #endif
00169         void Send(const byte* buf, size_t bufLen);
00170         unsigned int GetSendResult();
00171         void SendEof();
00172 
00173         unsigned int GetMaxWaitObjectCount() const {return 1;}
00174         void GetWaitObjects(WaitObjectContainer &container, CallStack const& callStack);
00175 
00176 private:
00177         Socket &m_s;
00178 #ifdef USE_WINDOWS_STYLE_SOCKETS
00179         WindowsHandle m_event;
00180         OVERLAPPED m_overlapped;
00181         bool m_resultPending;
00182         DWORD m_lastResult;
00183 #else
00184         unsigned int m_lastResult;
00185 #endif
00186 };
00187 
00188 //! socket-based implementation of NetworkSource
00189 class SocketSource : public NetworkSource, public Socket
00190 {
00191 public:
00192         SocketSource(socket_t s = INVALID_SOCKET, bool pumpAll = false, BufferedTransformation *attachment = NULL)
00193                 : NetworkSource(attachment), Socket(s), m_receiver(*this)
00194         {
00195                 if (pumpAll)
00196                         PumpAll();
00197         }
00198 
00199 private:
00200         NetworkReceiver & AccessReceiver() {return m_receiver;}
00201         SocketReceiver m_receiver;
00202 };
00203 
00204 //! socket-based implementation of NetworkSink
00205 class SocketSink : public NetworkSink, public Socket
00206 {
00207 public:
00208         SocketSink(socket_t s=INVALID_SOCKET, unsigned int maxBufferSize=0, unsigned int autoFlushBound=16*1024)
00209                 : NetworkSink(maxBufferSize, autoFlushBound), Socket(s), m_sender(*this) {}
00210 
00211         void SendEof() {ShutDown(SD_SEND);}
00212 
00213 private:
00214         NetworkSender & AccessSender() {return m_sender;}
00215         SocketSender m_sender;
00216 };
00217 
00218 NAMESPACE_END
00219 
00220 #endif  // #ifdef SOCKETS_AVAILABLE
00221 
00222 #endif

Generated on Thu Nov 23 15:57:46 2006 for Crypto++ by  doxygen 1.5.1-p1