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,
unsigned int bufLen,
int flags=0);
00081
unsigned int Receive(byte* buf,
unsigned int 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,
unsigned int 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,
unsigned int 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