summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/CMakeLists.txt1
-rw-r--r--src/network.cpp33
-rw-r--r--src/network.h3
-rw-r--r--src/network/protocol.cpp69
-rw-r--r--src/network/protocol.h33
5 files changed, 116 insertions, 23 deletions
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 6676a9c..478fc50 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -11,6 +11,7 @@ add_library(erebos
merge.cpp
message.cpp
network.cpp
+ network/protocol.cpp
pairing.cpp
pubkey.cpp
service.cpp
diff --git a/src/network.cpp b/src/network.cpp
index cd13bc4..b5dfd68 100644
--- a/src/network.cpp
+++ b/src/network.cpp
@@ -1,6 +1,7 @@
#include "network.h"
#include "identity.h"
+#include "network/protocol.h"
#include "service.h"
#include <algorithm>
@@ -313,10 +314,12 @@ Server::Priv::Priv(const Head<LocalState> & local, const Identity & self):
}
}
- sock = socket(AF_INET6, SOCK_DGRAM, 0);
+ int sock = socket(AF_INET6, SOCK_DGRAM, 0);
if (sock < 0)
throw std::system_error(errno, std::generic_category());
+ protocol = NetworkProtocol(sock);
+
int disable = 0;
// Should be disabled by default, but try to make sure. On platforms
// where the calls fails, IPv4 might not work.
@@ -349,15 +352,11 @@ Server::Priv::~Priv()
finish = true;
}
- if (sock >= 0)
- shutdown(sock, SHUT_RDWR);
+ protocol.shutdown();
announceCondvar.notify_all();
threadListen.join();
threadAnnounce.join();
-
- if (sock >= 0)
- close(sock);
}
shared_ptr<Server::Priv> Server::Priv::getptr()
@@ -372,18 +371,11 @@ void Server::Priv::doListen()
unique_lock lock(dataMutex);
for (; !finish; lock.lock()) {
- sockaddr_in6 paddr;
-
lock.unlock();
- socklen_t addrlen = sizeof(paddr);
- buf.resize(4096);
- ssize_t ret = recvfrom(sock, buf.data(), buf.size(), 0,
- (sockaddr *) &paddr, &addrlen);
- if (ret < 0)
- throw std::system_error(errno, std::generic_category());
- if (ret == 0)
+
+ sockaddr_in6 paddr;
+ if (not protocol.recvfrom(buf, paddr))
break;
- buf.resize(ret);
if (isSelfAddress(paddr))
continue;
@@ -456,7 +448,7 @@ void Server::Priv::doAnnounce()
sin.sin_family = AF_INET;
sin.sin_addr = in;
sin.sin_port = htons(discoveryPort);
- sendto(sock, bytes.data(), bytes.size(), 0, (sockaddr *) &sin, sizeof(sin));
+ protocol.sendto(bytes, sin);
}
lastAnnounce += announceInterval * ((now - lastAnnounce) / announceInterval);
@@ -703,8 +695,7 @@ void Server::Peer::send(const TransportHeader & header, const vector<Object> & o
out = std::move(data);
if (!out.empty())
- sendto(server.sock, out.data(), out.size(), 0,
- (sockaddr *) &addr, sizeof(addr));
+ server.protocol.sendto(out, addr);
}
void Server::Peer::updateIdentity(ReplyBuilder &)
@@ -840,9 +831,7 @@ void Server::Peer::trySendOutQueue()
for (const auto & data : secureOutQueue) {
auto out = std::get<unique_ptr<Channel>>(channel)->encrypt(data);
-
- sendto(server.sock, out.data(), out.size(), 0,
- (sockaddr *) &addr, sizeof(addr));
+ server.protocol.sendto(out, addr);
}
secureOutQueue.clear();
diff --git a/src/network.h b/src/network.h
index 1c1bb57..c242ac5 100644
--- a/src/network.h
+++ b/src/network.h
@@ -3,6 +3,7 @@
#include <erebos/network.h>
#include "channel.h"
+#include "network/protocol.h"
#include <condition_variable>
#include <mutex>
@@ -181,7 +182,7 @@ struct Server::Priv
vector<struct TransportHeader> outgoing;
vector<weak_ptr<WaitingRef>> waiting;
- int sock;
+ NetworkProtocol protocol;
vector<in_addr> localAddresses;
vector<in_addr> bcastAddresses;
diff --git a/src/network/protocol.cpp b/src/network/protocol.cpp
new file mode 100644
index 0000000..63cfde5
--- /dev/null
+++ b/src/network/protocol.cpp
@@ -0,0 +1,69 @@
+#include "protocol.h"
+
+#include <sys/socket.h>
+#include <unistd.h>
+
+#include <system_error>
+
+namespace erebos {
+
+NetworkProtocol::NetworkProtocol():
+ sock(-1)
+{}
+
+NetworkProtocol::NetworkProtocol(int s):
+ sock(s)
+{}
+
+NetworkProtocol::NetworkProtocol(NetworkProtocol && other):
+ sock(other.sock)
+{
+ other.sock = -1;
+}
+
+NetworkProtocol & NetworkProtocol::operator=(NetworkProtocol && other)
+{
+ sock = other.sock;
+ other.sock = -1;
+ return *this;
+}
+
+NetworkProtocol::~NetworkProtocol()
+{
+ if (sock >= 0)
+ close(sock);
+}
+
+bool NetworkProtocol::recvfrom(vector<uint8_t> & buffer, sockaddr_in6 & addr)
+{
+ socklen_t addrlen = sizeof(addr);
+ buffer.resize(4096);
+ ssize_t ret = ::recvfrom(sock, buffer.data(), buffer.size(), 0,
+ (sockaddr *) &addr, &addrlen);
+ if (ret < 0)
+ throw std::system_error(errno, std::generic_category());
+ if (ret == 0)
+ return false;
+
+ buffer.resize(ret);
+ return true;
+}
+
+void NetworkProtocol::sendto(const vector<uint8_t> & buffer, sockaddr_in addr)
+{
+ ::sendto(sock, buffer.data(), buffer.size(), 0,
+ (sockaddr *) &addr, sizeof(addr));
+}
+
+void NetworkProtocol::sendto(const vector<uint8_t> & buffer, sockaddr_in6 addr)
+{
+ ::sendto(sock, buffer.data(), buffer.size(), 0,
+ (sockaddr *) &addr, sizeof(addr));
+}
+
+void NetworkProtocol::shutdown()
+{
+ ::shutdown(sock, SHUT_RDWR);
+}
+
+}
diff --git a/src/network/protocol.h b/src/network/protocol.h
new file mode 100644
index 0000000..6a22f3b
--- /dev/null
+++ b/src/network/protocol.h
@@ -0,0 +1,33 @@
+#pragma once
+
+#include <netinet/in.h>
+
+#include <cstdint>
+#include <vector>
+
+namespace erebos {
+
+using std::vector;
+
+class NetworkProtocol
+{
+public:
+ NetworkProtocol();
+ explicit NetworkProtocol(int sock);
+ NetworkProtocol(const NetworkProtocol &) = delete;
+ NetworkProtocol(NetworkProtocol &&);
+ NetworkProtocol & operator=(const NetworkProtocol &) = delete;
+ NetworkProtocol & operator=(NetworkProtocol &&);
+ ~NetworkProtocol();
+
+ bool recvfrom(vector<uint8_t> & buffer, sockaddr_in6 & addr);
+ void sendto(const vector<uint8_t> & buffer, sockaddr_in addr);
+ void sendto(const vector<uint8_t> & buffer, sockaddr_in6 addr);
+
+ void shutdown();
+
+private:
+ int sock;
+};
+
+}