1//
2// detail/impl/socket_ops.ipp
3// ~~~~~~~~~~~~~~~~~~~~~~~~~~
4//
5// Copyright (c) 2003-2015 Christopher M. Kohlhoff (chris at kohlhoff dot com)
6//
7// Distributed under the Boost Software License, Version 1.0. (See accompanying
8// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
9//
10
11#ifndef ASIO_DETAIL_SOCKET_OPS_IPP
12#define ASIO_DETAIL_SOCKET_OPS_IPP
13
14
15#include "asio/detail/config.hpp"
16
17#include <cctype>
18#include <cstdio>
19#include <cstdlib>
20#include <cstring>
21#include <cerrno>
22#include <new>
23#include "asio/detail/assert.hpp"
24#include "asio/detail/socket_ops.hpp"
25#include "asio/error.hpp"
26
27
28#if defined(ASIO_WINDOWS) || defined(__CYGWIN__)    || defined(__MACH__) && defined(__APPLE__)
29# if defined(ASIO_HAS_PTHREADS)
30#  include <pthread.h>
31# endif // defined(ASIO_HAS_PTHREADS)
32#endif // defined(ASIO_WINDOWS) || defined(__CYGWIN__)
33       // || defined(__MACH__) && defined(__APPLE__)
34
35#include "asio/detail/push_options.hpp"
36
37namespace asio {
38namespace detail {
39namespace socket_ops {
40
41
42
43#if defined(__hpux)
44// HP-UX doesn't declare these functions extern "C", so they are declared again
45// here to avoid linker errors about undefined symbols.
46extern "C" char* if_indextoname(unsigned int, char*);
47extern "C" unsigned int if_nametoindex(const char*);
48#endif // defined(__hpux)
49
50
51inline void clear_last_error()
52{
53  errno = 0;
54}
55
56
57template <typename ReturnType>
58inline ReturnType error_wrapper(ReturnType return_value,
59    asio::error_code& ec)
60{
61  ec = asio::error_code(errno,
62      asio::error::get_system_category());
63  return return_value;
64}
65
66template <typename SockLenType>
67inline socket_type call_accept(SockLenType msghdr::*,
68    socket_type s, socket_addr_type* addr, std::size_t* addrlen)
69{
70  SockLenType tmp_addrlen = addrlen ? (SockLenType)*addrlen : 0;
71  socket_type result = ::accept(s, addr, addrlen ? &tmp_addrlen : 0);
72  if (addrlen)
73    *addrlen = (std::size_t)tmp_addrlen;
74  return result;
75}
76
77socket_type accept(socket_type s, socket_addr_type* addr,
78    std::size_t* addrlen, asio::error_code& ec)
79{
80  if (s == invalid_socket)
81  {
82    ec = asio::error::bad_descriptor;
83    return invalid_socket;
84  }
85
86  clear_last_error();
87
88  socket_type new_s = error_wrapper(call_accept(
89        &msghdr::msg_namelen, s, addr, addrlen), ec);
90  if (new_s == invalid_socket)
91    return new_s;
92
93#if defined(__MACH__) && defined(__APPLE__) || defined(__FreeBSD__)
94  int optval = 1;
95  int result = error_wrapper(::setsockopt(new_s,
96        SOL_SOCKET, SO_NOSIGPIPE, &optval, sizeof(optval)), ec);
97  if (result != 0)
98  {
99    ::close(new_s);
100    return invalid_socket;
101  }
102#endif
103
104  ec = asio::error_code();
105  return new_s;
106}
107
108socket_type sync_accept(socket_type s, state_type state,
109    socket_addr_type* addr, std::size_t* addrlen, asio::error_code& ec)
110{
111  // Accept a socket.
112  for (;;)
113  {
114    // Try to complete the operation without blocking.
115    socket_type new_socket = socket_ops::accept(s, addr, addrlen, ec);
116
117    // Check if operation succeeded.
118    if (new_socket != invalid_socket)
119      return new_socket;
120
121    // Operation failed.
122    if (ec == asio::error::would_block
123        || ec == asio::error::try_again)
124    {
125      if (state & user_set_non_blocking)
126        return invalid_socket;
127      // Fall through to retry operation.
128    }
129    else if (ec == asio::error::connection_aborted)
130    {
131      if (state & enable_connection_aborted)
132        return invalid_socket;
133      // Fall through to retry operation.
134    }
135#if defined(EPROTO)
136    else if (ec.value() == EPROTO)
137    {
138      if (state & enable_connection_aborted)
139        return invalid_socket;
140      // Fall through to retry operation.
141    }
142#endif // defined(EPROTO)
143    else
144      return invalid_socket;
145
146    // Wait for socket to become ready.
147    if (socket_ops::poll_read(s, 0, ec) < 0)
148      return invalid_socket;
149  }
150}
151
152
153bool non_blocking_accept(socket_type s,
154    state_type state, socket_addr_type* addr, std::size_t* addrlen,
155    asio::error_code& ec, socket_type& new_socket)
156{
157  for (;;)
158  {
159    // Accept the waiting connection.
160    new_socket = socket_ops::accept(s, addr, addrlen, ec);
161
162    // Check if operation succeeded.
163    if (new_socket != invalid_socket)
164      return true;
165
166    // Retry operation if interrupted by signal.
167    if (ec == asio::error::interrupted)
168      continue;
169
170    // Operation failed.
171    if (ec == asio::error::would_block
172        || ec == asio::error::try_again)
173    {
174      if (state & user_set_non_blocking)
175        return true;
176      // Fall through to retry operation.
177    }
178    else if (ec == asio::error::connection_aborted)
179    {
180      if (state & enable_connection_aborted)
181        return true;
182      // Fall through to retry operation.
183    }
184#if defined(EPROTO)
185    else if (ec.value() == EPROTO)
186    {
187      if (state & enable_connection_aborted)
188        return true;
189      // Fall through to retry operation.
190    }
191#endif // defined(EPROTO)
192    else
193      return true;
194
195    return false;
196  }
197}
198
199
200template <typename SockLenType>
201inline int call_bind(SockLenType msghdr::*,
202    socket_type s, const socket_addr_type* addr, std::size_t addrlen)
203{
204  return ::bind(s, addr, (SockLenType)addrlen);
205}
206
207int bind(socket_type s, const socket_addr_type* addr,
208    std::size_t addrlen, asio::error_code& ec)
209{
210  if (s == invalid_socket)
211  {
212    ec = asio::error::bad_descriptor;
213    return socket_error_retval;
214  }
215
216  clear_last_error();
217  int result = error_wrapper(call_bind(
218        &msghdr::msg_namelen, s, addr, addrlen), ec);
219  if (result == 0)
220    ec = asio::error_code();
221  return result;
222}
223
224int close(socket_type s, state_type& state,
225    bool destruction, asio::error_code& ec)
226{
227  int result = 0;
228  if (s != invalid_socket)
229  {
230    // We don't want the destructor to block, so set the socket to linger in
231    // the background. If the user doesn't like this behaviour then they need
232    // to explicitly close the socket.
233    if (destruction && (state & user_set_linger))
234    {
235      ::linger opt;
236      opt.l_onoff = 0;
237      opt.l_linger = 0;
238      asio::error_code ignored_ec;
239      socket_ops::setsockopt(s, state, SOL_SOCKET,
240          SO_LINGER, &opt, sizeof(opt), ignored_ec);
241    }
242
243    clear_last_error();
244    result = error_wrapper(::close(s), ec);
245
246    if (result != 0
247        && (ec == asio::error::would_block
248          || ec == asio::error::try_again))
249    {
250      // According to UNIX Network Programming Vol. 1, it is possible for
251      // close() to fail with EWOULDBLOCK under certain circumstances. What
252      // isn't clear is the state of the descriptor after this error. The one
253      // current OS where this behaviour is seen, Windows, says that the socket
254      // remains open. Therefore we'll put the descriptor back into blocking
255      // mode and have another attempt at closing it.
256      ioctl_arg_type arg = 0;
257      ::ioctl(s, FIONBIO, &arg);
258      state &= ~non_blocking;
259
260      clear_last_error();
261      result = error_wrapper(::close(s), ec);
262    }
263  }
264
265  if (result == 0)
266    ec = asio::error_code();
267  return result;
268}
269
270bool set_user_non_blocking(socket_type s,
271    state_type& state, bool value, asio::error_code& ec)
272{
273  if (s == invalid_socket)
274  {
275    ec = asio::error::bad_descriptor;
276    return false;
277  }
278
279  clear_last_error();
280  ioctl_arg_type arg = (value ? 1 : 0);
281  int result = error_wrapper(::ioctl(s, FIONBIO, &arg), ec);
282
283  if (result >= 0)
284  {
285    ec = asio::error_code();
286    if (value)
287      state |= user_set_non_blocking;
288    else
289    {
290      // Clearing the user-set non-blocking mode always overrides any
291      // internally-set non-blocking flag. Any subsequent asynchronous
292      // operations will need to re-enable non-blocking I/O.
293      state &= ~(user_set_non_blocking | internal_non_blocking);
294    }
295    return true;
296  }
297
298  return false;
299}
300
301bool set_internal_non_blocking(socket_type s,
302    state_type& state, bool value, asio::error_code& ec)
303{
304  if (s == invalid_socket)
305  {
306    ec = asio::error::bad_descriptor;
307    return false;
308  }
309
310  if (!value && (state & user_set_non_blocking))
311  {
312    // It does not make sense to clear the internal non-blocking flag if the
313    // user still wants non-blocking behaviour. Return an error and let the
314    // caller figure out whether to update the user-set non-blocking flag.
315    ec = asio::error::invalid_argument;
316    return false;
317  }
318
319  clear_last_error();
320  ioctl_arg_type arg = (value ? 1 : 0);
321  int result = error_wrapper(::ioctl(s, FIONBIO, &arg), ec);
322
323  if (result >= 0)
324  {
325    ec = asio::error_code();
326    if (value)
327      state |= internal_non_blocking;
328    else
329      state &= ~internal_non_blocking;
330    return true;
331  }
332
333  return false;
334}
335
336int shutdown(socket_type s, int what, asio::error_code& ec)
337{
338  if (s == invalid_socket)
339  {
340    ec = asio::error::bad_descriptor;
341    return socket_error_retval;
342  }
343
344  clear_last_error();
345  int result = error_wrapper(::shutdown(s, what), ec);
346  if (result == 0)
347    ec = asio::error_code();
348  return result;
349}
350
351template <typename SockLenType>
352inline int call_connect(SockLenType msghdr::*,
353    socket_type s, const socket_addr_type* addr, std::size_t addrlen)
354{
355  return ::connect(s, addr, (SockLenType)addrlen);
356}
357
358int connect(socket_type s, const socket_addr_type* addr,
359    std::size_t addrlen, asio::error_code& ec)
360{
361  if (s == invalid_socket)
362  {
363    ec = asio::error::bad_descriptor;
364    return socket_error_retval;
365  }
366
367  clear_last_error();
368  int result = error_wrapper(call_connect(
369        &msghdr::msg_namelen, s, addr, addrlen), ec);
370  if (result == 0)
371    ec = asio::error_code();
372#if defined(__linux__)
373  else if (ec == asio::error::try_again)
374    ec = asio::error::no_buffer_space;
375#endif // defined(__linux__)
376  return result;
377}
378
379void sync_connect(socket_type s, const socket_addr_type* addr,
380    std::size_t addrlen, asio::error_code& ec)
381{
382  // Perform the connect operation.
383  socket_ops::connect(s, addr, addrlen, ec);
384  if (ec != asio::error::in_progress
385      && ec != asio::error::would_block)
386  {
387    // The connect operation finished immediately.
388    return;
389  }
390
391  // Wait for socket to become ready.
392  if (socket_ops::poll_connect(s, ec) < 0)
393    return;
394
395  // Get the error code from the connect operation.
396  int connect_error = 0;
397  size_t connect_error_len = sizeof(connect_error);
398  if (socket_ops::getsockopt(s, 0, SOL_SOCKET, SO_ERROR,
399        &connect_error, &connect_error_len, ec) == socket_error_retval)
400    return;
401
402  // Return the result of the connect operation.
403  ec = asio::error_code(connect_error,
404      asio::error::get_system_category());
405}
406
407
408bool non_blocking_connect(socket_type s, asio::error_code& ec)
409{
410  // Check if the connect operation has finished. This is required since we may
411  // get spurious readiness notifications from the reactor.
412      // || defined(__CYGWIN__)
413      // || defined(__SYMBIAN32__)
414  pollfd fds;
415  fds.fd = s;
416  fds.events = POLLOUT;
417  fds.revents = 0;
418  int ready = ::poll(&fds, 1, 0);
419       // || defined(__CYGWIN__)
420       // || defined(__SYMBIAN32__)
421  if (ready == 0)
422  {
423    // The asynchronous connect operation is still in progress.
424    return false;
425  }
426
427  // Get the error code from the connect operation.
428  int connect_error = 0;
429  size_t connect_error_len = sizeof(connect_error);
430  if (socket_ops::getsockopt(s, 0, SOL_SOCKET, SO_ERROR,
431        &connect_error, &connect_error_len, ec) == 0)
432  {
433    if (connect_error)
434    {
435      ec = asio::error_code(connect_error,
436          asio::error::get_system_category());
437    }
438    else
439      ec = asio::error_code();
440  }
441
442  return true;
443}
444
445int socketpair(int af, int type, int protocol,
446    socket_type sv[2], asio::error_code& ec)
447{
448  clear_last_error();
449  int result = error_wrapper(::socketpair(af, type, protocol, sv), ec);
450  if (result == 0)
451    ec = asio::error_code();
452  return result;
453}
454
455bool sockatmark(socket_type s, asio::error_code& ec)
456{
457  if (s == invalid_socket)
458  {
459    ec = asio::error::bad_descriptor;
460    return false;
461  }
462
463#if defined(SIOCATMARK)
464  ioctl_arg_type value = 0;
465  int result = error_wrapper(::ioctl(s, SIOCATMARK, &value), ec);
466  if (result == 0)
467    ec = asio::error_code();
468# if defined(ENOTTY)
469  if (ec.value() == ENOTTY)
470    ec = asio::error::not_socket;
471# endif // defined(ENOTTY)
472#else // defined(SIOCATMARK)
473  int value = error_wrapper(::sockatmark(s), ec);
474  if (value != -1)
475    ec = asio::error_code();
476#endif // defined(SIOCATMARK)
477
478  return ec ? false : value != 0;
479}
480
481size_t available(socket_type s, asio::error_code& ec)
482{
483  if (s == invalid_socket)
484  {
485    ec = asio::error::bad_descriptor;
486    return 0;
487  }
488
489  ioctl_arg_type value = 0;
490  int result = error_wrapper(::ioctl(s, FIONREAD, &value), ec);
491  if (result == 0)
492    ec = asio::error_code();
493#if defined(ENOTTY)
494  if (ec.value() == ENOTTY)
495    ec = asio::error::not_socket;
496#endif // defined(ENOTTY)
497
498  return ec ? static_cast<size_t>(0) : static_cast<size_t>(value);
499}
500
501int listen(socket_type s, int backlog, asio::error_code& ec)
502{
503  if (s == invalid_socket)
504  {
505    ec = asio::error::bad_descriptor;
506    return socket_error_retval;
507  }
508
509  clear_last_error();
510  int result = error_wrapper(::listen(s, backlog), ec);
511  if (result == 0)
512    ec = asio::error_code();
513  return result;
514}
515
516inline void init_buf_iov_base(void*& base, void* addr)
517{
518  base = addr;
519}
520
521template <typename T>
522inline void init_buf_iov_base(T& base, void* addr)
523{
524  base = static_cast<T>(addr);
525}
526
527typedef iovec buf;
528
529void init_buf(buf& b, void* data, size_t size)
530{
531  init_buf_iov_base(b.iov_base, data);
532  b.iov_len = size;
533}
534
535void init_buf(buf& b, const void* data, size_t size)
536{
537  init_buf_iov_base(b.iov_base, const_cast<void*>(data));
538  b.iov_len = size;
539}
540
541inline void init_msghdr_msg_name(void*& name, socket_addr_type* addr)
542{
543  name = addr;
544}
545
546inline void init_msghdr_msg_name(void*& name, const socket_addr_type* addr)
547{
548  name = const_cast<socket_addr_type*>(addr);
549}
550
551template <typename T>
552inline void init_msghdr_msg_name(T& name, socket_addr_type* addr)
553{
554  name = reinterpret_cast<T>(addr);
555}
556
557template <typename T>
558inline void init_msghdr_msg_name(T& name, const socket_addr_type* addr)
559{
560  name = reinterpret_cast<T>(const_cast<socket_addr_type*>(addr));
561}
562
563signed_size_type recv(socket_type s, buf* bufs, size_t count,
564    int flags, asio::error_code& ec)
565{
566  clear_last_error();
567  msghdr msg = msghdr();
568  msg.msg_iov = bufs;
569  msg.msg_iovlen = static_cast<int>(count);
570  signed_size_type result = error_wrapper(::recvmsg(s, &msg, flags), ec);
571  if (result >= 0)
572    ec = asio::error_code();
573  return result;
574}
575
576size_t sync_recv(socket_type s, state_type state, buf* bufs,
577    size_t count, int flags, bool all_empty, asio::error_code& ec)
578{
579  if (s == invalid_socket)
580  {
581    ec = asio::error::bad_descriptor;
582    return 0;
583  }
584
585  // A request to read 0 bytes on a stream is a no-op.
586  if (all_empty && (state & stream_oriented))
587  {
588    ec = asio::error_code();
589    return 0;
590  }
591
592  // Read some data.
593  for (;;)
594  {
595    // Try to complete the operation without blocking.
596    signed_size_type bytes = socket_ops::recv(s, bufs, count, flags, ec);
597
598    // Check if operation succeeded.
599    if (bytes > 0)
600      return bytes;
601
602    // Check for EOF.
603    if ((state & stream_oriented) && bytes == 0)
604    {
605      ec = asio::error::eof;
606      return 0;
607    }
608
609    // Operation failed.
610    if ((state & user_set_non_blocking)
611        || (ec != asio::error::would_block
612          && ec != asio::error::try_again))
613      return 0;
614
615    // Wait for socket to become ready.
616    if (socket_ops::poll_read(s, 0, ec) < 0)
617      return 0;
618  }
619}
620
621
622bool non_blocking_recv(socket_type s,
623    buf* bufs, size_t count, int flags, bool is_stream,
624    asio::error_code& ec, size_t& bytes_transferred)
625{
626  for (;;)
627  {
628    // Read some data.
629    signed_size_type bytes = socket_ops::recv(s, bufs, count, flags, ec);
630
631    // Check for end of stream.
632    if (is_stream && bytes == 0)
633    {
634      ec = asio::error::eof;
635      return true;
636    }
637
638    // Retry operation if interrupted by signal.
639    if (ec == asio::error::interrupted)
640      continue;
641
642    // Check if we need to run the operation again.
643    if (ec == asio::error::would_block
644        || ec == asio::error::try_again)
645      return false;
646
647    // Operation is complete.
648    if (bytes >= 0)
649    {
650      ec = asio::error_code();
651      bytes_transferred = bytes;
652    }
653    else
654      bytes_transferred = 0;
655
656    return true;
657  }
658}
659
660
661signed_size_type recvfrom(socket_type s, buf* bufs, size_t count,
662    int flags, socket_addr_type* addr, std::size_t* addrlen,
663    asio::error_code& ec)
664{
665  clear_last_error();
666  msghdr msg = msghdr();
667  init_msghdr_msg_name(msg.msg_name, addr);
668  msg.msg_namelen = static_cast<int>(*addrlen);
669  msg.msg_iov = bufs;
670  msg.msg_iovlen = static_cast<int>(count);
671  signed_size_type result = error_wrapper(::recvmsg(s, &msg, flags), ec);
672  *addrlen = msg.msg_namelen;
673  if (result >= 0)
674    ec = asio::error_code();
675  return result;
676}
677
678size_t sync_recvfrom(socket_type s, state_type state, buf* bufs,
679    size_t count, int flags, socket_addr_type* addr,
680    std::size_t* addrlen, asio::error_code& ec)
681{
682  if (s == invalid_socket)
683  {
684    ec = asio::error::bad_descriptor;
685    return 0;
686  }
687
688  // Read some data.
689  for (;;)
690  {
691    // Try to complete the operation without blocking.
692    signed_size_type bytes = socket_ops::recvfrom(
693        s, bufs, count, flags, addr, addrlen, ec);
694
695    // Check if operation succeeded.
696    if (bytes >= 0)
697      return bytes;
698
699    // Operation failed.
700    if ((state & user_set_non_blocking)
701        || (ec != asio::error::would_block
702          && ec != asio::error::try_again))
703      return 0;
704
705    // Wait for socket to become ready.
706    if (socket_ops::poll_read(s, 0, ec) < 0)
707      return 0;
708  }
709}
710
711
712bool non_blocking_recvfrom(socket_type s,
713    buf* bufs, size_t count, int flags,
714    socket_addr_type* addr, std::size_t* addrlen,
715    asio::error_code& ec, size_t& bytes_transferred)
716{
717  for (;;)
718  {
719    // Read some data.
720    signed_size_type bytes = socket_ops::recvfrom(
721        s, bufs, count, flags, addr, addrlen, ec);
722
723    // Retry operation if interrupted by signal.
724    if (ec == asio::error::interrupted)
725      continue;
726
727    // Check if we need to run the operation again.
728    if (ec == asio::error::would_block
729        || ec == asio::error::try_again)
730      return false;
731
732    // Operation is complete.
733    if (bytes >= 0)
734    {
735      ec = asio::error_code();
736      bytes_transferred = bytes;
737    }
738    else
739      bytes_transferred = 0;
740
741    return true;
742  }
743}
744
745
746signed_size_type recvmsg(socket_type s, buf* bufs, size_t count,
747    int in_flags, int& out_flags, asio::error_code& ec)
748{
749  clear_last_error();
750  msghdr msg = msghdr();
751  msg.msg_iov = bufs;
752  msg.msg_iovlen = static_cast<int>(count);
753  signed_size_type result = error_wrapper(::recvmsg(s, &msg, in_flags), ec);
754  if (result >= 0)
755  {
756    ec = asio::error_code();
757    out_flags = msg.msg_flags;
758  }
759  else
760    out_flags = 0;
761  return result;
762}
763
764size_t sync_recvmsg(socket_type s, state_type state,
765    buf* bufs, size_t count, int in_flags, int& out_flags,
766    asio::error_code& ec)
767{
768  if (s == invalid_socket)
769  {
770    ec = asio::error::bad_descriptor;
771    return 0;
772  }
773
774  // Read some data.
775  for (;;)
776  {
777    // Try to complete the operation without blocking.
778    signed_size_type bytes = socket_ops::recvmsg(
779        s, bufs, count, in_flags, out_flags, ec);
780
781    // Check if operation succeeded.
782    if (bytes >= 0)
783      return bytes;
784
785    // Operation failed.
786    if ((state & user_set_non_blocking)
787        || (ec != asio::error::would_block
788          && ec != asio::error::try_again))
789      return 0;
790
791    // Wait for socket to become ready.
792    if (socket_ops::poll_read(s, 0, ec) < 0)
793      return 0;
794  }
795}
796
797
798bool non_blocking_recvmsg(socket_type s,
799    buf* bufs, size_t count, int in_flags, int& out_flags,
800    asio::error_code& ec, size_t& bytes_transferred)
801{
802  for (;;)
803  {
804    // Read some data.
805    signed_size_type bytes = socket_ops::recvmsg(
806        s, bufs, count, in_flags, out_flags, ec);
807
808    // Retry operation if interrupted by signal.
809    if (ec == asio::error::interrupted)
810      continue;
811
812    // Check if we need to run the operation again.
813    if (ec == asio::error::would_block
814        || ec == asio::error::try_again)
815      return false;
816
817    // Operation is complete.
818    if (bytes >= 0)
819    {
820      ec = asio::error_code();
821      bytes_transferred = bytes;
822    }
823    else
824      bytes_transferred = 0;
825
826    return true;
827  }
828}
829
830
831signed_size_type send(socket_type s, const buf* bufs, size_t count,
832    int flags, asio::error_code& ec)
833{
834  clear_last_error();
835  msghdr msg = msghdr();
836  msg.msg_iov = const_cast<buf*>(bufs);
837  msg.msg_iovlen = static_cast<int>(count);
838#if defined(__linux__)
839  flags |= MSG_NOSIGNAL;
840#endif // defined(__linux__)
841  signed_size_type result = error_wrapper(::sendmsg(s, &msg, flags), ec);
842  if (result >= 0)
843    ec = asio::error_code();
844  return result;
845}
846
847size_t sync_send(socket_type s, state_type state, const buf* bufs,
848    size_t count, int flags, bool all_empty, asio::error_code& ec)
849{
850  if (s == invalid_socket)
851  {
852    ec = asio::error::bad_descriptor;
853    return 0;
854  }
855
856  // A request to write 0 bytes to a stream is a no-op.
857  if (all_empty && (state & stream_oriented))
858  {
859    ec = asio::error_code();
860    return 0;
861  }
862
863  // Read some data.
864  for (;;)
865  {
866    // Try to complete the operation without blocking.
867    signed_size_type bytes = socket_ops::send(s, bufs, count, flags, ec);
868
869    // Check if operation succeeded.
870    if (bytes >= 0)
871      return bytes;
872
873    // Operation failed.
874    if ((state & user_set_non_blocking)
875        || (ec != asio::error::would_block
876          && ec != asio::error::try_again))
877      return 0;
878
879    // Wait for socket to become ready.
880    if (socket_ops::poll_write(s, 0, ec) < 0)
881      return 0;
882  }
883}
884
885
886bool non_blocking_send(socket_type s,
887    const buf* bufs, size_t count, int flags,
888    asio::error_code& ec, size_t& bytes_transferred)
889{
890  for (;;)
891  {
892    // Write some data.
893    signed_size_type bytes = socket_ops::send(s, bufs, count, flags, ec);
894
895    // Retry operation if interrupted by signal.
896    if (ec == asio::error::interrupted)
897      continue;
898
899    // Check if we need to run the operation again.
900    if (ec == asio::error::would_block
901        || ec == asio::error::try_again)
902      return false;
903
904    // Operation is complete.
905    if (bytes >= 0)
906    {
907      ec = asio::error_code();
908      bytes_transferred = bytes;
909    }
910    else
911      bytes_transferred = 0;
912
913    return true;
914  }
915}
916
917
918signed_size_type sendto(socket_type s, const buf* bufs, size_t count,
919    int flags, const socket_addr_type* addr, std::size_t addrlen,
920    asio::error_code& ec)
921{
922  clear_last_error();
923  msghdr msg = msghdr();
924  init_msghdr_msg_name(msg.msg_name, addr);
925  msg.msg_namelen = static_cast<int>(addrlen);
926  msg.msg_iov = const_cast<buf*>(bufs);
927  msg.msg_iovlen = static_cast<int>(count);
928#if defined(__linux__)
929  flags |= MSG_NOSIGNAL;
930#endif // defined(__linux__)
931  signed_size_type result = error_wrapper(::sendmsg(s, &msg, flags), ec);
932  if (result >= 0)
933    ec = asio::error_code();
934  return result;
935}
936
937size_t sync_sendto(socket_type s, state_type state, const buf* bufs,
938    size_t count, int flags, const socket_addr_type* addr,
939    std::size_t addrlen, asio::error_code& ec)
940{
941  if (s == invalid_socket)
942  {
943    ec = asio::error::bad_descriptor;
944    return 0;
945  }
946
947  // Write some data.
948  for (;;)
949  {
950    // Try to complete the operation without blocking.
951    signed_size_type bytes = socket_ops::sendto(
952        s, bufs, count, flags, addr, addrlen, ec);
953
954    // Check if operation succeeded.
955    if (bytes >= 0)
956      return bytes;
957
958    // Operation failed.
959    if ((state & user_set_non_blocking)
960        || (ec != asio::error::would_block
961          && ec != asio::error::try_again))
962      return 0;
963
964    // Wait for socket to become ready.
965    if (socket_ops::poll_write(s, 0, ec) < 0)
966      return 0;
967  }
968}
969
970
971bool non_blocking_sendto(socket_type s,
972    const buf* bufs, size_t count, int flags,
973    const socket_addr_type* addr, std::size_t addrlen,
974    asio::error_code& ec, size_t& bytes_transferred)
975{
976  for (;;)
977  {
978    // Write some data.
979    signed_size_type bytes = socket_ops::sendto(
980        s, bufs, count, flags, addr, addrlen, ec);
981
982    // Retry operation if interrupted by signal.
983    if (ec == asio::error::interrupted)
984      continue;
985
986    // Check if we need to run the operation again.
987    if (ec == asio::error::would_block
988        || ec == asio::error::try_again)
989      return false;
990
991    // Operation is complete.
992    if (bytes >= 0)
993    {
994      ec = asio::error_code();
995      bytes_transferred = bytes;
996    }
997    else
998      bytes_transferred = 0;
999
1000    return true;
1001  }
1002}
1003
1004
1005socket_type socket(int af, int type, int protocol,
1006    asio::error_code& ec)
1007{
1008  clear_last_error();
1009#if   defined(__MACH__) && defined(__APPLE__) || defined(__FreeBSD__)
1010  socket_type s = error_wrapper(::socket(af, type, protocol), ec);
1011  if (s == invalid_socket)
1012    return s;
1013
1014  int optval = 1;
1015  int result = error_wrapper(::setsockopt(s,
1016        SOL_SOCKET, SO_NOSIGPIPE, &optval, sizeof(optval)), ec);
1017  if (result != 0)
1018  {
1019    ::close(s);
1020    return invalid_socket;
1021  }
1022
1023  return s;
1024#else
1025  int s = error_wrapper(::socket(af, type, protocol), ec);
1026  if (s >= 0)
1027    ec = asio::error_code();
1028  return s;
1029#endif
1030}
1031
1032template <typename SockLenType>
1033inline int call_setsockopt(SockLenType msghdr::*,
1034    socket_type s, int level, int optname,
1035    const void* optval, std::size_t optlen)
1036{
1037  return ::setsockopt(s, level, optname,
1038      (const char*)optval, (SockLenType)optlen);
1039}
1040
1041int setsockopt(socket_type s, state_type& state, int level, int optname,
1042    const void* optval, std::size_t optlen, asio::error_code& ec)
1043{
1044  if (s == invalid_socket)
1045  {
1046    ec = asio::error::bad_descriptor;
1047    return socket_error_retval;
1048  }
1049
1050  if (level == custom_socket_option_level && optname == always_fail_option)
1051  {
1052    ec = asio::error::invalid_argument;
1053    return socket_error_retval;
1054  }
1055
1056  if (level == custom_socket_option_level
1057      && optname == enable_connection_aborted_option)
1058  {
1059    if (optlen != sizeof(int))
1060    {
1061      ec = asio::error::invalid_argument;
1062      return socket_error_retval;
1063    }
1064
1065    if (*static_cast<const int*>(optval))
1066      state |= enable_connection_aborted;
1067    else
1068      state &= ~enable_connection_aborted;
1069    ec = asio::error_code();
1070    return 0;
1071  }
1072
1073  if (level == SOL_SOCKET && optname == SO_LINGER)
1074    state |= user_set_linger;
1075
1076  clear_last_error();
1077  int result = error_wrapper(call_setsockopt(&msghdr::msg_namelen,
1078        s, level, optname, optval, optlen), ec);
1079  if (result == 0)
1080  {
1081    ec = asio::error_code();
1082
1083#if defined(__MACH__) && defined(__APPLE__)    || defined(__NetBSD__) || defined(__FreeBSD__) || defined(__OpenBSD__)
1084    // To implement portable behaviour for SO_REUSEADDR with UDP sockets we
1085    // need to also set SO_REUSEPORT on BSD-based platforms.
1086    if ((state & datagram_oriented)
1087        && level == SOL_SOCKET && optname == SO_REUSEADDR)
1088    {
1089      call_setsockopt(&msghdr::msg_namelen, s,
1090          SOL_SOCKET, SO_REUSEPORT, optval, optlen);
1091    }
1092#endif
1093  }
1094
1095  return result;
1096}
1097
1098template <typename SockLenType>
1099inline int call_getsockopt(SockLenType msghdr::*,
1100    socket_type s, int level, int optname,
1101    void* optval, std::size_t* optlen)
1102{
1103  SockLenType tmp_optlen = (SockLenType)*optlen;
1104  int result = ::getsockopt(s, level, optname, (char*)optval, &tmp_optlen);
1105  *optlen = (std::size_t)tmp_optlen;
1106  return result;
1107}
1108
1109int getsockopt(socket_type s, state_type state, int level, int optname,
1110    void* optval, size_t* optlen, asio::error_code& ec)
1111{
1112  if (s == invalid_socket)
1113  {
1114    ec = asio::error::bad_descriptor;
1115    return socket_error_retval;
1116  }
1117
1118  if (level == custom_socket_option_level && optname == always_fail_option)
1119  {
1120    ec = asio::error::invalid_argument;
1121    return socket_error_retval;
1122  }
1123
1124  if (level == custom_socket_option_level
1125      && optname == enable_connection_aborted_option)
1126  {
1127    if (*optlen != sizeof(int))
1128    {
1129      ec = asio::error::invalid_argument;
1130      return socket_error_retval;
1131    }
1132
1133    *static_cast<int*>(optval) = (state & enable_connection_aborted) ? 1 : 0;
1134    ec = asio::error_code();
1135    return 0;
1136  }
1137
1138  clear_last_error();
1139  int result = error_wrapper(call_getsockopt(&msghdr::msg_namelen,
1140        s, level, optname, optval, optlen), ec);
1141#if defined(__linux__)
1142  if (result == 0 && level == SOL_SOCKET && *optlen == sizeof(int)
1143      && (optname == SO_SNDBUF || optname == SO_RCVBUF))
1144  {
1145    // On Linux, setting SO_SNDBUF or SO_RCVBUF to N actually causes the kernel
1146    // to set the buffer size to N*2. Linux puts additional stuff into the
1147    // buffers so that only about half is actually available to the application.
1148    // The retrieved value is divided by 2 here to make it appear as though the
1149    // correct value has been set.
1150    *static_cast<int*>(optval) /= 2;
1151  }
1152#endif // defined(__linux__)
1153  if (result == 0)
1154    ec = asio::error_code();
1155  return result;
1156}
1157
1158template <typename SockLenType>
1159inline int call_getpeername(SockLenType msghdr::*,
1160    socket_type s, socket_addr_type* addr, std::size_t* addrlen)
1161{
1162  SockLenType tmp_addrlen = (SockLenType)*addrlen;
1163  int result = ::getpeername(s, addr, &tmp_addrlen);
1164  *addrlen = (std::size_t)tmp_addrlen;
1165  return result;
1166}
1167
1168int getpeername(socket_type s, socket_addr_type* addr,
1169    std::size_t* addrlen, bool cached, asio::error_code& ec)
1170{
1171  if (s == invalid_socket)
1172  {
1173    ec = asio::error::bad_descriptor;
1174    return socket_error_retval;
1175  }
1176
1177  (void)cached;
1178
1179  clear_last_error();
1180  int result = error_wrapper(call_getpeername(
1181        &msghdr::msg_namelen, s, addr, addrlen), ec);
1182  if (result == 0)
1183    ec = asio::error_code();
1184  return result;
1185}
1186
1187template <typename SockLenType>
1188inline int call_getsockname(SockLenType msghdr::*,
1189    socket_type s, socket_addr_type* addr, std::size_t* addrlen)
1190{
1191  SockLenType tmp_addrlen = (SockLenType)*addrlen;
1192  int result = ::getsockname(s, addr, &tmp_addrlen);
1193  *addrlen = (std::size_t)tmp_addrlen;
1194  return result;
1195}
1196
1197int getsockname(socket_type s, socket_addr_type* addr,
1198    std::size_t* addrlen, asio::error_code& ec)
1199{
1200  if (s == invalid_socket)
1201  {
1202    ec = asio::error::bad_descriptor;
1203    return socket_error_retval;
1204  }
1205
1206  clear_last_error();
1207  int result = error_wrapper(call_getsockname(
1208        &msghdr::msg_namelen, s, addr, addrlen), ec);
1209  if (result == 0)
1210    ec = asio::error_code();
1211  return result;
1212}
1213
1214int ioctl(socket_type s, state_type& state, int cmd,
1215    ioctl_arg_type* arg, asio::error_code& ec)
1216{
1217  if (s == invalid_socket)
1218  {
1219    ec = asio::error::bad_descriptor;
1220    return socket_error_retval;
1221  }
1222
1223  clear_last_error();
1224#if   defined(__MACH__) && defined(__APPLE__)    || defined(__NetBSD__) || defined(__FreeBSD__) || defined(__OpenBSD__)
1225  int result = error_wrapper(::ioctl(s,
1226        static_cast<unsigned int>(cmd), arg), ec);
1227#else
1228  int result = error_wrapper(::ioctl(s, cmd, arg), ec);
1229#endif
1230  if (result >= 0)
1231  {
1232    ec = asio::error_code();
1233
1234    // When updating the non-blocking mode we always perform the ioctl syscall,
1235    // even if the flags would otherwise indicate that the socket is already in
1236    // the correct state. This ensures that the underlying socket is put into
1237    // the state that has been requested by the user. If the ioctl syscall was
1238    // successful then we need to update the flags to match.
1239    if (cmd == static_cast<int>(FIONBIO))
1240    {
1241      if (*arg)
1242      {
1243        state |= user_set_non_blocking;
1244      }
1245      else
1246      {
1247        // Clearing the non-blocking mode always overrides any internally-set
1248        // non-blocking flag. Any subsequent asynchronous operations will need
1249        // to re-enable non-blocking I/O.
1250        state &= ~(user_set_non_blocking | internal_non_blocking);
1251      }
1252    }
1253  }
1254
1255  return result;
1256}
1257
1258int select(int nfds, fd_set* readfds, fd_set* writefds,
1259    fd_set* exceptfds, timeval* timeout, asio::error_code& ec)
1260{
1261  clear_last_error();
1262
1263#if defined(__hpux) && defined(__SELECT)
1264  timespec ts;
1265  ts.tv_sec = timeout ? timeout->tv_sec : 0;
1266  ts.tv_nsec = timeout ? timeout->tv_usec * 1000 : 0;
1267  return error_wrapper(::pselect(nfds, readfds,
1268        writefds, exceptfds, timeout ? &ts : 0, 0), ec);
1269#else
1270  int result = error_wrapper(::select(nfds, readfds,
1271        writefds, exceptfds, timeout), ec);
1272  if (result >= 0)
1273    ec = asio::error_code();
1274  return result;
1275#endif
1276}
1277
1278int poll_read(socket_type s, state_type state, asio::error_code& ec)
1279{
1280  if (s == invalid_socket)
1281  {
1282    ec = asio::error::bad_descriptor;
1283    return socket_error_retval;
1284  }
1285
1286      // || defined(__CYGWIN__)
1287      // || defined(__SYMBIAN32__)
1288  pollfd fds;
1289  fds.fd = s;
1290  fds.events = POLLIN;
1291  fds.revents = 0;
1292  int timeout = (state & user_set_non_blocking) ? 0 : -1;
1293  clear_last_error();
1294  int result = error_wrapper(::poll(&fds, 1, timeout), ec);
1295       // || defined(__CYGWIN__)
1296       // || defined(__SYMBIAN32__)
1297  if (result == 0)
1298    ec = (state & user_set_non_blocking)
1299      ? asio::error::would_block : asio::error_code();
1300  else if (result > 0)
1301    ec = asio::error_code();
1302  return result;
1303}
1304
1305int poll_write(socket_type s, state_type state, asio::error_code& ec)
1306{
1307  if (s == invalid_socket)
1308  {
1309    ec = asio::error::bad_descriptor;
1310    return socket_error_retval;
1311  }
1312
1313      // || defined(__CYGWIN__)
1314      // || defined(__SYMBIAN32__)
1315  pollfd fds;
1316  fds.fd = s;
1317  fds.events = POLLOUT;
1318  fds.revents = 0;
1319  int timeout = (state & user_set_non_blocking) ? 0 : -1;
1320  clear_last_error();
1321  int result = error_wrapper(::poll(&fds, 1, timeout), ec);
1322       // || defined(__CYGWIN__)
1323       // || defined(__SYMBIAN32__)
1324  if (result == 0)
1325    ec = (state & user_set_non_blocking)
1326      ? asio::error::would_block : asio::error_code();
1327  else if (result > 0)
1328    ec = asio::error_code();
1329  return result;
1330}
1331
1332int poll_connect(socket_type s, asio::error_code& ec)
1333{
1334  if (s == invalid_socket)
1335  {
1336    ec = asio::error::bad_descriptor;
1337    return socket_error_retval;
1338  }
1339
1340      // || defined(__CYGWIN__)
1341      // || defined(__SYMBIAN32__)
1342  pollfd fds;
1343  fds.fd = s;
1344  fds.events = POLLOUT;
1345  fds.revents = 0;
1346  clear_last_error();
1347  int result = error_wrapper(::poll(&fds, 1, -1), ec);
1348  if (result >= 0)
1349    ec = asio::error_code();
1350  return result;
1351       // || defined(__CYGWIN__)
1352       // || defined(__SYMBIAN32__)
1353}
1354
1355
1356const char* inet_ntop(int af, const void* src, char* dest, size_t length,
1357    unsigned long scope_id, asio::error_code& ec)
1358{
1359  clear_last_error();
1360  const char* result = error_wrapper(::inet_ntop(
1361        af, src, dest, static_cast<int>(length)), ec);
1362  if (result == 0 && !ec)
1363    ec = asio::error::invalid_argument;
1364  if (result != 0 && af == ASIO_OS_DEF(AF_INET6) && scope_id != 0)
1365  {
1366    using namespace std; // For strcat and sprintf.
1367    char if_name[IF_NAMESIZE + 1] = "%";
1368    const in6_addr_type* ipv6_address = static_cast<const in6_addr_type*>(src);
1369    bool is_link_local = ((ipv6_address->s6_addr[0] == 0xfe)
1370        && ((ipv6_address->s6_addr[1] & 0xc0) == 0x80));
1371    bool is_multicast_link_local = ((ipv6_address->s6_addr[0] == 0xff)
1372        && ((ipv6_address->s6_addr[1] & 0x0f) == 0x02));
1373    if ((!is_link_local && !is_multicast_link_local)
1374        || if_indextoname(static_cast<unsigned>(scope_id), if_name + 1) == 0)
1375      sprintf(if_name + 1, "%lu", scope_id);
1376    strcat(dest, if_name);
1377  }
1378  return result;
1379}
1380
1381int inet_pton(int af, const char* src, void* dest,
1382    unsigned long* scope_id, asio::error_code& ec)
1383{
1384  clear_last_error();
1385  using namespace std; // For strchr, memcpy and atoi.
1386
1387  // On some platforms, inet_pton fails if an address string contains a scope
1388  // id. Detect and remove the scope id before passing the string to inet_pton.
1389  const bool is_v6 = (af == ASIO_OS_DEF(AF_INET6));
1390  const char* if_name = is_v6 ? strchr(src, '%') : 0;
1391  char src_buf[max_addr_v6_str_len + 1];
1392  const char* src_ptr = src;
1393  if (if_name != 0)
1394  {
1395    if (if_name - src > max_addr_v6_str_len)
1396    {
1397      ec = asio::error::invalid_argument;
1398      return 0;
1399    }
1400    memcpy(src_buf, src, if_name - src);
1401    src_buf[if_name - src] = 0;
1402    src_ptr = src_buf;
1403  }
1404
1405  int result = error_wrapper(::inet_pton(af, src_ptr, dest), ec);
1406  if (result <= 0 && !ec)
1407    ec = asio::error::invalid_argument;
1408  if (result > 0 && is_v6 && scope_id)
1409  {
1410    using namespace std; // For strchr and atoi.
1411    *scope_id = 0;
1412    if (if_name != 0)
1413    {
1414      in6_addr_type* ipv6_address = static_cast<in6_addr_type*>(dest);
1415      bool is_link_local = ((ipv6_address->s6_addr[0] == 0xfe)
1416          && ((ipv6_address->s6_addr[1] & 0xc0) == 0x80));
1417      bool is_multicast_link_local = ((ipv6_address->s6_addr[0] == 0xff)
1418          && ((ipv6_address->s6_addr[1] & 0x0f) == 0x02));
1419      if (is_link_local || is_multicast_link_local)
1420        *scope_id = if_nametoindex(if_name + 1);
1421      if (*scope_id == 0)
1422        *scope_id = atoi(if_name + 1);
1423    }
1424  }
1425  return result;
1426}
1427
1428int gethostname(char* name, int namelen, asio::error_code& ec)
1429{
1430  clear_last_error();
1431  int result = error_wrapper(::gethostname(name, namelen), ec);
1432  return result;
1433}
1434
1435
1436
1437inline asio::error_code translate_addrinfo_error(int error)
1438{
1439  switch (error)
1440  {
1441  case 0:
1442    return asio::error_code();
1443  case EAI_AGAIN:
1444    return asio::error::host_not_found_try_again;
1445  case EAI_BADFLAGS:
1446    return asio::error::invalid_argument;
1447  case EAI_FAIL:
1448    return asio::error::no_recovery;
1449  case EAI_FAMILY:
1450    return asio::error::address_family_not_supported;
1451  case EAI_MEMORY:
1452    return asio::error::no_memory;
1453  case EAI_NONAME:
1454#if defined(EAI_ADDRFAMILY)
1455  case EAI_ADDRFAMILY:
1456#endif
1457#if defined(EAI_NODATA) && (EAI_NODATA != EAI_NONAME)
1458  case EAI_NODATA:
1459#endif
1460    return asio::error::host_not_found;
1461  case EAI_SERVICE:
1462    return asio::error::service_not_found;
1463  case EAI_SOCKTYPE:
1464    return asio::error::socket_type_not_supported;
1465  default: // Possibly the non-portable EAI_SYSTEM.
1466    return asio::error_code(
1467        errno, asio::error::get_system_category());
1468  }
1469}
1470
1471asio::error_code getaddrinfo(const char* host,
1472    const char* service, const addrinfo_type& hints,
1473    addrinfo_type** result, asio::error_code& ec)
1474{
1475  host = (host && *host) ? host : 0;
1476  service = (service && *service) ? service : 0;
1477  clear_last_error();
1478  int error = ::getaddrinfo(host, service, &hints, result);
1479  return ec = translate_addrinfo_error(error);
1480}
1481
1482asio::error_code background_getaddrinfo(
1483    const weak_cancel_token_type& cancel_token, const char* host,
1484    const char* service, const addrinfo_type& hints,
1485    addrinfo_type** result, asio::error_code& ec)
1486{
1487  if (cancel_token.expired())
1488    ec = asio::error::operation_aborted;
1489  else
1490    socket_ops::getaddrinfo(host, service, hints, result, ec);
1491  return ec;
1492}
1493
1494void freeaddrinfo(addrinfo_type* ai)
1495{
1496  ::freeaddrinfo(ai);
1497}
1498
1499asio::error_code getnameinfo(const socket_addr_type* addr,
1500    std::size_t addrlen, char* host, std::size_t hostlen,
1501    char* serv, std::size_t servlen, int flags, asio::error_code& ec)
1502{
1503  clear_last_error();
1504  int error = ::getnameinfo(addr, addrlen, host, hostlen, serv, servlen, flags);
1505  return ec = translate_addrinfo_error(error);
1506}
1507
1508asio::error_code sync_getnameinfo(
1509    const socket_addr_type* addr, std::size_t addrlen,
1510    char* host, std::size_t hostlen, char* serv,
1511    std::size_t servlen, int sock_type, asio::error_code& ec)
1512{
1513  // First try resolving with the service name. If that fails try resolving
1514  // but allow the service to be returned as a number.
1515  int flags = (sock_type == SOCK_DGRAM) ? NI_DGRAM : 0;
1516  socket_ops::getnameinfo(addr, addrlen, host,
1517      hostlen, serv, servlen, flags, ec);
1518  if (ec)
1519  {
1520    socket_ops::getnameinfo(addr, addrlen, host, hostlen,
1521        serv, servlen, flags | NI_NUMERICSERV, ec);
1522  }
1523
1524  return ec;
1525}
1526
1527asio::error_code background_getnameinfo(
1528    const weak_cancel_token_type& cancel_token,
1529    const socket_addr_type* addr, std::size_t addrlen,
1530    char* host, std::size_t hostlen, char* serv,
1531    std::size_t servlen, int sock_type, asio::error_code& ec)
1532{
1533  if (cancel_token.expired())
1534  {
1535    ec = asio::error::operation_aborted;
1536  }
1537  else
1538  {
1539    // First try resolving with the service name. If that fails try resolving
1540    // but allow the service to be returned as a number.
1541    int flags = (sock_type == SOCK_DGRAM) ? NI_DGRAM : 0;
1542    socket_ops::getnameinfo(addr, addrlen, host,
1543        hostlen, serv, servlen, flags, ec);
1544    if (ec)
1545    {
1546      socket_ops::getnameinfo(addr, addrlen, host, hostlen,
1547          serv, servlen, flags | NI_NUMERICSERV, ec);
1548    }
1549  }
1550
1551  return ec;
1552}
1553
1554
1555u_long_type network_to_host_long(u_long_type value)
1556{
1557  return ntohl(value);
1558}
1559
1560u_long_type host_to_network_long(u_long_type value)
1561{
1562  return htonl(value);
1563}
1564
1565u_short_type network_to_host_short(u_short_type value)
1566{
1567  return ntohs(value);
1568}
1569
1570u_short_type host_to_network_short(u_short_type value)
1571{
1572  return htons(value);
1573}
1574
1575} // namespace socket_ops
1576} // namespace detail
1577} // namespace asio
1578
1579#include "asio/detail/pop_options.hpp"
1580
1581#endif // ASIO_DETAIL_SOCKET_OPS_IPP
1582