libcppwrap
A collection of C++ wrappers for native APIs
Loading...
Searching...
No Matches
sockets.hpp
Go to the documentation of this file.
1//
2// libcppwrap - A collection of C++ wrappers for native APIs
3// Copyright (C) 2021-2023 David A. Norris <danorris@gmail.com>
4// Published under the MIT license - https://opensource.org/licenses/MIT
5//
6
7#pragma once
8
9#include <cstddef>
10#include <cstdint>
11#include <cstring>
12#include <stdexcept>
13
14#include <ifaddrs.h>
15#include <netinet/ip6.h>
16#include <sys/socket.h>
17#include <sys/types.h>
18#include <sys/un.h>
19
20#include <w/handle.hpp>
21#include <w/iterators.hpp>
22#include <w/posix.hpp>
23
24namespace w
25{
29 struct ipv4_address : sockaddr_in
30 {
38
46 ipv4_address(const char *address, std::uint16_t port = 0);
47
55 ipv4_address(const in_addr& address, std::uint16_t port = 0);
56 };
57
61 struct ipv6_address : sockaddr_in6
62 {
70
78 ipv6_address(const char *address, std::uint16_t port = 0);
79
88 ipv6_address(const char *address, std::uint16_t port, unsigned interface_index);
89
99 ipv6_address(const char *address, std::uint16_t port, const char *interface_name);
100
108 ipv6_address(const in6_addr& address, std::uint16_t port = 0);
109
118 ipv6_address(const in6_addr& address, std::uint16_t port, unsigned interface_index);
119
129 ipv6_address(const in6_addr& address, std::uint16_t port, const char *interface_name);
130 };
131
135 struct unix_domain_address : sockaddr_un
136 {
143 unix_domain_address(const char *path);
144 };
145
157 w::fd accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
158
169 template <typename Address>
170 w::fd accept(int sockfd, Address& addr)
171 {
172 socklen_t addrlen = sizeof(addr);
173 w::fd fd = w::accept(sockfd, reinterpret_cast<struct sockaddr *>(&addr), &addrlen);
174
175 if (addrlen != sizeof(addr))
176 throw std::runtime_error(
177 "provided structure is not the correct size to hold receive connect address");
178
179 return fd;
180 }
181
190 void bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen);
191
200 template <typename Address>
201 void bind(int sockfd, const Address& addr)
202 {
203 w::bind(sockfd, reinterpret_cast<const struct sockaddr *>(&addr), sizeof(addr));
204 }
205
214 void connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen);
215
224 template <typename Address>
225 void connect(int sockfd, const Address& addr)
226 {
227 w::connect(sockfd, reinterpret_cast<const struct sockaddr *>(&addr), sizeof(addr));
228 }
229
237
251 int getsockopt(int sockfd, int level, int optname,
252 void *optval = nullptr, socklen_t *optlen = nullptr);
253
264 template <typename Value>
265 Value getsockopt(int sockfd, int level, int optname)
266 {
267 Value optval;
268 socklen_t optlen = sizeof(optval);
269 w::getsockopt(sockfd, level, optname, &optval, &optlen);
270 if (optlen != sizeof(optval))
271 throw std::runtime_error(
272 "wrong size value expected for socket option");
273 return optval;
274 }
275
283 unsigned if_nametoindex(const char *ifname);
284
295 char *inet_ntop(int af, const void *src, char *dst, socklen_t size);
296
306 void *inet_pton(int af, const char *src, void *dst);
307
317 template <typename Address>
318 Address& inet_pton(int af, const char *src, Address& dst)
319 {
320 w::inet_pton(af, src, static_cast<void *>(&dst));
321 return dst;
322 }
323
331 void listen(int sockfd, int backlog);
332
343 std::size_t recv(int sockfd, void *buf, std::size_t len, int flags = 0);
344
354 std::size_t recvmsg(int sockfd, struct msghdr *msg, int flags = 0);
355
372 std::size_t recvfrom(int sockfd, void *buf, std::size_t len, int flags,
373 struct sockaddr *src_addr = nullptr, socklen_t *addrlen = nullptr);
374
389 template <typename Address>
390 std::size_t recvfrom(int sockfd, void *buf, std::size_t len, int flags, Address& src_addr)
391 {
392 socklen_t addrlen = sizeof(src_addr);
393 std::size_t rv = w::recvfrom(sockfd, buf, len, flags,
394 reinterpret_cast<struct sockaddr *>(&src_addr), &addrlen);
395
396 if (addrlen != sizeof(src_addr))
397 throw std::runtime_error(
398 "provided structure is not the correct size to hold receive source address");
399
400 return rv;
401 }
402
413 std::size_t send(int sockfd, const void *buf, std::size_t len, int flags = 0);
414
424 std::size_t sendmsg(int sockfd, const struct msghdr *msg, int flags = 0);
425
438 std::size_t sendto(int sockfd, const void *buf, std::size_t len,
439 int flags, const struct sockaddr *dest_addr, socklen_t addrlen);
440
453 template <typename Address>
454 std::size_t sendto(int sockfd, const void *buf, std::size_t len,
455 int flags, const Address& dest_addr)
456 {
457 return w::sendto(sockfd, buf, len, flags,
458 reinterpret_cast<const struct sockaddr *>(&dest_addr), sizeof(dest_addr));
459 }
460
472 int setsockopt(int sockfd, int level, int optname,
473 const void *optval = nullptr, socklen_t optlen = 0);
474
485 template <typename Value>
486 void setsockopt(int sockfd, int level, int optname, const Value& optval)
487 {
488 w::setsockopt(sockfd, level, optname, &optval, sizeof(optval));
489 }
490
498 void shutdown(int sockfd, int how);
499
509 w::fd socket(int domain, int type, int protocol = 0);
510}
511
512namespace w::detail
513{
514 inline const struct ifaddrs *get_next_ifaddrs(const struct ifaddrs *cur)
515 {
516 return cur->ifa_next;
517 }
518}
519
526inline auto begin(const struct ifaddrs *ptr) noexcept
527{
529}
530
537inline auto end(const struct ifaddrs *ptr) noexcept
538{
540}
541
549inline bool operator==(const in6_addr& a, const in6_addr& b) noexcept
550{
551 return 0 == std::memcmp(&a, &b, sizeof(in6_addr));
552}
553
561inline bool operator!=(const in6_addr& a, const in6_addr& b) noexcept
562{
563 return !(a == b);
564}
565
573inline bool operator<(const in6_addr& a, const in6_addr& b) noexcept
574{
575 return std::memcmp(&a, &b, sizeof(in6_addr)) < 0;
576}
An RAII handle type which owns an opaque resource of a specified type, and calls a designated functio...
Definition: handle.hpp:40
T memcmp(T... args)
Definition: assert.hpp:13
void bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen)
Binds a socket to an address.
Definition: sockets.cpp:113
std::size_t recv(int sockfd, void *buf, std::size_t len, int flags=0)
Receives a message from a socket.
Definition: sockets.cpp:190
w::handle< int, -1, ::close > fd
An RAII util::handle type for POSIX file descriptors.
Definition: posix.hpp:25
w::handle< struct ifaddrs *, nullptr, ::freeifaddrs > getifaddrs()
Gets a pointer to the head of a linked list of the system's network interfaces.
Definition: sockets.cpp:129
int setsockopt(int sockfd, int level, int optname, const void *optval=nullptr, socklen_t optlen=0)
Sets an option on a socket.
Definition: sockets.cpp:246
void listen(int sockfd, int backlog)
Puts a socket in a listening state.
Definition: sockets.cpp:182
std::size_t sendmsg(int sockfd, const struct msghdr *msg, int flags=0)
Sends a message on a socket.
Definition: sockets.cpp:227
unsigned if_nametoindex(const char *ifname)
Returns the index of the specified network interface.
Definition: sockets.cpp:149
std::size_t send(int sockfd, const void *buf, std::size_t len, int flags=0)
Sends a message on a socket.
Definition: sockets.cpp:218
w::fd socket(int domain, int type, int protocol=0)
Creates a socket.
Definition: sockets.cpp:263
std::size_t recvfrom(int sockfd, void *buf, std::size_t len, int flags, struct sockaddr *src_addr=nullptr, socklen_t *addrlen=nullptr)
Receives a message from a socket.
Definition: sockets.cpp:208
void * inet_pton(int af, const char *src, void *dst)
Converts an IPv4 or IPv6 address from a string to a binary value.
Definition: sockets.cpp:167
void shutdown(int sockfd, int how)
Shuts down part of a full-duplex connection.
Definition: sockets.cpp:255
std::size_t recvmsg(int sockfd, struct msghdr *msg, int flags=0)
Receives a message from a socket.
Definition: sockets.cpp:199
char * inet_ntop(int af, const void *src, char *dst, socklen_t size)
Converts an IPv4 or IPv6 address to a string.
Definition: sockets.cpp:157
int getsockopt(int sockfd, int level, int optname, void *optval=nullptr, socklen_t *optlen=nullptr)
Gets an option on a socket.
Definition: sockets.cpp:140
void connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen)
Connects a socket.
Definition: sockets.cpp:121
std::size_t sendto(int sockfd, const void *buf, std::size_t len, int flags, const struct sockaddr *dest_addr, socklen_t addrlen)
Sends a message on a socket.
Definition: sockets.cpp:236
w::fd accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen)
Accepts a connection on a socket.
Definition: sockets.cpp:105
auto end(const struct ifaddrs *ptr) noexcept
Returns an input iterator pointing to the end of a struct ifaddrs array.
Definition: sockets.hpp:537
auto begin(const struct ifaddrs *ptr) noexcept
Returns an input iterator pointing to the struct ifaddrs entry ptr.
Definition: sockets.hpp:526
bool operator==(const in6_addr &a, const in6_addr &b) noexcept
Compares two IPv6 addresses.
Definition: sockets.hpp:549
bool operator!=(const in6_addr &a, const in6_addr &b) noexcept
Compares two IPv6 addresses.
Definition: sockets.hpp:561
bool operator<(const in6_addr &a, const in6_addr &b) noexcept
Compares two IPv6 addresses.
Definition: sockets.hpp:573
A forward iterator for linked lists.
Definition: iterators.hpp:22
Wraps struct sockaddr_in, adding constructors for convenient initialization.
Definition: sockets.hpp:30
Wraps struct sockaddr_in6, adding constructors for convenient initialization.
Definition: sockets.hpp:62
Wraps struct sockaddr_in, adding constructors for convenient initialization.
Definition: sockets.hpp:136