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