Ticket #4787: boost_1_44_0.asio.patch

File boost_1_44_0.asio.patch, 7.4 KB (added by saleyn@…, 12 years ago)

Support of optional datagram control headers.

  • boost/asio/detail/impl/socket_ops.ipp

    old new  
    741741
    742742int recvfrom(socket_type s, buf* bufs, size_t count, int flags,
    743743    socket_addr_type* addr, std::size_t* addrlen,
     744    void* control, std::size_t controllen,
    744745    boost::system::error_code& ec)
    745746{
    746747  clear_last_error();
     
    767768  msg.msg_namelen = *addrlen;
    768769  msg.msg_iov = bufs;
    769770  msg.msg_iovlen = count;
     771  if (controllen > 0) {
     772    msg.msg_control = control;
     773    msg.msg_controllen = controllen;
     774  }
    770775  int result = error_wrapper(::recvmsg(s, &msg, flags), ec);
    771776  *addrlen = msg.msg_namelen;
    772777  if (result >= 0)
     
    777782
    778783size_t sync_recvfrom(socket_type s, state_type state, buf* bufs,
    779784    size_t count, int flags, socket_addr_type* addr,
    780     std::size_t* addrlen, boost::system::error_code& ec)
     785    std::size_t* addrlen,
     786    void* control, std::size_t controllen,
     787    boost::system::error_code& ec)
    781788{
    782789  if (s == invalid_socket)
    783790  {
     
    789796  for (;;)
    790797  {
    791798    // Try to complete the operation without blocking.
    792     int bytes = socket_ops::recvfrom(s, bufs, count, flags, addr, addrlen, ec);
     799    int bytes = socket_ops::recvfrom(s, bufs, count,
     800        flags, addr, addrlen, control, controllen, ec);
    793801
    794802    // Check if operation succeeded.
    795803    if (bytes >= 0)
     
    837845  for (;;)
    838846  {
    839847    // Read some data.
    840     int bytes = socket_ops::recvfrom(s, bufs, count, flags, addr, addrlen, ec);
     848    int bytes = socket_ops::recvfrom(s, bufs, count, flags, addr, addrlen, NULL, 0, ec);
    841849
    842850    // Retry operation if interrupted by signal.
    843851    if (ec == boost::asio::error::interrupted)
  • boost/asio/detail/win_iocp_socket_service.hpp

    old new  
    306306    std::size_t addr_len = sender_endpoint.capacity();
    307307    std::size_t bytes_recvd = socket_ops::sync_recvfrom(
    308308        impl.socket_, impl.state_, bufs.buffers(), bufs.count(),
    309         flags, sender_endpoint.data(), &addr_len, ec);
     309        flags, sender_endpoint.data(), &addr_len, NULL, 0, ec);
    310310
    311311    if (!ec)
    312312      sender_endpoint.resize(addr_len);
  • boost/asio/detail/reactive_socket_service.hpp

    old new  
    238238    std::size_t addr_len = sender_endpoint.capacity();
    239239    std::size_t bytes_recvd = socket_ops::sync_recvfrom(
    240240        impl.socket_, impl.state_, bufs.buffers(), bufs.count(),
    241         flags, sender_endpoint.data(), &addr_len, ec);
     241        flags, sender_endpoint.data(), &addr_len,
     242        sender_endpoint.control(), sender_endpoint.control_size(),
     243        ec);
    242244
    243245    if (!ec)
    244246      sender_endpoint.resize(addr_len);
  • boost/asio/detail/socket_ops.hpp

    old new  
    145145
    146146BOOST_ASIO_DECL int recvfrom(socket_type s, buf* bufs, size_t count, int flags,
    147147    socket_addr_type* addr, std::size_t* addrlen,
     148    void* control, std::size_t controllen,
    148149    boost::system::error_code& ec);
    149150
    150151BOOST_ASIO_DECL size_t sync_recvfrom(socket_type s, state_type state,
    151152    buf* bufs, size_t count, int flags, socket_addr_type* addr,
    152     std::size_t* addrlen, boost::system::error_code& ec);
     153    std::size_t* addrlen, void* control, std::size_t controllen,
     154    boost::system::error_code& ec);
    153155
    154156#if defined(BOOST_ASIO_HAS_IOCP)
    155157
  • boost/asio/ip/basic_endpoint.hpp

    old new  
    136136    impl_.resize(size);
    137137  }
    138138
     139  /// Get the underlying endpoint's first control header for recvfrom calls.
     140  const struct cmsghdr* control_header_first() const
     141  {
     142    return impl_.control_header_first();
     143  }
     144
     145  /// Get the underlying endpoint's next control header for recvfrom calls.
     146  const struct cmsghdr* control_header_next(const cmsghdr* prev) const
     147  {
     148    return impl_.control_header_next(prev);
     149  }
     150
     151  /// Get the underlying size of the endpoint's buffer used to store
     152  /// control messages.
     153  template <typename T>
     154  T control_msg_data(const struct cmsghdr* cmsg) const
     155  {
     156    return impl_.control_msg_data<T>(cmsg);
     157  }
     158
     159  /// Get the underlying endpoint's control message given its header.
     160  void* control_msg() const
     161  {
     162    return impl_.control_msg();
     163  }
     164
     165  /// Get the underlying size of the endpoint's buffer used to store
     166  /// control messages.
     167  std::size_t control_size() const
     168  {
     169    return impl_.control_size();
     170  }
     171
     172  /// Set the size of the buffer used for storing control message.
     173  void control_size(size_t size)
     174  {
     175    impl_.control_size(size);
     176  }
     177
    139178  /// Get the capacity of the endpoint in the native type.
    140179  std::size_t capacity() const
    141180  {
  • boost/asio/ip/detail/endpoint.hpp

    old new  
    7777      return sizeof(boost::asio::detail::sockaddr_in6_type);
    7878  }
    7979
     80  /// Get the underlying endpoint's first control header for recvfrom calls.
     81  const struct cmsghdr* control_header_first() const
     82  {
     83    return CMSG_FIRSTHDR(control_.msg());
     84  }
     85
     86  /// Get the underlying endpoint's next control header for recvfrom calls.
     87  const struct cmsghdr* control_header_next(const cmsghdr* prev) const
     88  {
     89    return static_cast<const struct cmsghdr*>(
     90      CMSG_NXTHDR(const_cast<struct msghdr*>(control_.msg()),
     91                  const_cast<struct cmsghdr*>(prev)));
     92  }
     93
     94  /// Get the underlying size of the endpoint's buffer used to store
     95  /// control messages.
     96  template <typename T>
     97  T control_msg_data(const struct cmsghdr* cmsg) const
     98  {
     99    return reinterpret_cast<T>(CMSG_DATA(cmsg));
     100  }
     101
     102  /// Get the underlying endpoint's control message given its header.
     103  void* control_msg() const
     104  {
     105    return control_.msg()->msg_control;
     106  }
     107
     108  /// Get the underlying size of the endpoint's buffer used to store
     109  /// control messages.
     110  std::size_t control_size() const
     111  {
     112    return control_.msg()->msg_controllen;
     113  }
     114
     115  /// Set the size of the buffer used for storing control message.
     116  void control_size(size_t size)
     117  {
     118    control_.allocate(size);
     119  }
     120
    80121  // Set the underlying size of the endpoint in the native type.
    81122  BOOST_ASIO_DECL void resize(std::size_t size);
    82123
     
    126167    boost::asio::detail::sockaddr_in4_type v4;
    127168    boost::asio::detail::sockaddr_in6_type v6;
    128169  } data_;
     170
     171  // Space for control message for receive
     172  struct control
     173  {
     174    control()
     175    {
     176        memset(&msg_, 0, sizeof(msghdr));
     177    }
     178    ~control()
     179    {
     180        allocate(0);
     181    }
     182    void allocate(size_t sz)
     183    {
     184      if (msg_.msg_control)
     185          delete [] (char*)msg_.msg_control;
     186      if (sz == 0)
     187          return;
     188      size_t n = sz > sizeof(struct cmsghdr) ? sz : sizeof(struct cmsghdr)+128;
     189      msg_.msg_control    = new char[n];
     190      msg_.msg_controllen = n;
     191      memset(msg_.msg_control, 0, n);
     192    }
     193
     194    const  msghdr*  msg()  const { return &msg_; }
     195    const  cmsghdr* cmsg() const { return static_cast<const cmsghdr*>(msg_.msg_control); }
     196    size_t          cmsg_len()   { return msg_.msg_controllen; }
     197  private:
     198    msghdr msg_;
     199  } control_;
    129200};
    130201
    131202} // namespace detail