Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
  • ReadMailReallyFast/code
1 result
Show changes
Commits on Source (4)
...@@ -11,8 +11,12 @@ ...@@ -11,8 +11,12 @@
namespace rmrf::net { namespace rmrf::net {
connection_client::~connection_client() { connection_client::~connection_client() {
if(this->server_active) async.stop();
if (this->server_active) {
io.stop(); io.stop();
}
if (destructor_cb) { if (destructor_cb) {
destructor_cb(exit_status_t::NO_ERROR); destructor_cb(exit_status_t::NO_ERROR);
} }
...@@ -59,15 +63,22 @@ namespace rmrf::net { ...@@ -59,15 +63,22 @@ namespace rmrf::net {
this->server_active = false; this->server_active = false;
io.stop(); io.stop();
} }
void connection_client::set_incomming_data_callback(const incomming_data_cb& cb) { void connection_client::set_incomming_data_callback(const incomming_data_cb &cb) {
this->in_data_cb = cb; this->in_data_cb = cb;
set_new_flags(); this->async.send();
} }
void connection_client::set_rate_limit(unsigned int new_limit) { void connection_client::set_rate_limit(unsigned int new_limit) {
this->rate_limit = new_limit; this->rate_limit = new_limit;
// TODO start timer if new limit is not no_rate_limit // TODO start timer if new limit is not no_rate_limit
// TODO stop timer if timer exists and new limit is no_rate_limit // TODO stop timer if timer exists and new limit is no_rate_limit
} }
void connection_client::cb_async(::ev::async &w, int events) {
MARK_UNUSED(w);
MARK_UNUSED(events);
set_new_flags();
}
} }
...@@ -49,6 +49,7 @@ protected: ...@@ -49,6 +49,7 @@ protected:
auto_fd net_socket; auto_fd net_socket;
private: private:
::ev::io io; ::ev::io io;
::ev::async async;
ioqueue<iorecord> write_queue; ioqueue<iorecord> write_queue;
const destructor_cb_type destructor_cb; const destructor_cb_type destructor_cb;
bool server_active = false; bool server_active = false;
...@@ -73,10 +74,12 @@ public: ...@@ -73,10 +74,12 @@ public:
* @param peer_address_ The remote address the client is connected to * @param peer_address_ The remote address the client is connected to
*/ */
connection_client(auto_fd&& socket_fd, const socketaddr& peer_address_, const destructor_cb_type destructor_cb_) : connection_client(auto_fd&& socket_fd, const socketaddr& peer_address_, const destructor_cb_type destructor_cb_) :
net_socket(std::forward<auto_fd>(socket_fd)), io{}, write_queue{}, destructor_cb{destructor_cb_}, net_socket(std::forward<auto_fd>(socket_fd)), io{}, async{}, write_queue{}, destructor_cb{destructor_cb_},
in_data_cb{}, own_address{}, peer_address{peer_address_} in_data_cb{}, own_address{}, peer_address{peer_address_}
{ {
if(this->net_socket) { if(this->net_socket) {
async.set<connection_client, &connection_client::cb_async>(this);
async.start();
io.set<connection_client, &connection_client::cb_ev>(this); io.set<connection_client, &connection_client::cb_ev>(this);
io.start(this->net_socket.get(), 0); io.start(this->net_socket.get(), 0);
this->server_active = true; this->server_active = true;
...@@ -93,7 +96,7 @@ public: ...@@ -93,7 +96,7 @@ public:
inline virtual void write_data(const iorecord& data) { inline virtual void write_data(const iorecord& data) {
// Create NICBuffer from data // Create NICBuffer from data
this->write_queue.push_back(data); this->write_queue.push_back(data);
this->io.set(::ev::READ | ::ev::WRITE); this->async.send();
} }
/** /**
...@@ -106,9 +109,9 @@ public: ...@@ -106,9 +109,9 @@ public:
*/ */
inline void write_data(iorecord&& data) { inline void write_data(iorecord&& data) {
this->write_queue.push_back(std::forward<iorecord>(data)); this->write_queue.push_back(std::forward<iorecord>(data));
this->io.set(::ev::READ | ::ev::WRITE); this->async.send();
} }
/** /**
* This method sends data over the socket. Keep in mind that this method only enqueues the * This method sends data over the socket. Keep in mind that this method only enqueues the
* data and requests it's transmission but does not send the data directly. While this ensures * data and requests it's transmission but does not send the data directly. While this ensures
...@@ -188,6 +191,8 @@ private: ...@@ -188,6 +191,8 @@ private:
* @param events The event flag container * @param events The event flag container
*/ */
void cb_ev(::ev::io& w, int events); void cb_ev(::ev::io& w, int events);
void cb_async(::ev::async& w, int events);
inline void set_new_flags() { inline void set_new_flags() {
auto new_flags = 0; auto new_flags = 0;
...@@ -202,4 +207,3 @@ private: ...@@ -202,4 +207,3 @@ private:
}; };
} }
...@@ -19,8 +19,10 @@ namespace rmrf::net { ...@@ -19,8 +19,10 @@ namespace rmrf::net {
std::string format_network_error(int error) { std::string format_network_error(int error) {
switch (error) { switch (error) {
#ifdef __linux__
case EAI_ADDRFAMILY: case EAI_ADDRFAMILY:
return "There was no compatible address for the requested families. (EAI_ADDRFAMILY)"; return "There was no compatible address for the requested families. (EAI_ADDRFAMILY)";
#endif
case EAI_AGAIN: case EAI_AGAIN:
return "The consulted DNS server reported a temporary lookup failure. Try again later. (EAI_AGAIN)"; return "The consulted DNS server reported a temporary lookup failure. Try again later. (EAI_AGAIN)";
case EAI_BADFLAGS: case EAI_BADFLAGS:
...@@ -31,8 +33,10 @@ namespace rmrf::net { ...@@ -31,8 +33,10 @@ namespace rmrf::net {
return "The required protocol family is not supported by this host. (EAI_FAMILY)"; return "The required protocol family is not supported by this host. (EAI_FAMILY)";
case EAI_MEMORY: case EAI_MEMORY:
return "Out of Memory while performing DNS lookup. (EAI_MEMORY)"; return "Out of Memory while performing DNS lookup. (EAI_MEMORY)";
#ifdef __linux__
case EAI_NODATA: case EAI_NODATA:
return "The requested DNS entry does not contain an A or AAAA entry. (EAI_NODATA)"; return "The requested DNS entry does not contain an A or AAAA entry. (EAI_NODATA)";
#endif
case EAI_NONAME: case EAI_NONAME:
return "There was no matching nodename, service tuple. (EAI_NONAME)"; return "There was no matching nodename, service tuple. (EAI_NONAME)";
case EAI_SERVICE: case EAI_SERVICE:
...@@ -42,6 +46,7 @@ namespace rmrf::net { ...@@ -42,6 +46,7 @@ namespace rmrf::net {
default: default:
return std::to_string(error); return std::to_string(error);
} }
// TODO implement EAI_OVERFLOW, EAI_PROTOCOL, EAI_BADHINTS, EAI_SYSTEM (*BSD specific)
} }
bool decode_address(std::list<socketaddr> &l, addrinfo* looked_up_addrs, const int port) { bool decode_address(std::list<socketaddr> &l, addrinfo* looked_up_addrs, const int port) {
......
...@@ -46,11 +46,13 @@ public: ...@@ -46,11 +46,13 @@ public:
/** /**
* This method copies the content of data on the write queue and schedules its transmission to destination. * This method copies the content of data on the write queue and schedules its transmission to destination.
* It needs to know the packet size of the udp packet, provided by the template.
* @brief Send a udp packet * @brief Send a udp packet
* @param destination The destination to send it to * @param destination The destination to send it to
* @param data The data to be send * @param data The data to be send
*/ */
void send_packet(const socketaddr& destination, const udp_packet<>& data) { template<size_t packet_size>
inline void send_packet(const socketaddr& destination, const udp_packet<packet_size>& data) {
this->write_data(std::forward<iorecord>(iorecord{data.raw(), data.size(), destination})); this->write_data(std::forward<iorecord>(iorecord{data.raw(), data.size(), destination}));
} }
...@@ -75,14 +77,19 @@ public: ...@@ -75,14 +77,19 @@ public:
* device handling the send packet shall report if the path was viable or not. This * device handling the send packet shall report if the path was viable or not. This
* is useful for debugging but may negatively impact performance. * is useful for debugging but may negatively impact performance.
* @brief Enable or disable UDP confirm mode * @brief Enable or disable UDP confirm mode
* @note This is only enabled if MSG_CONFIRM is enabled on your platform.
* @param enabled If set to true the UDP confirm mode will be activated. * @param enabled If set to true the UDP confirm mode will be activated.
*/ */
void enable_confirm_mode(bool enabled) { void enable_confirm_mode(bool enabled) {
#ifdef MSG_CONFIRM
if (enabled) { if (enabled) {
this->send_flags |= MSG_CONFIRM; this->send_flags |= MSG_CONFIRM;
} else { } else {
this->send_flags &= ~MSG_CONFIRM; this->send_flags &= ~MSG_CONFIRM;
} }
#else
MARK_UNUSED(enabled);
#endif
}; };
protected: protected:
......
...@@ -71,19 +71,19 @@ public: ...@@ -71,19 +71,19 @@ public:
return this->arr.data(); return this->arr.data();
} }
constexpr std::array<uint8_t, pkg_size>::iterator begin() noexcept { constexpr typename std::array<uint8_t, pkg_size>::iterator begin() noexcept {
return this->arr.begin(); return this->arr.begin();
} }
constexpr std::array<uint8_t, pkg_size>::iterator end() noexcept { constexpr typename std::array<uint8_t, pkg_size>::iterator end() noexcept {
return this->arr.end(); return this->arr.end();
} }
constexpr std::array<uint8_t, pkg_size>::const_iterator cbegin() const noexcept { constexpr typename std::array<uint8_t, pkg_size>::const_iterator cbegin() const noexcept {
return this->arr.cbegin(); return this->arr.cbegin();
} }
constexpr std::array<uint8_t, pkg_size>::const_iterator cend() const noexcept { constexpr typename std::array<uint8_t, pkg_size>::const_iterator cend() const noexcept {
return this->arr.cend(); return this->arr.cend();
} }
......