25#ifndef JOIN_CORE_DATAGRAM_SOCKET_HPP
26#define JOIN_CORE_DATAGRAM_SOCKET_HPP
39 template <
class Protocol>
40 class BasicDatagramSocket final :
public BasicRawSocket<Protocol>
43 using Ptr = std::unique_ptr<BasicDatagramSocket<Protocol>>;
96 ,
_remote (std::move (other._remote))
111 _remote = std::move (other._remote);
139 if ((
protocol.protocol () == IPPROTO_UDP) || (
protocol.protocol () == IPPROTO_TCP))
141 if ((
protocol.family () == AF_INET6) &&
142 (::setsockopt (this->_handle, IPPROTO_IPV6, IPV6_V6ONLY, &off, sizeof (off)) == -1))
145 lastError = std::error_code (errno, std::generic_category ());
152 if ((
protocol.protocol () == IPPROTO_ICMPV6) || (
protocol.protocol () == IPPROTO_ICMP))
154 if ((
protocol.family () == AF_INET) &&
155 (::setsockopt (this->_handle, IPPROTO_IP, IP_HDRINCL, &off, sizeof (off)) == -1))
158 lastError = std::error_code (errno, std::generic_category ());
180 if ((this->
_state != State::Closed) && (this->
_state != State::Disconnected))
186 if ((this->
_state == State::Closed) && (
open (endpoint.protocol ()) == -1))
193 lastError = std::error_code (errno, std::generic_category ());
199 this->
_state = State::Connected;
210 if (this->
_state == State::Connected)
212 struct sockaddr_storage nullAddr;
213 ::memset (&nullAddr, 0,
sizeof (nullAddr));
215 nullAddr.ss_family = AF_UNSPEC;
217 int result =
::connect (this->
_handle,
reinterpret_cast<struct sockaddr*
> (&nullAddr),
218 sizeof (
struct sockaddr_storage));
222 if (errno != EAFNOSUPPORT)
224 lastError = std::error_code (errno, std::generic_category ());
230 this->
_state = State::Disconnected;
255 ssize_t
readFrom (
char* data,
size_t maxSize,
Endpoint* endpoint =
nullptr,
char* control =
nullptr,
256 size_t* controlSize =
nullptr) noexcept
258 struct sockaddr_storage sa;
262 iov.iov_len = maxSize;
264 struct msghdr message;
265 message.msg_name = &sa;
266 message.msg_namelen =
sizeof (
struct sockaddr_storage);
267 message.msg_iov = &iov;
268 message.msg_iovlen = 1;
269 message.msg_control = control;
270 message.msg_controllen = controlSize ? *controlSize : 0;
272 ssize_t size = ::recvmsg (this->
_handle, &message, 0);
275 lastError = std::error_code (errno, std::generic_category ());
279 if (message.msg_flags & (MSG_TRUNC | MSG_CTRUNC))
285 if (endpoint !=
nullptr)
287 *endpoint =
Endpoint (
reinterpret_cast<struct sockaddr*
> (&sa), message.msg_namelen);
290 if (controlSize !=
nullptr)
292 *controlSize = message.msg_controllen;
307 ssize_t
writeTo (
const char* data,
size_t size,
const Endpoint& endpoint,
const char* control =
nullptr,
308 size_t controlSize = 0) noexcept
310 if ((this->
_state == State::Closed) && (
open (endpoint.protocol ()) == -1))
316 iov.iov_base =
const_cast<char*
> (data);
319 struct msghdr message;
320 message.msg_name =
const_cast<struct sockaddr*
> (endpoint.addr ());
321 message.msg_namelen = endpoint.length ();
322 message.msg_iov = &iov;
323 message.msg_iovlen = 1;
324 message.msg_control =
const_cast<char*
> (control);
325 message.msg_controllen = controlSize;
326 message.msg_flags = 0;
328 ssize_t result = ::sendmsg (this->
_handle, &message, 0);
331 lastError = std::error_code (errno, std::generic_category ());
353 return (this->
_state == State::Connected);
362 if (this->
_state == State::Closed)
368 int result = -1, value = -1;
369 socklen_t valueLen =
sizeof (value);
371 if (this->
family () == AF_INET6)
373 result = ::getsockopt (this->
_handle, IPPROTO_IPV6, IPV6_MTU, &value, &valueLen);
375 else if (this->
family () == AF_INET)
377 result = ::getsockopt (this->
_handle, IPPROTO_IP, IP_MTU, &value, &valueLen);
387 lastError = std::error_code (errno, std::generic_category ());
basic datagram socket class.
Definition protocol.hpp:50
typename BasicRawSocket< Protocol >::Option Option
Definition datagram_socket.hpp:45
bool connected() const noexcept
check if the socket is connected.
Definition datagram_socket.hpp:351
BasicDatagramSocket(const BasicDatagramSocket &other)=delete
Copy constructor.
ssize_t writeTo(const char *data, size_t size, const Endpoint &endpoint, const char *control=nullptr, size_t controlSize=0) noexcept
write data on the socket.
Definition datagram_socket.hpp:307
const Endpoint & remoteEndpoint() const noexcept
determine the remote endpoint associated with this socket.
Definition datagram_socket.hpp:342
int mtu() const noexcept
get socket mtu.
Definition datagram_socket.hpp:360
std::unique_ptr< BasicDatagramSocket< Protocol > > Ptr
Definition datagram_socket.hpp:43
int disconnect() noexcept
remove the default remote endpoint.
Definition datagram_socket.hpp:208
Endpoint _remote
remote endpoint.
Definition datagram_socket.hpp:405
typename BasicRawSocket< Protocol >::Mode Mode
Definition datagram_socket.hpp:44
int _ttl
packet time to live.
Definition datagram_socket.hpp:408
typename BasicRawSocket< Protocol >::State State
Definition datagram_socket.hpp:46
BasicDatagramSocket() noexcept
Default constructor.
Definition datagram_socket.hpp:52
~BasicDatagramSocket()=default
Destroy the instance.
typename Protocol::Endpoint Endpoint
Definition datagram_socket.hpp:47
void close() noexcept override
close the socket handle.
Definition datagram_socket.hpp:240
ssize_t readFrom(char *data, size_t maxSize, Endpoint *endpoint=nullptr, char *control=nullptr, size_t *controlSize=nullptr) noexcept
read data on the socket.
Definition datagram_socket.hpp:255
int connect(const Endpoint &endpoint) noexcept
assign the default remote endpoint for this socket.
Definition datagram_socket.hpp:178
BasicDatagramSocket & operator=(const BasicDatagramSocket &other)=delete
Copy assignment operator.
BasicDatagramSocket(BasicDatagramSocket &&other) noexcept
Move constructor.
Definition datagram_socket.hpp:94
BasicDatagramSocket(int ttl) noexcept
Create instance specifying the time to live.
Definition datagram_socket.hpp:61
int ttl() const noexcept
returns the Time-To-Live value.
Definition datagram_socket.hpp:398
BasicDatagramSocket(Mode mode, int ttl=60) noexcept
Create instance specifying the mode.
Definition datagram_socket.hpp:71
int open(const Protocol &protocol=Protocol()) noexcept override
open socket using the given protocol.
Definition datagram_socket.hpp:129
basic raw socket class.
Definition raw_socket.hpp:42
typename BasicSocket< Protocol >::Mode Mode
Definition raw_socket.hpp:45
typename BasicSocket< Protocol >::State State
Definition raw_socket.hpp:46
Option
socket options.
Definition raw_socket.hpp:53
BasicRawSocket & operator=(const BasicRawSocket &other)=delete
copy assignment operator.
virtual int setOption(Option option, int value) noexcept
set the given option to the given value.
Definition raw_socket.hpp:277
BasicRawSocket() noexcept
default constructor.
Definition raw_socket.hpp:76
virtual int open(const Protocol &protocol=Protocol()) noexcept
open socket using the given protocol.
Definition socket.hpp:168
Mode mode() const noexcept
get the blocking mode of the socket.
Definition socket.hpp:374
virtual void close() noexcept
close the socket.
Definition socket.hpp:203
int family() const noexcept
get socket address family.
Definition socket.hpp:347
@ NonBlocking
Definition socket.hpp:69
State _state
socket state.
Definition socket.hpp:468
int protocol() const noexcept
get socket protocol.
Definition socket.hpp:365
int _handle
socket handle.
Definition socket.hpp:474
Definition acceptor.hpp:32
std::error_code make_error_code(join::Errc code) noexcept
Create an std::error_code object.
Definition error.cpp:195