My Project: /home/noptrix/ba/blackarch/packages/opendht-c/src/opendht/include/opendht/network_utils.h Source File

My Project 3.7.7 C++ Distributed Hash Table

Loading...
Searching...
No Matches
network_utils.h
1// Copyright (c) 2014-2026 Savoir-faire Linux Inc.
2// SPDX-License-Identifier: MIT
3#pragma once
4
5#include "def.h"
6
7#include "sockaddr.h"
8#include "utils.h"
9#include "logger.h"
10
11#ifdef _WIN32
12#include <ws2tcpip.h>
13#include <winsock2.h>
14#else
15#include <sys/socket.h>
16#include <netinet/in.h>
17#include <unistd.h>
18#endif
19
20#include <functional>
21#include <thread>
22#include <atomic>
23#include <mutex>
24#include <list>
25
26namespace dht {
27namespace net {
28
29static const constexpr in_port_t DHT_DEFAULT_PORT = 4222;
30static const constexpr size_t RX_QUEUE_MAX_SIZE = 1024 * 64;
31static const constexpr std::chrono::milliseconds RX_QUEUE_MAX_DELAY(650);
32
33int bindSocket(const SockAddr& addr, SockAddr& bound);
34
35bool setNonblocking(int fd, bool nonblocking = true);
36
37#ifdef _WIN32
38void udpPipe(int fds[2]);
39#endif
40 struct ReceivedPacket
41{
42 Blob data;
43 SockAddr from;
44 time_point received;
45};
46using PacketList = std::list<ReceivedPacket>;
47
48 class OPENDHT_PUBLIC DatagramSocket
49{
50public:
54 using OnReceive = std::function<PacketList(PacketList&& packets)>;
55 virtual ~DatagramSocket() {};
56
57 virtual int sendTo(const SockAddr& dest, const uint8_t* data, size_t size, bool replied) = 0;
58
59 inline void setOnReceive(OnReceive&& cb)
60 {
61 std::lock_guard lk(lock);
62 rx_callback = std::move(cb);
63 }
64
65 virtual bool hasIPv4() const = 0;
66 virtual bool hasIPv6() const = 0;
67
68 SockAddr getBound(sa_family_t family = AF_UNSPEC) const
69 {
70 std::lock_guard lk(lock);
71 return getBoundRef(family);
72 }
73 in_port_t getPort(sa_family_t family = AF_UNSPEC) const
74 {
75 std::lock_guard lk(lock);
76 return getBoundRef(family).getPort();
77 }
78
79 virtual const SockAddr& getBoundRef(sa_family_t family = AF_UNSPEC) const = 0;
80
82 virtual std::vector<SockAddr> resolve(const std::string& host, const std::string& service = {})
83 {
84 return SockAddr::resolve(host, service);
85 }
86
87 virtual void stop() = 0;
88
89protected:
90 PacketList getNewPacket()
91 {
92 PacketList pkts;
93 if (toRecycle_.empty()) {
94 pkts.emplace_back();
95 } else {
96 auto begIt = toRecycle_.begin();
97 auto begItNext = std::next(begIt);
98 pkts.splice(pkts.end(), toRecycle_, begIt, begItNext);
99 }
100 return pkts;
101 }
102
103 inline void onReceived(PacketList&& packets)
104 {
105 std::lock_guard lk(lock);
106 if (rx_callback) {
107 auto r = rx_callback(std::move(packets));
108 if (not r.empty() and toRecycle_.size() < RX_QUEUE_MAX_SIZE)
109 toRecycle_.splice(toRecycle_.end(), std::move(r));
110 }
111 }
112
113protected:
114 mutable std::mutex lock;
115
116private:
117 OnReceive rx_callback;
118 PacketList toRecycle_;
119};
120
121 class OPENDHT_PUBLIC UdpSocket : public DatagramSocket
122{
123public:
124 UdpSocket(in_port_t port, const std::shared_ptr<Logger>& l = {});
125 UdpSocket(const SockAddr& bind4, const SockAddr& bind6, const std::shared_ptr<Logger>& l = {});
126 ~UdpSocket();
127
128 int sendTo(const SockAddr& dest, const uint8_t* data, size_t size, bool replied) override;
129
130 const SockAddr& getBoundRef(sa_family_t family = AF_UNSPEC) const override
131 {
132 return (family == AF_INET6) ? bound6 : bound4;
133 }
134
135 bool hasIPv4() const override
136 {
137 std::lock_guard lk(lock);
138 return s4 != -1;
139 }
140 bool hasIPv6() const override
141 {
142 std::lock_guard lk(lock);
143 return s6 != -1;
144 }
145
146 void stop() override;
147
148private:
149 std::shared_ptr<Logger> logger;
150 int s4 {-1};
151 int s6 {-1};
152 int stopfd {-1};
153 SockAddr bound4, bound6;
154 std::thread rcv_thread {};
155 std::atomic_bool running {false};
156
157 void openSockets(const SockAddr& bind4, const SockAddr& bind6);
158};
159
160} // namespace net
161} // namespace dht
dht::SockAddr
Definition sockaddr.h:47
dht::net::DatagramSocket
Definition network_utils.h:49
dht::net::DatagramSocket::resolve
virtual std::vector< SockAddr > resolve(const std::string &host, const std::string &service={})
Definition network_utils.h:82
dht::net::DatagramSocket::OnReceive
std::function< PacketList(PacketList &&packets)> OnReceive
Definition network_utils.h:54
dht
Definition callbacks.h:17
dht::Blob
std::vector< uint8_t > Blob
Definition utils.h:158
dht::net::ReceivedPacket
Definition network_utils.h:41