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