uvw 2.12.1
Loading...
Searching...
No Matches
udp.h
1#ifndef UVW_UDP_INCLUDE_H
2#define UVW_UDP_INCLUDE_H
3
4#include <cstddef>
5#include <memory>
6#include <string>
7#include <type_traits>
8#include <utility>
9#include <uv.h>
10#include "handle.hpp"
11#include "request.hpp"
12#include "util.h"
13
14namespace uvw {
15
21struct SendEvent {};
22
29 explicit UDPDataEvent(Addr sndr, std::unique_ptr<char[]> buf, std::size_t len, bool part) noexcept;
30
31 std::unique_ptr<char[]> data;
32 std::size_t length;
34 bool partial;
35};
36
37namespace details {
38
39enum class UVUDPFlags : std::underlying_type_t<uv_udp_flags> {
40 IPV6ONLY = UV_UDP_IPV6ONLY,
41 UDP_PARTIAL = UV_UDP_PARTIAL,
42 REUSEADDR = UV_UDP_REUSEADDR,
43 UDP_MMSG_CHUNK = UV_UDP_MMSG_CHUNK,
44 UDP_MMSG_FREE = UV_UDP_MMSG_FREE,
45 UDP_LINUX_RECVERR = UV_UDP_LINUX_RECVERR,
46 UDP_RECVMMSG = UV_UDP_RECVMMSG
47};
48
49enum class UVMembership : std::underlying_type_t<uv_membership> {
50 LEAVE_GROUP = UV_LEAVE_GROUP,
51 JOIN_GROUP = UV_JOIN_GROUP
52};
53
54class SendReq final: public Request<SendReq, uv_udp_send_t> {
55public:
56 using Deleter = void (*)(char *);
57
58 SendReq(ConstructorAccess ca, std::shared_ptr<Loop> loop, std::unique_ptr<char[], Deleter> dt, unsigned int len);
59
60 void send(uv_udp_t *handle, const struct sockaddr *addr);
61
62private:
63 std::unique_ptr<char[], Deleter> data;
64 uv_buf_t buf;
65};
66
67} // namespace details
68
85class UDPHandle final: public Handle<UDPHandle, uv_udp_t> {
86 template<typename I>
87 static void recvCallback(uv_udp_t *handle, ssize_t nread, const uv_buf_t *buf, const sockaddr *addr, unsigned flags) {
88 const typename details::IpTraits<I>::Type *aptr = reinterpret_cast<const typename details::IpTraits<I>::Type *>(addr);
89
90 UDPHandle &udp = *(static_cast<UDPHandle *>(handle->data));
91 // data will be destroyed no matter of what the value of nread is
92 std::unique_ptr<char[]> data{buf->base};
93
94 if(nread > 0) {
95 // data available (can be truncated)
96 udp.publish(UDPDataEvent{details::address<I>(aptr), std::move(data), static_cast<std::size_t>(nread), !(0 == (flags & UV_UDP_PARTIAL))});
97 } else if(nread == 0 && addr == nullptr) {
98 // no more data to be read, doing nothing is fine
99 } else if(nread == 0 && addr != nullptr) {
100 // empty udp packet
101 udp.publish(UDPDataEvent{details::address<I>(aptr), std::move(data), static_cast<std::size_t>(nread), false});
102 } else {
103 // transmission error
104 udp.publish(ErrorEvent(nread));
105 }
106 }
107
108public:
109 using Membership = details::UVMembership;
110 using Bind = details::UVUDPFlags;
111 using IPv4 = uvw::IPv4;
112 using IPv6 = uvw::IPv6;
113
114 explicit UDPHandle(ConstructorAccess ca, std::shared_ptr<Loop> ref, unsigned int f = {});
115
120 bool init();
121
134 void open(OSSocketHandle socket);
135
156 void bind(const sockaddr &addr, Flags<Bind> opts = Flags<Bind>{});
157
171 void connect(const sockaddr &addr);
172
187 template<typename I = IPv4>
188 void connect(const std::string &ip, unsigned int port);
189
203 template<typename I = IPv4>
204 void connect(Addr addr);
205
214
219 template<typename I = IPv4>
220 Addr peer() const noexcept;
221
243 template<typename I = IPv4>
244 void bind(const std::string &ip, unsigned int port, Flags<Bind> opts = Flags<Bind>{});
245
266 template<typename I = IPv4>
267 void bind(Addr addr, Flags<Bind> opts = Flags<Bind>{});
268
273 template<typename I = IPv4>
274 Addr sock() const noexcept;
275
289 template<typename I = IPv4>
290 bool multicastMembership(const std::string &multicast, const std::string &iface, Membership membership);
291
300 bool multicastLoop(bool enable = true);
301
307 bool multicastTtl(int val);
308
314 template<typename I = IPv4>
315 bool multicastInterface(const std::string &iface);
316
322 bool broadcast(bool enable = false);
323
329 bool ttl(int val);
330
348 void send(const sockaddr &addr, std::unique_ptr<char[]> data, unsigned int len);
349
368 template<typename I = IPv4>
369 void send(const std::string &ip, unsigned int port, std::unique_ptr<char[]> data, unsigned int len);
370
388 template<typename I = IPv4>
389 void send(Addr addr, std::unique_ptr<char[]> data, unsigned int len);
390
408 void send(const sockaddr &addr, char *data, unsigned int len);
409
428 template<typename I = IPv4>
429 void send(const std::string &ip, unsigned int port, char *data, unsigned int len);
430
448 template<typename I = IPv4>
449 void send(Addr addr, char *data, unsigned int len);
450
462 template<typename I = IPv4>
463 int trySend(const sockaddr &addr, std::unique_ptr<char[]> data, unsigned int len);
464
477 template<typename I = IPv4>
478 int trySend(const std::string &ip, unsigned int port, std::unique_ptr<char[]> data, unsigned int len);
479
491 template<typename I = IPv4>
492 int trySend(Addr addr, std::unique_ptr<char[]> data, unsigned int len);
493
505 template<typename I = IPv4>
506 int trySend(const sockaddr &addr, char *data, unsigned int len);
507
520 template<typename I = IPv4>
521 int trySend(const std::string &ip, unsigned int port, char *data, unsigned int len);
522
534 template<typename I = IPv4>
535 int trySend(Addr addr, char *data, unsigned int len);
536
547 template<typename I = IPv4>
548 void recv();
549
553 void stop();
554
562 size_t sendQueueSize() const noexcept;
563
568 size_t sendQueueCount() const noexcept;
569
570private:
571 enum {
572 DEFAULT,
573 FLAGS
574 } tag{DEFAULT};
575
576 unsigned int flags{};
577};
578
584// (extern) explicit instantiations
585#ifdef UVW_AS_LIB
586extern template void UDPHandle::connect<IPv4>(const std::string &, unsigned int);
587extern template void UDPHandle::connect<IPv6>(const std::string &, unsigned int);
588
589extern template void UDPHandle::connect<IPv4>(Addr);
590extern template void UDPHandle::connect<IPv6>(Addr);
591
592extern template Addr UDPHandle::peer<IPv4>() const noexcept;
593extern template Addr UDPHandle::peer<IPv6>() const noexcept;
594
595extern template void UDPHandle::bind<IPv4>(const std::string &, unsigned int, Flags<Bind>);
596extern template void UDPHandle::bind<IPv6>(const std::string &, unsigned int, Flags<Bind>);
597
598extern template void UDPHandle::bind<IPv4>(Addr, Flags<Bind>);
599extern template void UDPHandle::bind<IPv6>(Addr, Flags<Bind>);
600
601extern template Addr UDPHandle::sock<IPv4>() const noexcept;
602extern template Addr UDPHandle::sock<IPv6>() const noexcept;
603
604extern template bool UDPHandle::multicastMembership<IPv4>(const std::string &, const std::string &, Membership);
605extern template bool UDPHandle::multicastMembership<IPv6>(const std::string &, const std::string &, Membership);
606
607extern template bool UDPHandle::multicastInterface<IPv4>(const std::string &);
608extern template bool UDPHandle::multicastInterface<IPv6>(const std::string &);
609
610extern template void UDPHandle::send<IPv4>(const std::string &, unsigned int, std::unique_ptr<char[]>, unsigned int);
611extern template void UDPHandle::send<IPv6>(const std::string &, unsigned int, std::unique_ptr<char[]>, unsigned int);
612
613extern template void UDPHandle::send<IPv4>(Addr, std::unique_ptr<char[]>, unsigned int);
614extern template void UDPHandle::send<IPv6>(Addr, std::unique_ptr<char[]>, unsigned int);
615
616extern template void UDPHandle::send<IPv4>(const std::string &, unsigned int, char *, unsigned int);
617extern template void UDPHandle::send<IPv6>(const std::string &, unsigned int, char *, unsigned int);
618
619extern template void UDPHandle::send<IPv4>(Addr, char *, unsigned int);
620extern template void UDPHandle::send<IPv6>(Addr, char *, unsigned int);
621
622extern template int UDPHandle::trySend<IPv4>(const sockaddr &, std::unique_ptr<char[]>, unsigned int);
623extern template int UDPHandle::trySend<IPv6>(const sockaddr &, std::unique_ptr<char[]>, unsigned int);
624
625extern template int UDPHandle::trySend<IPv4>(const std::string &, unsigned int, std::unique_ptr<char[]>, unsigned int);
626extern template int UDPHandle::trySend<IPv6>(const std::string &, unsigned int, std::unique_ptr<char[]>, unsigned int);
627
628extern template int UDPHandle::trySend<IPv4>(Addr, std::unique_ptr<char[]>, unsigned int);
629extern template int UDPHandle::trySend<IPv6>(Addr, std::unique_ptr<char[]>, unsigned int);
630
631extern template int UDPHandle::trySend<IPv4>(const sockaddr &, char *, unsigned int);
632extern template int UDPHandle::trySend<IPv6>(const sockaddr &, char *, unsigned int);
633
634extern template int UDPHandle::trySend<IPv4>(const std::string &, unsigned int, char *, unsigned int);
635extern template int UDPHandle::trySend<IPv6>(const std::string &, unsigned int, char *, unsigned int);
636
637extern template int UDPHandle::trySend<IPv4>(Addr, char *, unsigned int);
638extern template int UDPHandle::trySend<IPv6>(Addr, char *, unsigned int);
639
640extern template void UDPHandle::recv<IPv4>();
641extern template void UDPHandle::recv<IPv6>();
642#endif // UVW_AS_LIB
643
649} // namespace uvw
650
651#ifndef UVW_AS_LIB
652# include "udp.cpp"
653#endif
654
655#endif // UVW_UDP_INCLUDE_H
Utility class to handle flags.
Definition util.h:80
Handle base class.
Definition handle.hpp:26
std::shared_ptr< R > data() const
Definition resource.hpp:48
The UDPHandle handle.
Definition udp.h:85
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:8
details::UVTypeWrapper< uv_os_sock_t > OSSocketHandle
Definition util.h:206
Address representation.
Definition util.h:332
The ErrorEvent event.
Definition emitter.h:23
The IPv4 tag.
Definition util.h:320
The IPv6 tag.
Definition util.h:327
SendEvent event.
Definition udp.h:21
UDPDataEvent event.
Definition udp.h:28
std::size_t length
Definition udp.h:32
Addr sender
Definition udp.h:33
bool partial
Definition udp.h:34
std::unique_ptr< char[]> data
Definition udp.h:31