00001
00002
00003 #include "pch.h"
00004
00005
00006 #define _WINSOCK_DEPRECATED_NO_WARNINGS
00007 #include "socketft.h"
00008
00009 #ifdef SOCKETS_AVAILABLE
00010
00011 #include "wait.h"
00012
00013 #ifdef USE_BERKELEY_STYLE_SOCKETS
00014 #include <errno.h>
00015 #include <netdb.h>
00016 #include <unistd.h>
00017 #include <arpa/inet.h>
00018 #include <netinet/in.h>
00019 #include <sys/ioctl.h>
00020 #endif
00021
00022 #ifdef PREFER_WINDOWS_STYLE_SOCKETS
00023 # pragma comment(lib, "ws2_32.lib")
00024 #endif
00025
00026 NAMESPACE_BEGIN(CryptoPP)
00027
00028 #ifdef USE_WINDOWS_STYLE_SOCKETS
00029 const int SOCKET_EINVAL = WSAEINVAL;
00030 const int SOCKET_EWOULDBLOCK = WSAEWOULDBLOCK;
00031 typedef int socklen_t;
00032 #else
00033 const int SOCKET_EINVAL = EINVAL;
00034 const int SOCKET_EWOULDBLOCK = EWOULDBLOCK;
00035 #endif
00036
00037
00038 #ifndef INADDR_NONE
00039 # define INADDR_NONE 0xffffffff
00040 #endif
00041
00042 Socket::Err::Err(socket_t s, const std::string& operation, int error)
00043 : OS_Error(IO_ERROR, "Socket: " + operation + " operation failed with error " + IntToString(error), operation, error)
00044 , m_s(s)
00045 {
00046 }
00047
00048 Socket::~Socket()
00049 {
00050 if (m_own)
00051 {
00052 try
00053 {
00054 CloseSocket();
00055 }
00056 catch (const Exception&)
00057 {
00058 assert(0);
00059 }
00060 }
00061 }
00062
00063 void Socket::AttachSocket(socket_t s, bool own)
00064 {
00065 if (m_own)
00066 CloseSocket();
00067
00068 m_s = s;
00069 m_own = own;
00070 SocketChanged();
00071 }
00072
00073 socket_t Socket::DetachSocket()
00074 {
00075 socket_t s = m_s;
00076 m_s = INVALID_SOCKET;
00077 SocketChanged();
00078 return s;
00079 }
00080
00081 void Socket::Create(int nType)
00082 {
00083 assert(m_s == INVALID_SOCKET);
00084 m_s = socket(AF_INET, nType, 0);
00085 CheckAndHandleError("socket", m_s);
00086 m_own = true;
00087 SocketChanged();
00088 }
00089
00090 void Socket::CloseSocket()
00091 {
00092 if (m_s != INVALID_SOCKET)
00093 {
00094 #ifdef USE_WINDOWS_STYLE_SOCKETS
00095 CancelIo((HANDLE) m_s);
00096 CheckAndHandleError_int("closesocket", closesocket(m_s));
00097 #else
00098 CheckAndHandleError_int("close", close(m_s));
00099 #endif
00100 m_s = INVALID_SOCKET;
00101 SocketChanged();
00102 }
00103 }
00104
00105 void Socket::Bind(unsigned int port, const char *addr)
00106 {
00107 sockaddr_in sa;
00108 memset(&sa, 0, sizeof(sa));
00109 sa.sin_family = AF_INET;
00110
00111 if (addr == NULL)
00112 sa.sin_addr.s_addr = htonl(INADDR_ANY);
00113 else
00114 {
00115 unsigned long result = inet_addr(addr);
00116 if (result == INADDR_NONE)
00117 {
00118 SetLastError(SOCKET_EINVAL);
00119 CheckAndHandleError_int("inet_addr", SOCKET_ERROR);
00120 }
00121 sa.sin_addr.s_addr = result;
00122 }
00123
00124 sa.sin_port = htons((u_short)port);
00125
00126 Bind((sockaddr *)&sa, sizeof(sa));
00127 }
00128
00129 void Socket::Bind(const sockaddr *psa, socklen_t saLen)
00130 {
00131 assert(m_s != INVALID_SOCKET);
00132
00133 CheckAndHandleError_int("bind", bind(m_s, const_cast<sockaddr *>(psa), saLen));
00134 }
00135
00136 void Socket::Listen(int backlog)
00137 {
00138 assert(m_s != INVALID_SOCKET);
00139 CheckAndHandleError_int("listen", listen(m_s, backlog));
00140 }
00141
00142 bool Socket::Connect(const char *addr, unsigned int port)
00143 {
00144 assert(addr != NULL);
00145
00146 sockaddr_in sa;
00147 memset(&sa, 0, sizeof(sa));
00148 sa.sin_family = AF_INET;
00149 sa.sin_addr.s_addr = inet_addr(addr);
00150
00151 if (sa.sin_addr.s_addr == INADDR_NONE)
00152 {
00153 hostent *lphost = gethostbyname(addr);
00154 if (lphost == NULL)
00155 {
00156 SetLastError(SOCKET_EINVAL);
00157 CheckAndHandleError_int("gethostbyname", SOCKET_ERROR);
00158 }
00159 else
00160 {
00161 sa.sin_addr.s_addr = ((in_addr *)lphost->h_addr)->s_addr;
00162 }
00163 }
00164
00165 sa.sin_port = htons((u_short)port);
00166
00167 return Connect((const sockaddr *)&sa, sizeof(sa));
00168 }
00169
00170 bool Socket::Connect(const sockaddr* psa, socklen_t saLen)
00171 {
00172 assert(m_s != INVALID_SOCKET);
00173 int result = connect(m_s, const_cast<sockaddr*>(psa), saLen);
00174 if (result == SOCKET_ERROR && GetLastError() == SOCKET_EWOULDBLOCK)
00175 return false;
00176 CheckAndHandleError_int("connect", result);
00177 return true;
00178 }
00179
00180 bool Socket::Accept(Socket& target, sockaddr *psa, socklen_t *psaLen)
00181 {
00182 assert(m_s != INVALID_SOCKET);
00183 socket_t s = accept(m_s, psa, psaLen);
00184 if (s == INVALID_SOCKET && GetLastError() == SOCKET_EWOULDBLOCK)
00185 return false;
00186 CheckAndHandleError("accept", s);
00187 target.AttachSocket(s, true);
00188 return true;
00189 }
00190
00191 void Socket::GetSockName(sockaddr *psa, socklen_t *psaLen)
00192 {
00193 assert(m_s != INVALID_SOCKET);
00194 CheckAndHandleError_int("getsockname", getsockname(m_s, psa, psaLen));
00195 }
00196
00197 void Socket::GetPeerName(sockaddr *psa, socklen_t *psaLen)
00198 {
00199 assert(m_s != INVALID_SOCKET);
00200 CheckAndHandleError_int("getpeername", getpeername(m_s, psa, psaLen));
00201 }
00202
00203 unsigned int Socket::Send(const byte* buf, size_t bufLen, int flags)
00204 {
00205 assert(m_s != INVALID_SOCKET);
00206 int result = send(m_s, (const char *)buf, UnsignedMin(INT_MAX, bufLen), flags);
00207 CheckAndHandleError_int("send", result);
00208 return result;
00209 }
00210
00211 unsigned int Socket::Receive(byte* buf, size_t bufLen, int flags)
00212 {
00213 assert(m_s != INVALID_SOCKET);
00214 int result = recv(m_s, (char *)buf, UnsignedMin(INT_MAX, bufLen), flags);
00215 CheckAndHandleError_int("recv", result);
00216 return result;
00217 }
00218
00219 void Socket::ShutDown(int how)
00220 {
00221 assert(m_s != INVALID_SOCKET);
00222 int result = shutdown(m_s, how);
00223 CheckAndHandleError_int("shutdown", result);
00224 }
00225
00226 void Socket::IOCtl(long cmd, unsigned long *argp)
00227 {
00228 assert(m_s != INVALID_SOCKET);
00229 #ifdef USE_WINDOWS_STYLE_SOCKETS
00230 CheckAndHandleError_int("ioctlsocket", ioctlsocket(m_s, cmd, argp));
00231 #else
00232 CheckAndHandleError_int("ioctl", ioctl(m_s, cmd, argp));
00233 #endif
00234 }
00235
00236 bool Socket::SendReady(const timeval *timeout)
00237 {
00238 fd_set fds;
00239 FD_ZERO(&fds);
00240 FD_SET(m_s, &fds);
00241 int ready;
00242 if (timeout == NULL)
00243 ready = select((int)m_s+1, NULL, &fds, NULL, NULL);
00244 else
00245 {
00246 timeval timeoutCopy = *timeout;
00247 ready = select((int)m_s+1, NULL, &fds, NULL, &timeoutCopy);
00248 }
00249 CheckAndHandleError_int("select", ready);
00250 return ready > 0;
00251 }
00252
00253 bool Socket::ReceiveReady(const timeval *timeout)
00254 {
00255 fd_set fds;
00256 FD_ZERO(&fds);
00257 FD_SET(m_s, &fds);
00258 int ready;
00259 if (timeout == NULL)
00260 ready = select((int)m_s+1, &fds, NULL, NULL, NULL);
00261 else
00262 {
00263 timeval timeoutCopy = *timeout;
00264 ready = select((int)m_s+1, &fds, NULL, NULL, &timeoutCopy);
00265 }
00266 CheckAndHandleError_int("select", ready);
00267 return ready > 0;
00268 }
00269
00270 unsigned int Socket::PortNameToNumber(const char *name, const char *protocol)
00271 {
00272 int port = atoi(name);
00273 if (IntToString(port) == name)
00274 return port;
00275
00276 servent *se = getservbyname(name, protocol);
00277 if (!se)
00278 throw Err(INVALID_SOCKET, "getservbyname", SOCKET_EINVAL);
00279 return ntohs(se->s_port);
00280 }
00281
00282 void Socket::StartSockets()
00283 {
00284 #ifdef USE_WINDOWS_STYLE_SOCKETS
00285 WSADATA wsd;
00286 int result = WSAStartup(0x0202, &wsd);
00287 if (result != 0)
00288 throw Err(INVALID_SOCKET, "WSAStartup", result);
00289 #endif
00290 }
00291
00292 void Socket::ShutdownSockets()
00293 {
00294 #ifdef USE_WINDOWS_STYLE_SOCKETS
00295 int result = WSACleanup();
00296 if (result != 0)
00297 throw Err(INVALID_SOCKET, "WSACleanup", result);
00298 #endif
00299 }
00300
00301 int Socket::GetLastError()
00302 {
00303 #ifdef USE_WINDOWS_STYLE_SOCKETS
00304 return WSAGetLastError();
00305 #else
00306 return errno;
00307 #endif
00308 }
00309
00310 void Socket::SetLastError(int errorCode)
00311 {
00312 #ifdef USE_WINDOWS_STYLE_SOCKETS
00313 WSASetLastError(errorCode);
00314 #else
00315 errno = errorCode;
00316 #endif
00317 }
00318
00319 void Socket::HandleError(const char *operation) const
00320 {
00321 int err = GetLastError();
00322 throw Err(m_s, operation, err);
00323 }
00324
00325 #ifdef USE_WINDOWS_STYLE_SOCKETS
00326
00327 SocketReceiver::SocketReceiver(Socket &s)
00328 : m_s(s), m_eofReceived(false), m_resultPending(false)
00329 {
00330 m_event.AttachHandle(CreateEvent(NULL, true, false, NULL), true);
00331 m_s.CheckAndHandleError("CreateEvent", m_event.HandleValid());
00332 memset(&m_overlapped, 0, sizeof(m_overlapped));
00333 m_overlapped.hEvent = m_event;
00334 }
00335
00336 SocketReceiver::~SocketReceiver()
00337 {
00338 #ifdef USE_WINDOWS_STYLE_SOCKETS
00339 CancelIo((HANDLE) m_s.GetSocket());
00340 #endif
00341 }
00342
00343 bool SocketReceiver::Receive(byte* buf, size_t bufLen)
00344 {
00345 assert(!m_resultPending && !m_eofReceived);
00346
00347 DWORD flags = 0;
00348
00349 WSABUF wsabuf = {UnsignedMin((u_long)128*1024, bufLen), (char *)buf};
00350 if (WSARecv(m_s, &wsabuf, 1, &m_lastResult, &flags, &m_overlapped, NULL) == 0)
00351 {
00352 if (m_lastResult == 0)
00353 m_eofReceived = true;
00354 }
00355 else
00356 {
00357 switch (WSAGetLastError())
00358 {
00359 default:
00360 m_s.CheckAndHandleError_int("WSARecv", SOCKET_ERROR);
00361 case WSAEDISCON:
00362 m_lastResult = 0;
00363 m_eofReceived = true;
00364 break;
00365 case WSA_IO_PENDING:
00366 m_resultPending = true;
00367 }
00368 }
00369 return !m_resultPending;
00370 }
00371
00372 void SocketReceiver::GetWaitObjects(WaitObjectContainer &container, CallStack const& callStack)
00373 {
00374 if (m_resultPending)
00375 container.AddHandle(m_event, CallStack("SocketReceiver::GetWaitObjects() - result pending", &callStack));
00376 else if (!m_eofReceived)
00377 container.SetNoWait(CallStack("SocketReceiver::GetWaitObjects() - result ready", &callStack));
00378 }
00379
00380 unsigned int SocketReceiver::GetReceiveResult()
00381 {
00382 if (m_resultPending)
00383 {
00384 DWORD flags = 0;
00385 if (WSAGetOverlappedResult(m_s, &m_overlapped, &m_lastResult, false, &flags))
00386 {
00387 if (m_lastResult == 0)
00388 m_eofReceived = true;
00389 }
00390 else
00391 {
00392 switch (WSAGetLastError())
00393 {
00394 default:
00395 m_s.CheckAndHandleError("WSAGetOverlappedResult", FALSE);
00396 case WSAEDISCON:
00397 m_lastResult = 0;
00398 m_eofReceived = true;
00399 }
00400 }
00401 m_resultPending = false;
00402 }
00403 return m_lastResult;
00404 }
00405
00406
00407
00408 SocketSender::SocketSender(Socket &s)
00409 : m_s(s), m_resultPending(false), m_lastResult(0)
00410 {
00411 m_event.AttachHandle(CreateEvent(NULL, true, false, NULL), true);
00412 m_s.CheckAndHandleError("CreateEvent", m_event.HandleValid());
00413 memset(&m_overlapped, 0, sizeof(m_overlapped));
00414 m_overlapped.hEvent = m_event;
00415 }
00416
00417
00418 SocketSender::~SocketSender()
00419 {
00420 #ifdef USE_WINDOWS_STYLE_SOCKETS
00421 CancelIo((HANDLE) m_s.GetSocket());
00422 #endif
00423 }
00424
00425 void SocketSender::Send(const byte* buf, size_t bufLen)
00426 {
00427 assert(!m_resultPending);
00428 DWORD written = 0;
00429
00430 WSABUF wsabuf = {UnsignedMin((u_long)128*1024, bufLen), (char *)buf};
00431 if (WSASend(m_s, &wsabuf, 1, &written, 0, &m_overlapped, NULL) == 0)
00432 {
00433 m_resultPending = false;
00434 m_lastResult = written;
00435 }
00436 else
00437 {
00438 if (WSAGetLastError() != WSA_IO_PENDING)
00439 m_s.CheckAndHandleError_int("WSASend", SOCKET_ERROR);
00440
00441 m_resultPending = true;
00442 }
00443 }
00444
00445 void SocketSender::SendEof()
00446 {
00447 assert(!m_resultPending);
00448 m_s.ShutDown(SD_SEND);
00449 m_s.CheckAndHandleError("ResetEvent", ResetEvent(m_event));
00450 m_s.CheckAndHandleError_int("WSAEventSelect", WSAEventSelect(m_s, m_event, FD_CLOSE));
00451 m_resultPending = true;
00452 }
00453
00454 bool SocketSender::EofSent()
00455 {
00456 if (m_resultPending)
00457 {
00458 WSANETWORKEVENTS events;
00459 m_s.CheckAndHandleError_int("WSAEnumNetworkEvents", WSAEnumNetworkEvents(m_s, m_event, &events));
00460 if ((events.lNetworkEvents & FD_CLOSE) != FD_CLOSE)
00461 throw Socket::Err(m_s, "WSAEnumNetworkEvents (FD_CLOSE not present)", E_FAIL);
00462 if (events.iErrorCode[FD_CLOSE_BIT] != 0)
00463 throw Socket::Err(m_s, "FD_CLOSE (via WSAEnumNetworkEvents)", events.iErrorCode[FD_CLOSE_BIT]);
00464 m_resultPending = false;
00465 }
00466 return m_lastResult != 0;
00467 }
00468
00469 void SocketSender::GetWaitObjects(WaitObjectContainer &container, CallStack const& callStack)
00470 {
00471 if (m_resultPending)
00472 container.AddHandle(m_event, CallStack("SocketSender::GetWaitObjects() - result pending", &callStack));
00473 else
00474 container.SetNoWait(CallStack("SocketSender::GetWaitObjects() - result ready", &callStack));
00475 }
00476
00477 unsigned int SocketSender::GetSendResult()
00478 {
00479 if (m_resultPending)
00480 {
00481 DWORD flags = 0;
00482 BOOL result = WSAGetOverlappedResult(m_s, &m_overlapped, &m_lastResult, false, &flags);
00483 m_s.CheckAndHandleError("WSAGetOverlappedResult", result);
00484 m_resultPending = false;
00485 }
00486 return m_lastResult;
00487 }
00488
00489 #endif
00490
00491 #ifdef USE_BERKELEY_STYLE_SOCKETS
00492
00493 SocketReceiver::SocketReceiver(Socket &s)
00494 : m_s(s), m_eofReceived(false), m_lastResult(0)
00495 {
00496 }
00497
00498 void SocketReceiver::GetWaitObjects(WaitObjectContainer &container, CallStack const& callStack)
00499 {
00500 if (!m_eofReceived)
00501 container.AddReadFd(m_s, CallStack("SocketReceiver::GetWaitObjects()", &callStack));
00502 }
00503
00504 bool SocketReceiver::Receive(byte* buf, size_t bufLen)
00505 {
00506 m_lastResult = m_s.Receive(buf, bufLen);
00507 if (bufLen > 0 && m_lastResult == 0)
00508 m_eofReceived = true;
00509 return true;
00510 }
00511
00512 unsigned int SocketReceiver::GetReceiveResult()
00513 {
00514 return m_lastResult;
00515 }
00516
00517 SocketSender::SocketSender(Socket &s)
00518 : m_s(s), m_lastResult(0)
00519 {
00520 }
00521
00522 void SocketSender::Send(const byte* buf, size_t bufLen)
00523 {
00524 m_lastResult = m_s.Send(buf, bufLen);
00525 }
00526
00527 void SocketSender::SendEof()
00528 {
00529 m_s.ShutDown(SD_SEND);
00530 }
00531
00532 unsigned int SocketSender::GetSendResult()
00533 {
00534 return m_lastResult;
00535 }
00536
00537 void SocketSender::GetWaitObjects(WaitObjectContainer &container, CallStack const& callStack)
00538 {
00539 container.AddWriteFd(m_s, CallStack("SocketSender::GetWaitObjects()", &callStack));
00540 }
00541
00542 #endif
00543
00544 NAMESPACE_END
00545
00546 #endif // #ifdef SOCKETS_AVAILABLE