uvw  2.10.0
udp.h
1 #ifndef UVW_UDP_INCLUDE_H
2 #define UVW_UDP_INCLUDE_H
3 
4 
5 #include <type_traits>
6 #include <utility>
7 #include <cstddef>
8 #include <memory>
9 #include <string>
10 #include <uv.h>
11 #include "request.hpp"
12 #include "handle.hpp"
13 #include "util.h"
14 
15 
16 namespace uvw {
17 
18 
24 struct SendEvent {};
25 
26 
32 struct UDPDataEvent {
33  explicit UDPDataEvent(Addr sndr, std::unique_ptr<char[]> buf, std::size_t len, bool part) noexcept;
34 
35  std::unique_ptr<char[]> data;
36  std::size_t length;
38  bool partial;
39 };
40 
41 
42 namespace details {
43 
44 
45 enum class UVUDPFlags: std::underlying_type_t<uv_udp_flags> {
46  IPV6ONLY = UV_UDP_IPV6ONLY,
47  UDP_PARTIAL = UV_UDP_PARTIAL,
48  REUSEADDR = UV_UDP_REUSEADDR,
49  UDP_MMSG_CHUNK = UV_UDP_MMSG_CHUNK,
50  UDP_MMSG_FREE = UV_UDP_MMSG_FREE,
51  UDP_LINUX_RECVERR = UV_UDP_LINUX_RECVERR,
52  UDP_RECVMMSG = UV_UDP_RECVMMSG
53 };
54 
55 
56 enum class UVMembership: std::underlying_type_t<uv_membership> {
57  LEAVE_GROUP = UV_LEAVE_GROUP,
58  JOIN_GROUP = UV_JOIN_GROUP
59 };
60 
61 
62 class SendReq final: public Request<SendReq, uv_udp_send_t> {
63 public:
64  using Deleter = void(*)(char *);
65 
66  SendReq(ConstructorAccess ca, std::shared_ptr<Loop> loop, std::unique_ptr<char[], Deleter> dt, unsigned int len);
67 
68  void send(uv_udp_t *handle, const struct sockaddr* addr);
69 
70 private:
71  std::unique_ptr<char[], Deleter> data;
72  uv_buf_t buf;
73 };
74 
75 
76 }
77 
78 
95 class UDPHandle final: public Handle<UDPHandle, uv_udp_t> {
96  template<typename I>
97  static void recvCallback(uv_udp_t *handle, ssize_t nread, const uv_buf_t *buf, const sockaddr *addr, unsigned flags) {
98  const typename details::IpTraits<I>::Type *aptr = reinterpret_cast<const typename details::IpTraits<I>::Type *>(addr);
99 
100  UDPHandle &udp = *(static_cast<UDPHandle*>(handle->data));
101  // data will be destroyed no matter of what the value of nread is
102  std::unique_ptr<char[]> data{buf->base};
103 
104  if(nread > 0) {
105  // data available (can be truncated)
106  udp.publish(UDPDataEvent{details::address<I>(aptr), std::move(data), static_cast<std::size_t>(nread), !(0 == (flags & UV_UDP_PARTIAL))});
107  } else if(nread == 0 && addr == nullptr) {
108  // no more data to be read, doing nothing is fine
109  } else if(nread == 0 && addr != nullptr) {
110  // empty udp packet
111  udp.publish(UDPDataEvent{details::address<I>(aptr), std::move(data), static_cast<std::size_t>(nread), false});
112  } else {
113  // transmission error
114  udp.publish(ErrorEvent(nread));
115  }
116  }
117 
118 public:
119  using Membership = details::UVMembership;
120  using Bind = details::UVUDPFlags;
121  using IPv4 = uvw::IPv4;
122  using IPv6 = uvw::IPv6;
123 
124  explicit UDPHandle(ConstructorAccess ca, std::shared_ptr<Loop> ref, unsigned int f = {});
125 
130  bool init();
131 
144  void open(OSSocketHandle socket);
145 
166  void bind(const sockaddr &addr, Flags<Bind> opts = Flags<Bind>{});
167 
181  void connect(const sockaddr &addr);
182 
197  template<typename I = IPv4>
198  void connect(const std::string &ip, unsigned int port);
199 
213  template<typename I = IPv4>
214  void connect(Addr addr);
215 
223  void disconnect();
224 
229  template<typename I = IPv4>
230  Addr peer() const noexcept;
231 
253  template<typename I = IPv4>
254  void bind(const std::string &ip, unsigned int port, Flags<Bind> opts = Flags<Bind>{});
255 
276  template<typename I = IPv4>
277  void bind(Addr addr, Flags<Bind> opts = Flags<Bind>{});
278 
283  template<typename I = IPv4>
284  Addr sock() const noexcept;
285 
299  template<typename I = IPv4>
300  bool multicastMembership(const std::string &multicast, const std::string &iface, Membership membership);
301 
310  bool multicastLoop(bool enable = true);
311 
317  bool multicastTtl(int val);
318 
324  template<typename I = IPv4>
325  bool multicastInterface(const std::string &iface);
326 
332  bool broadcast(bool enable = false);
333 
339  bool ttl(int val);
340 
358  void send(const sockaddr &addr, std::unique_ptr<char[]> data, unsigned int len);
359 
378  template<typename I = IPv4>
379  void send(const std::string &ip, unsigned int port, std::unique_ptr<char[]> data, unsigned int len);
380 
398  template<typename I = IPv4>
399  void send(Addr addr, std::unique_ptr<char[]> data, unsigned int len);
400 
418  void send(const sockaddr &addr, char *data, unsigned int len);
419 
438  template<typename I = IPv4>
439  void send(const std::string &ip, unsigned int port, char *data, unsigned int len);
440 
458  template<typename I = IPv4>
459  void send(Addr addr, char *data, unsigned int len);
460 
472  template<typename I = IPv4>
473  int trySend(const sockaddr &addr, std::unique_ptr<char[]> data, unsigned int len);
474 
487  template<typename I = IPv4>
488  int trySend(const std::string &ip, unsigned int port, std::unique_ptr<char[]> data, unsigned int len);
489 
501  template<typename I = IPv4>
502  int trySend(Addr addr, std::unique_ptr<char[]> data, unsigned int len);
503 
515  template<typename I = IPv4>
516  int trySend(const sockaddr &addr, char *data, unsigned int len);
517 
530  template<typename I = IPv4>
531  int trySend(const std::string &ip, unsigned int port, char *data, unsigned int len);
532 
544  template<typename I = IPv4>
545  int trySend(Addr addr, char *data, unsigned int len);
546 
557  template<typename I = IPv4>
558  void recv();
559 
563  void stop();
564 
572  size_t sendQueueSize() const noexcept;
573 
578  size_t sendQueueCount() const noexcept;
579 
580 private:
581  enum { DEFAULT, FLAGS } tag{DEFAULT};
582  unsigned int flags{};
583 };
584 
585 
592 // (extern) explicit instantiations
593 #ifdef UVW_AS_LIB
594 extern template void UDPHandle::connect<IPv4>(const std::string &, unsigned int);
595 extern template void UDPHandle::connect<IPv6>(const std::string &, unsigned int);
596 
597 extern template void UDPHandle::connect<IPv4>(Addr);
598 extern template void UDPHandle::connect<IPv6>(Addr);
599 
600 extern template Addr UDPHandle::peer<IPv4>() const noexcept;
601 extern template Addr UDPHandle::peer<IPv6>() const noexcept;
602 
603 extern template void UDPHandle::bind<IPv4>(const std::string &, unsigned int, Flags<Bind>);
604 extern template void UDPHandle::bind<IPv6>(const std::string &, unsigned int, Flags<Bind>);
605 
606 extern template void UDPHandle::bind<IPv4>(Addr, Flags<Bind>);
607 extern template void UDPHandle::bind<IPv6>(Addr, Flags<Bind>);
608 
609 extern template Addr UDPHandle::sock<IPv4>() const noexcept;
610 extern template Addr UDPHandle::sock<IPv6>() const noexcept;
611 
612 extern template bool UDPHandle::multicastMembership<IPv4>(const std::string &, const std::string &, Membership);
613 extern template bool UDPHandle::multicastMembership<IPv6>(const std::string &, const std::string &, Membership);
614 
615 extern template bool UDPHandle::multicastInterface<IPv4>(const std::string &);
616 extern template bool UDPHandle::multicastInterface<IPv6>(const std::string &);
617 
618 extern template void UDPHandle::send<IPv4>(const std::string &, unsigned int, std::unique_ptr<char[]>, unsigned int);
619 extern template void UDPHandle::send<IPv6>(const std::string &, unsigned int, std::unique_ptr<char[]>, unsigned int);
620 
621 extern template void UDPHandle::send<IPv4>(Addr, std::unique_ptr<char[]>, unsigned int);
622 extern template void UDPHandle::send<IPv6>(Addr, std::unique_ptr<char[]>, unsigned int);
623 
624 extern template void UDPHandle::send<IPv4>(const std::string &, unsigned int, char *, unsigned int);
625 extern template void UDPHandle::send<IPv6>(const std::string &, unsigned int, char *, unsigned int);
626 
627 extern template void UDPHandle::send<IPv4>(Addr, char *, unsigned int);
628 extern template void UDPHandle::send<IPv6>(Addr, char *, unsigned int);
629 
630 extern template int UDPHandle::trySend<IPv4>(const sockaddr &, std::unique_ptr<char[]>, unsigned int);
631 extern template int UDPHandle::trySend<IPv6>(const sockaddr &, std::unique_ptr<char[]>, unsigned int);
632 
633 extern template int UDPHandle::trySend<IPv4>(const std::string &, unsigned int, std::unique_ptr<char[]>, unsigned int);
634 extern template int UDPHandle::trySend<IPv6>(const std::string &, unsigned int, std::unique_ptr<char[]>, unsigned int);
635 
636 extern template int UDPHandle::trySend<IPv4>(Addr, std::unique_ptr<char[]>, unsigned int);
637 extern template int UDPHandle::trySend<IPv6>(Addr, std::unique_ptr<char[]>, unsigned int);
638 
639 extern template int UDPHandle::trySend<IPv4>(const sockaddr &, char *, unsigned int);
640 extern template int UDPHandle::trySend<IPv6>(const sockaddr &, char *, unsigned int);
641 
642 extern template int UDPHandle::trySend<IPv4>(const std::string &, unsigned int, char *, unsigned int);
643 extern template int UDPHandle::trySend<IPv6>(const std::string &, unsigned int, char *, unsigned int);
644 
645 extern template int UDPHandle::trySend<IPv4>(Addr, char *, unsigned int);
646 extern template int UDPHandle::trySend<IPv6>(Addr, char *, unsigned int);
647 
648 extern template void UDPHandle::recv<IPv4>();
649 extern template void UDPHandle::recv<IPv6>();
650 #endif // UVW_AS_LIB
651 
652 
659 }
660 
661 
662 #ifndef UVW_AS_LIB
663 #include "udp.cpp"
664 #endif
665 
666 
667 #endif // UVW_UDP_INCLUDE_H
Utility class to handle flags.
Definition: util.h:82
Handle base class.
Definition: handle.hpp:30
std::shared_ptr< R > data() const
Gets user-defined data. uvw won't use this field in any case.
Definition: resource.hpp:52
The UDPHandle handle.
Definition: udp.h:95
bool init()
Initializes the handle. The actual socket is created lazily.
void stop()
Stops listening for incoming datagrams.
bool broadcast(bool enable=false)
Sets broadcast on or off.
void connect(Addr addr)
Associates the handle to a remote address and port (either IPv4 or IPv6).
size_t sendQueueSize() const noexcept
Gets the number of bytes queued for sending.
void bind(const sockaddr &addr, Flags< Bind > opts=Flags< Bind >{})
Binds the UDP handle to an IP address and port.
int trySend(const sockaddr &addr, std::unique_ptr< char[]> data, unsigned int len)
Sends data over the UDP socket.
size_t sendQueueCount() const noexcept
Number of send requests currently in the queue awaiting to be processed.
void bind(Addr addr, Flags< Bind > opts=Flags< Bind >{})
Binds the UDP handle to an IP address and port.
bool multicastTtl(int val)
Sets the multicast ttl.
Addr peer() const noexcept
Gets the remote address to which the handle is connected, if any.
void send(const sockaddr &addr, std::unique_ptr< char[]> data, unsigned int len)
Sends data over the UDP socket.
void recv()
Prepares for receiving data.
bool multicastInterface(const std::string &iface)
Sets the multicast interface to send or receive data on.
bool ttl(int val)
Sets the time to live.
bool multicastMembership(const std::string &multicast, const std::string &iface, Membership membership)
Sets membership for a multicast address.
Addr sock() const noexcept
Get the local IP and port of the UDP handle.
void disconnect()
Disconnects the handle.
void connect(const sockaddr &addr)
Associates the handle to a remote address and port (either IPv4 or IPv6).
void open(OSSocketHandle socket)
Opens an existing file descriptor or SOCKET as a UDP handle.
void connect(const std::string &ip, unsigned int port)
Associates the handle to a remote address and port (either IPv4 or IPv6).
bool multicastLoop(bool enable=true)
Sets IP multicast loop flag.
uvw default namespace.
Definition: async.h:10
details::UVTypeWrapper< uv_os_sock_t > OSSocketHandle
Definition: util.h:190
Address representation.
Definition: util.h:321
The ErrorEvent event.
Definition: emitter.h:25
The IPv4 tag.
Definition: util.h:307
The IPv6 tag.
Definition: util.h:315
SendEvent event.
Definition: udp.h:24
UDPDataEvent event.
Definition: udp.h:32
std::size_t length
Definition: udp.h:36
Addr sender
Definition: udp.h:37
bool partial
Definition: udp.h:38
std::unique_ptr< char[]> data
Definition: udp.h:35