Crypto++  5.6.5
Free C++ class library of cryptographic schemes
socketft.cpp
1 // socketft.cpp - originally written and placed in the public domain by Wei Dai
2 
3 #include "pch.h"
4 #include "config.h"
5 
6 #if !defined(NO_OS_DEPENDENCE) && defined(SOCKETS_AVAILABLE)
7 
8 #include "socketft.h"
9 #include "wait.h"
10 
11 // Windows 8, Windows Server 2012, and Windows Phone 8.1 need <synchapi.h> and <ioapiset.h>
12 #if defined(CRYPTOPP_WIN32_AVAILABLE)
13 # if ((WINVER >= 0x0602 /*_WIN32_WINNT_WIN8*/) || (_WIN32_WINNT >= 0x0602 /*_WIN32_WINNT_WIN8*/))
14 # include <synchapi.h>
15 # include <ioapiset.h>
16 # define USE_WINDOWS8_API
17 # endif
18 #endif
19 
20 #ifdef USE_BERKELEY_STYLE_SOCKETS
21 #include <errno.h>
22 #include <netdb.h>
23 #include <unistd.h>
24 #include <arpa/inet.h>
25 #include <netinet/in.h>
26 #include <sys/ioctl.h>
27 #endif
28 
29 #if defined(CRYPTOPP_MSAN)
30 # include <sanitizer/msan_interface.h>
31 #endif
32 
33 // From http://groups.google.com/d/msg/cryptopp-users/MzvocLrbIpE/TMCa6LFhCgAJ,
34 // <wspiapi.h> is a compatibility header and it needs _WIN32_WINNT >= 0x501.
35 // The work-around should be OK since it won't cross-pollinate into header files.
36 #if defined(__MINGW32__) && (_WIN32_WINNT < 0x501)
37 # undef _WIN32_WINNT
38 # define _WIN32_WINNT 0x501
39 #endif
40 
41 #ifdef USE_WINDOWS_STYLE_SOCKETS
42 # pragma comment(lib, "ws2_32.lib")
43 # if defined(_WIN32_WINNT) && (_WIN32_WINNT < 0x501)
44 # include <wspiapi.h>
45 # endif
46 #endif
47 
48 NAMESPACE_BEGIN(CryptoPP)
49 
50 #ifdef USE_WINDOWS_STYLE_SOCKETS
51 const int SOCKET_EINVAL = WSAEINVAL;
52 const int SOCKET_EWOULDBLOCK = WSAEWOULDBLOCK;
53 typedef int socklen_t;
54 #else
55 const int SOCKET_EINVAL = EINVAL;
56 const int SOCKET_EWOULDBLOCK = EWOULDBLOCK;
57 #endif
58 
59 // Solaris doesn't have INADDR_NONE
60 #ifndef INADDR_NONE
61 # define INADDR_NONE 0xffffffff
62 #endif /* INADDR_NONE */
63 
64 // Some Windows SDKs do not have INET6_ADDRSTRLEN
65 #ifndef INET_ADDRSTRLEN
66 # define INET_ADDRSTRLEN (22)
67 #endif
68 #ifndef INET6_ADDRSTRLEN
69 # define INET6_ADDRSTRLEN (65)
70 #endif
71 
72 #define MAX_ADDRSTRLEN (INET6_ADDRSTRLEN > INET_ADDRSTRLEN ? INET6_ADDRSTRLEN : INET_ADDRSTRLEN)
73 
74 // Also see http://stackoverflow.com/a/20816961 and http://github.com/weidai11/cryptopp/issues/322
75 #if defined(USE_WINDOWS_STYLE_SOCKETS)
76 int inet_pton(int af, const char *src, void *dst)
77 {
78 #if CRYPTOPP_MSC_VERSION
79 # pragma warning(push)
80 # pragma warning(disable: 4996)
81 #endif
82 
83  // Posix states only src is validated. Avoid a bad dst dereference.
84  if(!src || !dst) return 0;
85 
86  struct sockaddr_storage ss;
87  ZeroMemory(&ss, sizeof(ss));
88 
89 #if CRYPTOPP_MSC_VERSION >= 1400
90  char temp[MAX_ADDRSTRLEN];
91  strcpy_s(temp, sizeof(temp), src);
92 #else
93  char temp[MAX_ADDRSTRLEN];
94  strncpy(temp, src, sizeof(temp));
95  temp[MAX_ADDRSTRLEN-1] = '\0';
96 #endif
97 
98 
99  int size = sizeof(ss);
100  if (WSAStringToAddressA(temp, af, NULLPTR, (struct sockaddr *)&ss, &size) == 0) {
101  switch (af) {
102  case AF_INET:
103  *(struct in_addr *)dst = ((struct sockaddr_in *)&ss)->sin_addr;
104  return 1;
105  case AF_INET6:
106  *(struct in6_addr *)dst = ((struct sockaddr_in6 *)&ss)->sin6_addr;
107  return 1;
108  }
109  }
110 
111  ((sockaddr_in *)dst)->sin_addr.s_addr = INADDR_NONE;
112  return 0;
113 
114 #if CRYPTOPP_MSC_VERSION
115 # pragma warning(pop)
116 #endif
117 }
118 #endif
119 
120 Socket::Err::Err(socket_t s, const std::string& operation, int error)
121  : OS_Error(IO_ERROR, "Socket: " + operation + " operation failed with error " + IntToString(error), operation, error)
122  , m_s(s)
123 {
124 }
125 
126 Socket::~Socket()
127 {
128  if (m_own)
129  {
130  try
131  {
132  CloseSocket();
133  }
134  catch (const Exception&)
135  {
136  CRYPTOPP_ASSERT(0);
137  }
138  }
139 }
140 
141 void Socket::AttachSocket(socket_t s, bool own)
142 {
143  if (m_own)
144  CloseSocket();
145 
146  m_s = s;
147  m_own = own;
148  SocketChanged();
149 }
150 
151 socket_t Socket::DetachSocket()
152 {
153  socket_t s = m_s;
154  m_s = INVALID_SOCKET;
155  SocketChanged();
156  return s;
157 }
158 
159 void Socket::Create(int nType)
160 {
161  CRYPTOPP_ASSERT(m_s == INVALID_SOCKET);
162  m_s = socket(AF_INET, nType, 0);
163  CheckAndHandleError("socket", m_s);
164  m_own = true;
165  SocketChanged();
166 }
167 
168 void Socket::CloseSocket()
169 {
170  if (m_s != INVALID_SOCKET)
171  {
172 #ifdef USE_WINDOWS_STYLE_SOCKETS
173 # if defined(USE_WINDOWS8_API)
174  BOOL result = CancelIoEx((HANDLE) m_s, NULLPTR);
175  CRYPTOPP_ASSERT(result || (!result && GetLastError() == ERROR_NOT_FOUND));
176  CheckAndHandleError_int("closesocket", closesocket(m_s));
177  CRYPTOPP_UNUSED(result); // Used by CRYPTOPP_ASSERT in debug builds
178 # else
179  BOOL result = CancelIo((HANDLE) m_s);
180  CRYPTOPP_ASSERT(result || (!result && GetLastError() == ERROR_NOT_FOUND));
181  CheckAndHandleError_int("closesocket", closesocket(m_s));
182  CRYPTOPP_UNUSED(result);
183 # endif
184 #else
185  CheckAndHandleError_int("close", close(m_s));
186 #endif
187  m_s = INVALID_SOCKET;
188  SocketChanged();
189  }
190 }
191 
192 void Socket::Bind(unsigned int port, const char *addr)
193 {
194  sockaddr_in sa;
195  memset(&sa, 0, sizeof(sa));
196  sa.sin_family = AF_INET;
197 
198  if (addr == NULLPTR)
199  sa.sin_addr.s_addr = htonl(INADDR_ANY);
200  else
201  {
202  // unsigned long result = inet_addr(addr);
203  unsigned long result;
204  if (inet_pton(AF_INET, addr, &result) < 1 || result == INADDR_NONE)
205  {
206  SetLastError(SOCKET_EINVAL);
207  CheckAndHandleError_int("inet_addr", SOCKET_ERROR);
208  }
209  sa.sin_addr.s_addr = result;
210  }
211 
212  sa.sin_port = htons((unsigned short)port);
213 
214  Bind((sockaddr *)&sa, sizeof(sa));
215 }
216 
217 void Socket::Bind(const sockaddr *psa, socklen_t saLen)
218 {
219  CRYPTOPP_ASSERT(m_s != INVALID_SOCKET);
220  // cygwin workaround: needs const_cast
221  CheckAndHandleError_int("bind", bind(m_s, const_cast<sockaddr *>(psa), saLen));
222 }
223 
224 void Socket::Listen(int backlog)
225 {
226  CRYPTOPP_ASSERT(m_s != INVALID_SOCKET);
227  CheckAndHandleError_int("listen", listen(m_s, backlog));
228 }
229 
230 bool Socket::Connect(const char *addr, unsigned int port)
231 {
232  CRYPTOPP_ASSERT(addr != NULLPTR);
233 
234  sockaddr_in sa;
235  memset(&sa, 0, sizeof(sa));
236  sa.sin_family = AF_INET;
237 
238  // Make inet_pton failures non-fatal.
239  if (!addr || inet_pton(AF_INET, addr, &sa.sin_addr.s_addr) < 1)
240  sa.sin_addr.s_addr = INADDR_NONE;
241 
242  if (sa.sin_addr.s_addr == INADDR_NONE)
243  {
244  addrinfo hints, *result = NULLPTR;
245  memset(&hints, 0, sizeof(hints));
246 
247  hints.ai_socktype = SOCK_STREAM;
248  hints.ai_family = AF_INET;
249 
250  if (getaddrinfo(addr, NULLPTR, &hints, &result) != 0 || result == NULLPTR)
251  {
252  freeaddrinfo(result);
253  SetLastError(SOCKET_EINVAL);
254  CheckAndHandleError_int("getaddrinfo", SOCKET_ERROR);
255  }
256  else
257  {
258  // Avoid assignment on due to alignment issues in Apple headers
259  // sa.sin_addr.s_addr = ((struct sockaddr_in *)(result->ai_addr))->sin_addr.s_addr;
260  struct sockaddr_in* sap = (struct sockaddr_in *)result->ai_addr;
261  memcpy(&sa.sin_addr.s_addr, &sap->sin_addr.s_addr, sizeof(sa.sin_addr.s_addr));
262  freeaddrinfo(result);
263  }
264  }
265 
266  sa.sin_port = htons((unsigned short)port);
267 
268  return Connect((const sockaddr *)&sa, sizeof(sa));
269 }
270 
271 bool Socket::Connect(const sockaddr* psa, socklen_t saLen)
272 {
273  CRYPTOPP_ASSERT(m_s != INVALID_SOCKET);
274  int result = connect(m_s, const_cast<sockaddr*>(psa), saLen);
275  if (result == SOCKET_ERROR && GetLastError() == SOCKET_EWOULDBLOCK)
276  return false;
277  CheckAndHandleError_int("connect", result);
278  return true;
279 }
280 
281 bool Socket::Accept(Socket& target, sockaddr *psa, socklen_t *psaLen)
282 {
283  CRYPTOPP_ASSERT(m_s != INVALID_SOCKET);
284  socket_t s = accept(m_s, psa, psaLen);
285  if (s == INVALID_SOCKET && GetLastError() == SOCKET_EWOULDBLOCK)
286  return false;
287  CheckAndHandleError("accept", s);
288  target.AttachSocket(s, true);
289  return true;
290 }
291 
292 void Socket::GetSockName(sockaddr *psa, socklen_t *psaLen)
293 {
294  CRYPTOPP_ASSERT(m_s != INVALID_SOCKET);
295  CheckAndHandleError_int("getsockname", getsockname(m_s, psa, psaLen));
296 }
297 
298 void Socket::GetPeerName(sockaddr *psa, socklen_t *psaLen)
299 {
300  CRYPTOPP_ASSERT(m_s != INVALID_SOCKET);
301  CheckAndHandleError_int("getpeername", getpeername(m_s, psa, psaLen));
302 }
303 
304 unsigned int Socket::Send(const byte* buf, size_t bufLen, int flags)
305 {
306  CRYPTOPP_ASSERT(m_s != INVALID_SOCKET);
307  int result = send(m_s, (const char *)buf, UnsignedMin(INT_MAX, bufLen), flags);
308  CheckAndHandleError_int("send", result);
309  return result;
310 }
311 
312 unsigned int Socket::Receive(byte* buf, size_t bufLen, int flags)
313 {
314  CRYPTOPP_ASSERT(m_s != INVALID_SOCKET);
315  int result = recv(m_s, (char *)buf, UnsignedMin(INT_MAX, bufLen), flags);
316  CheckAndHandleError_int("recv", result);
317  return result;
318 }
319 
320 void Socket::ShutDown(int how)
321 {
322  CRYPTOPP_ASSERT(m_s != INVALID_SOCKET);
323  int result = shutdown(m_s, how);
324  CheckAndHandleError_int("shutdown", result);
325 }
326 
327 void Socket::IOCtl(long cmd, unsigned long *argp)
328 {
329  CRYPTOPP_ASSERT(m_s != INVALID_SOCKET);
330 #ifdef USE_WINDOWS_STYLE_SOCKETS
331  CheckAndHandleError_int("ioctlsocket", ioctlsocket(m_s, cmd, argp));
332 #else
333  CheckAndHandleError_int("ioctl", ioctl(m_s, cmd, argp));
334 #endif
335 }
336 
337 bool Socket::SendReady(const timeval *timeout)
338 {
339  fd_set fds;
340  FD_ZERO(&fds);
341  FD_SET(m_s, &fds);
342 #ifdef CRYPTOPP_MSAN
343  __msan_unpoison(&fds, sizeof(fds));
344 #endif
345 
346  int ready;
347  if (timeout == NULLPTR)
348  ready = select((int)m_s+1, NULLPTR, &fds, NULLPTR, NULLPTR);
349  else
350  {
351  timeval timeoutCopy = *timeout; // select() modified timeout on Linux
352  ready = select((int)m_s+1, NULLPTR, &fds, NULLPTR, &timeoutCopy);
353  }
354  CheckAndHandleError_int("select", ready);
355  return ready > 0;
356 }
357 
358 bool Socket::ReceiveReady(const timeval *timeout)
359 {
360  fd_set fds;
361  FD_ZERO(&fds);
362  FD_SET(m_s, &fds);
363 #ifdef CRYPTOPP_MSAN
364  __msan_unpoison(&fds, sizeof(fds));
365 #endif
366 
367  int ready;
368  if (timeout == NULLPTR)
369  ready = select((int)m_s+1, &fds, NULLPTR, NULLPTR, NULLPTR);
370  else
371  {
372  timeval timeoutCopy = *timeout; // select() modified timeout on Linux
373  ready = select((int)m_s+1, &fds, NULLPTR, NULLPTR, &timeoutCopy);
374  }
375  CheckAndHandleError_int("select", ready);
376  return ready > 0;
377 }
378 
379 unsigned int Socket::PortNameToNumber(const char *name, const char *protocol)
380 {
381  int port = atoi(name);
382  if (IntToString(port) == name)
383  return port;
384 
385  servent *se = getservbyname(name, protocol);
386  if (!se)
387  throw Err(INVALID_SOCKET, "getservbyname", SOCKET_EINVAL);
388  return ntohs(se->s_port);
389 }
390 
392 {
393 #ifdef USE_WINDOWS_STYLE_SOCKETS
394  WSADATA wsd;
395  int result = WSAStartup(0x0202, &wsd);
396  if (result != 0)
397  throw Err(INVALID_SOCKET, "WSAStartup", result);
398 #endif
399 }
400 
402 {
403 #ifdef USE_WINDOWS_STYLE_SOCKETS
404  int result = WSACleanup();
405  if (result != 0)
406  throw Err(INVALID_SOCKET, "WSACleanup", result);
407 #endif
408 }
409 
411 {
412 #ifdef USE_WINDOWS_STYLE_SOCKETS
413  return WSAGetLastError();
414 #else
415  return errno;
416 #endif
417 }
418 
419 void Socket::SetLastError(int errorCode)
420 {
421 #ifdef USE_WINDOWS_STYLE_SOCKETS
422  WSASetLastError(errorCode);
423 #else
424  errno = errorCode;
425 #endif
426 }
427 
428 void Socket::HandleError(const char *operation) const
429 {
430  int err = GetLastError();
431  throw Err(m_s, operation, err);
432 }
433 
434 #ifdef USE_WINDOWS_STYLE_SOCKETS
435 
436 SocketReceiver::SocketReceiver(Socket &s)
437  : m_s(s), m_lastResult(0), m_resultPending(false), m_eofReceived(false)
438 {
439  m_event.AttachHandle(CreateEvent(NULLPTR, true, false, NULLPTR), true);
440  m_s.CheckAndHandleError("CreateEvent", m_event.HandleValid());
441  memset(&m_overlapped, 0, sizeof(m_overlapped));
442  m_overlapped.hEvent = m_event;
443 }
444 
445 SocketReceiver::~SocketReceiver()
446 {
447 #ifdef USE_WINDOWS_STYLE_SOCKETS
448 # if defined(USE_WINDOWS8_API)
449  BOOL result = CancelIoEx((HANDLE) m_s.GetSocket(), NULLPTR);
450  CRYPTOPP_ASSERT(result || (!result && GetLastError() == ERROR_NOT_FOUND));
451  CRYPTOPP_UNUSED(result); // Used by CRYPTOPP_ASSERT in debug builds
452 # else
453  BOOL result = CancelIo((HANDLE) m_s.GetSocket());
454  CRYPTOPP_ASSERT(result || (!result && GetLastError() == ERROR_NOT_FOUND));
455  CRYPTOPP_UNUSED(result);
456 # endif
457 #endif
458 }
459 
460 bool SocketReceiver::Receive(byte* buf, size_t bufLen)
461 {
462  CRYPTOPP_ASSERT(!m_resultPending && !m_eofReceived);
463 
464  DWORD flags = 0;
465  // don't queue too much at once, or we might use up non-paged memory
466  WSABUF wsabuf = {UnsignedMin((u_long)128*1024, bufLen), (char *)buf};
467  if (WSARecv(m_s, &wsabuf, 1, &m_lastResult, &flags, &m_overlapped, NULLPTR) == 0)
468  {
469  if (m_lastResult == 0)
470  m_eofReceived = true;
471  }
472  else
473  {
474  switch (WSAGetLastError())
475  {
476  default:
477  m_s.CheckAndHandleError_int("WSARecv", SOCKET_ERROR);
478  // Fall through for non-fatal
479  case WSAEDISCON:
480  m_lastResult = 0;
481  m_eofReceived = true;
482  break;
483  case WSA_IO_PENDING:
484  m_resultPending = true;
485  }
486  }
487  return !m_resultPending;
488 }
489 
491 {
492  if (m_resultPending)
493  container.AddHandle(m_event, CallStack("SocketReceiver::GetWaitObjects() - result pending", &callStack));
494  else if (!m_eofReceived)
495  container.SetNoWait(CallStack("SocketReceiver::GetWaitObjects() - result ready", &callStack));
496 }
497 
498 unsigned int SocketReceiver::GetReceiveResult()
499 {
500  if (m_resultPending)
501  {
502  DWORD flags = 0;
503  if (WSAGetOverlappedResult(m_s, &m_overlapped, &m_lastResult, false, &flags))
504  {
505  if (m_lastResult == 0)
506  m_eofReceived = true;
507  }
508  else
509  {
510  switch (WSAGetLastError())
511  {
512  default:
513  m_s.CheckAndHandleError("WSAGetOverlappedResult", FALSE);
514  // Fall through for non-fatal
515  case WSAEDISCON:
516  m_lastResult = 0;
517  m_eofReceived = true;
518  }
519  }
520  m_resultPending = false;
521  }
522  return m_lastResult;
523 }
524 
525 // *************************************************************
526 
527 SocketSender::SocketSender(Socket &s)
528  : m_s(s), m_lastResult(0), m_resultPending(false)
529 {
530  m_event.AttachHandle(CreateEvent(NULLPTR, true, false, NULLPTR), true);
531  m_s.CheckAndHandleError("CreateEvent", m_event.HandleValid());
532  memset(&m_overlapped, 0, sizeof(m_overlapped));
533  m_overlapped.hEvent = m_event;
534 }
535 
536 
537 SocketSender::~SocketSender()
538 {
539 #ifdef USE_WINDOWS_STYLE_SOCKETS
540 # if defined(USE_WINDOWS8_API)
541  BOOL result = CancelIoEx((HANDLE) m_s.GetSocket(), NULLPTR);
542  CRYPTOPP_ASSERT(result || (!result && GetLastError() == ERROR_NOT_FOUND));
543  CRYPTOPP_UNUSED(result); // Used by CRYPTOPP_ASSERT in debug builds
544 # else
545  BOOL result = CancelIo((HANDLE) m_s.GetSocket());
546  CRYPTOPP_ASSERT(result || (!result && GetLastError() == ERROR_NOT_FOUND));
547  CRYPTOPP_UNUSED(result);
548 # endif
549 #endif
550 }
551 
552 void SocketSender::Send(const byte* buf, size_t bufLen)
553 {
554  CRYPTOPP_ASSERT(!m_resultPending);
555  DWORD written = 0;
556  // don't queue too much at once, or we might use up non-paged memory
557  WSABUF wsabuf = {UnsignedMin((u_long)128*1024, bufLen), (char *)buf};
558  if (WSASend(m_s, &wsabuf, 1, &written, 0, &m_overlapped, NULLPTR) == 0)
559  {
560  m_resultPending = false;
561  m_lastResult = written;
562  }
563  else
564  {
565  if (WSAGetLastError() != WSA_IO_PENDING)
566  m_s.CheckAndHandleError_int("WSASend", SOCKET_ERROR);
567 
568  m_resultPending = true;
569  }
570 }
571 
572 void SocketSender::SendEof()
573 {
574  CRYPTOPP_ASSERT(!m_resultPending);
575  m_s.ShutDown(SD_SEND);
576  m_s.CheckAndHandleError("ResetEvent", ResetEvent(m_event));
577  m_s.CheckAndHandleError_int("WSAEventSelect", WSAEventSelect(m_s, m_event, FD_CLOSE));
578  m_resultPending = true;
579 }
580 
581 bool SocketSender::EofSent()
582 {
583  if (m_resultPending)
584  {
585  WSANETWORKEVENTS events;
586  m_s.CheckAndHandleError_int("WSAEnumNetworkEvents", WSAEnumNetworkEvents(m_s, m_event, &events));
587  if ((events.lNetworkEvents & FD_CLOSE) != FD_CLOSE)
588  throw Socket::Err(m_s, "WSAEnumNetworkEvents (FD_CLOSE not present)", E_FAIL);
589  if (events.iErrorCode[FD_CLOSE_BIT] != 0)
590  throw Socket::Err(m_s, "FD_CLOSE (via WSAEnumNetworkEvents)", events.iErrorCode[FD_CLOSE_BIT]);
591  m_resultPending = false;
592  }
593  return m_lastResult != 0;
594 }
595 
597 {
598  if (m_resultPending)
599  container.AddHandle(m_event, CallStack("SocketSender::GetWaitObjects() - result pending", &callStack));
600  else
601  container.SetNoWait(CallStack("SocketSender::GetWaitObjects() - result ready", &callStack));
602 }
603 
604 unsigned int SocketSender::GetSendResult()
605 {
606  if (m_resultPending)
607  {
608  DWORD flags = 0;
609  BOOL result = WSAGetOverlappedResult(m_s, &m_overlapped, &m_lastResult, false, &flags);
610  m_s.CheckAndHandleError("WSAGetOverlappedResult", result);
611  m_resultPending = false;
612  }
613  return m_lastResult;
614 }
615 
616 #endif
617 
618 #ifdef USE_BERKELEY_STYLE_SOCKETS
619 
620 SocketReceiver::SocketReceiver(Socket &s)
621  : m_s(s), m_lastResult(0), m_eofReceived(false)
622 {
623 }
624 
625 void SocketReceiver::GetWaitObjects(WaitObjectContainer &container, CallStack const& callStack)
626 {
627  if (!m_eofReceived)
628  container.AddReadFd(m_s, CallStack("SocketReceiver::GetWaitObjects()", &callStack));
629 }
630 
631 bool SocketReceiver::Receive(byte* buf, size_t bufLen)
632 {
633  m_lastResult = m_s.Receive(buf, bufLen);
634  if (bufLen > 0 && m_lastResult == 0)
635  m_eofReceived = true;
636  return true;
637 }
638 
639 unsigned int SocketReceiver::GetReceiveResult()
640 {
641  return m_lastResult;
642 }
643 
644 SocketSender::SocketSender(Socket &s)
645  : m_s(s), m_lastResult(0)
646 {
647 }
648 
649 void SocketSender::Send(const byte* buf, size_t bufLen)
650 {
651  m_lastResult = m_s.Send(buf, bufLen);
652 }
653 
654 void SocketSender::SendEof()
655 {
656  m_s.ShutDown(SD_SEND);
657 }
658 
659 unsigned int SocketSender::GetSendResult()
660 {
661  return m_lastResult;
662 }
663 
664 void SocketSender::GetWaitObjects(WaitObjectContainer &container, CallStack const& callStack)
665 {
666  container.AddWriteFd(m_s, CallStack("SocketSender::GetWaitObjects()", &callStack));
667 }
668 
669 #endif // USE_BERKELEY_STYLE_SOCKETS
670 
671 NAMESPACE_END
672 
673 #endif // SOCKETS_AVAILABLE
Base class for all exceptions thrown by the library.
Definition: cryptlib.h:156
static unsigned int PortNameToNumber(const char *name, const char *protocol="tcp")
look up the port number given its name, returns 0 if not found
Definition: socketft.cpp:379
container of wait objects
Definition: wait.h:169
The operating system reported an error.
Definition: cryptlib.h:235
static void ShutdownSockets()
calls WSACleanup for Windows Sockets
Definition: socketft.cpp:401
Library configuration file.
exception thrown by Socket class
Definition: socketft.h:49
static void StartSockets()
start Windows Sockets 2
Definition: socketft.cpp:391
const T1 UnsignedMin(const T1 &a, const T2 &b)
Safe comparison of values that could be neagtive and incorrectly promoted.
Definition: misc.h:542
static void SetLastError(int errorCode)
sets errno or calls WSASetLastError
Definition: socketft.cpp:419
#define CRYPTOPP_ASSERT(exp)
Debugging and diagnostic assertion.
Definition: trap.h:60
wrapper for Windows or Berkeley Sockets
Definition: socketft.h:45
bool Receive(byte *buf, size_t bufLen)
receive data from network source, returns whether result is immediately available ...
Definition: socketft.cpp:460
std::string IntToString(T value, unsigned int base=10)
Converts a value to a string.
Definition: misc.h:572
Crypto++ library namespace.
void GetWaitObjects(WaitObjectContainer &container, CallStack const &callStack)
Retrieves waitable objects.
Definition: socketft.cpp:490
static int GetLastError()
returns errno or WSAGetLastError
Definition: socketft.cpp:410
void GetWaitObjects(WaitObjectContainer &container, CallStack const &callStack)
Retrieves waitable objects.
Definition: socketft.cpp:596