src/Socket.cpp
author František Kučera <franta-hg@frantovo.cz>
Sun, 21 Aug 2022 00:16:50 +0200
branchv_0
changeset 3 2b57c8683ffe
permissions -rw-r--r--
synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
3
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
     1
/**
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
     2
 * Relational pipes
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
     3
 * Copyright © 2022 František Kučera (Frantovo.cz, GlobalCode.info)
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
     4
 *
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
     5
 * This program is free software: you can redistribute it and/or modify
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
     6
 * it under the terms of the GNU General Public License as published by
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
     7
 * the Free Software Foundation, version 3 of the License.
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
     8
 *
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
     9
 * This program is distributed in the hope that it will be useful,
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
    10
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
    11
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
    12
 * GNU General Public License for more details.
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
    13
 *
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
    14
 * You should have received a copy of the GNU General Public License
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
    15
 * along with this program. If not, see <http://www.gnu.org/licenses/>.
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
    16
 */
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
    17
#include <string>
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
    18
#include <cstring>
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
    19
#include <unistd.h>
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
    20
#include <stdexcept>
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
    21
#include <arpa/inet.h>
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
    22
#include <sys/types.h>
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
    23
#include <sys/socket.h>
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
    24
#include <sys/un.h>
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
    25
#include <netinet/in.h>
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
    26
#include <vector>
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
    27
#include <memory>
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
    28
#include <regex>
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
    29
#include <iostream>
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
    30
#include <netdb.h>
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
    31
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
    32
#include "Socket.h"
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
    33
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
    34
namespace relpipe {
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
    35
namespace in {
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
    36
namespace socket {
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
    37
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
    38
using namespace relpipe::in::socket::options;
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
    39
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
    40
static const std::string findOption(SocketOptions options, std::string name, bool required = false, const std::string defaultValue = "") {
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
    41
	for (auto o : options) if (o.name == name) return o.value;
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
    42
	if (required) throw std::invalid_argument("Option " + name + " is required but was not found");
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
    43
	else return defaultValue;
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
    44
}
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
    45
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
    46
class FD {
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
    47
private:
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
    48
	int fd;
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
    49
public:
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
    50
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
    51
	FD(int fd) : fd(fd) {
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
    52
	};
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
    53
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
    54
	virtual ~FD() {
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
    55
		close(fd);
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
    56
	}
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
    57
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
    58
	int getFD() {
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
    59
		return fd;
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
    60
	}
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
    61
};
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
    62
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
    63
static void check(int result, std::string message) {
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
    64
	if (result == 0); // OK
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
    65
	else throw std::logic_error("Got error result: " + message + ": " + strerror(errno) + " (result=" + std::to_string(result) + ", errno=" + std::to_string(errno) + ")");
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
    66
}
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
    67
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
    68
class AddressInfos {
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
    69
private:
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
    70
	std::shared_ptr<addrinfo> addrInfo;
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
    71
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
    72
	AddressInfos(addrinfo* addrInfo) : addrInfo(std::shared_ptr<addrinfo>(addrInfo, freeaddrinfo)) {
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
    73
	}
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
    74
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
    75
public:
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
    76
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
    77
	virtual ~AddressInfos() {
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
    78
	}
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
    79
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
    80
	class AddressInfo {
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
    81
	private:
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
    82
		std::shared_ptr<addrinfo> parent; // to avoid premature deletion of the whole structure
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
    83
	public:
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
    84
		const addrinfo * const ai;
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
    85
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
    86
		AddressInfo(const addrinfo * const ai, std::shared_ptr<addrinfo> parent) : ai(ai), parent(parent) {
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
    87
		}
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
    88
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
    89
		const std::string toString() const {
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
    90
			char buffer[INET6_ADDRSTRLEN] = {0};
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
    91
			if (ai->ai_family == AF_INET) return inet_ntop(ai->ai_family, &((sockaddr_in const *) ai->ai_addr)->sin_addr, buffer, sizeof (buffer)); // TODO: check 0 result
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
    92
			else if (ai->ai_family == AF_INET6) return inet_ntop(ai->ai_family, &((sockaddr_in6 const *) ai->ai_addr)->sin6_addr, buffer, sizeof (buffer)); // TODO: check 0 result
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
    93
			else return "unknown address family: " + std::to_string(ai->ai_family);
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
    94
		}
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
    95
	};
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
    96
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
    97
	static AddressInfos getAddressInfos(const std::string& host, const std::string& port, int socketType = SOCK_STREAM, int protocol = IPPROTO_TCP) {
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
    98
		struct addrinfo query;
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
    99
		memset(&query, sizeof (query), 0);
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   100
		query.ai_family = AF_UNSPEC;
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   101
		query.ai_socktype = socketType;
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   102
		query.ai_protocol = protocol;
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   103
		query.ai_flags = AI_ALL;
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   104
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   105
		struct addrinfo* addrInfo;
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   106
		check(getaddrinfo(host.c_str(), port.c_str(), &query, &addrInfo), "getaddrinfo");
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   107
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   108
		return AddressInfos(addrInfo);
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   109
	}
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   110
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   111
	const std::size_t size() const {
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   112
		std::size_t size = 0;
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   113
		for (addrinfo* ai = addrInfo.get(); ai; ai = ai->ai_next) size++;
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   114
		return size;
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   115
	}
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   116
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   117
	const AddressInfo operator[](std::size_t index) const {
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   118
		for (addrinfo* ai = addrInfo.get(); ai; index--) {
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   119
			if (index == 0) return AddressInfo(ai, addrInfo);
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   120
			else ai = ai->ai_next;
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   121
		}
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   122
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   123
		throw std::out_of_range("invalid index for AddressInfo: " + std::to_string(index));
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   124
	}
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   125
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   126
};
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   127
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   128
template<class SocketClass, class... MoreArgs> static std::shared_ptr<SocketClass> openClientSocket(const SocketOptions& options, int socketType, int protocol, MoreArgs... moreArgs) {
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   129
	AddressInfos remoteAddresses = AddressInfos::getAddressInfos(
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   130
			findOption(options, OPTION_HOST, true),
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   131
			findOption(options, OPTION_PORT, true),
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   132
			socketType,
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   133
			protocol);
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   134
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   135
	return std::shared_ptr<SocketClass>(new SocketClass(remoteAddresses[0], moreArgs...));
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   136
}
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   137
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   138
/**
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   139
 * abstract class for sockets that use sendmsg() / recvmsg()
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   140
 */
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   141
class MSGSocket : public Socket {
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   142
protected:
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   143
	FD socket;
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   144
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   145
	void sendmsg(const std::string& message) {
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   146
		iovec iov[1];
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   147
		msghdr msg = {};
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   148
		msg.msg_iov = iov;
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   149
		msg.msg_iov[0].iov_base = (void*) message.c_str();
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   150
		msg.msg_iov[0].iov_len = message.size();
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   151
		msg.msg_iovlen = sizeof (iov) / sizeof (iov[0]);
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   152
		ssize_t written = ::sendmsg(socket.getFD(), &msg, 0);
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   153
		if (written != message.size()) throw std::logic_error("writing to the socket failed");
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   154
	}
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   155
public:
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   156
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   157
	MSGSocket(int socket) : socket(socket) {
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   158
	}
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   159
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   160
	void send(const OutgoingMessage& message) {
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   161
		sendmsg(message.data);
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   162
	}
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   163
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   164
};
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   165
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   166
class UDPClientSocket : public Socket {
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   167
private:
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   168
	AddressInfos::AddressInfo remoteAddress;
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   169
	useconds_t delay = 0;
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   170
	FD socket;
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   171
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   172
public:
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   173
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   174
	UDPClientSocket(AddressInfos::AddressInfo remoteAddress) : remoteAddress(remoteAddress), socket(::socket(remoteAddress.ai->ai_family, remoteAddress.ai->ai_socktype, remoteAddress.ai->ai_protocol)) {
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   175
	}
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   176
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   177
	static std::shared_ptr<Socket> open(const SocketOptions& options) {
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   178
		auto socket = openClientSocket<UDPClientSocket>(options, SOCK_DGRAM, IPPROTO_UDP);
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   179
		socket->delay = std::stol(findOption(options, OPTION_DELAY, false, "0")); // TODO: Move to SocketHandler? Or delete.
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   180
		return socket;
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   181
	}
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   182
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   183
	void send(const OutgoingMessage& message) override {
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   184
		auto ai = remoteAddress.ai;
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   185
		sendto(socket.getFD(), message.data.c_str(), message.data.size(), 0, ai->ai_addr, ai->ai_addrlen);
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   186
		if (delay) usleep(delay);
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   187
	}
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   188
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   189
	const IncomingMessage receive() override {
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   190
		// TODO: UDP receive()
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   191
		return IncomingMessage("TODO: receive() a message");
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   192
	}
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   193
};
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   194
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   195
class UDPServerSocket : public Socket {
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   196
private:
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   197
	AddressInfos::AddressInfo localAddress;
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   198
	sockaddr_in6 remoteAddressForSending = {};
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   199
	useconds_t delay = 0;
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   200
	FD socket;
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   201
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   202
public:
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   203
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   204
	UDPServerSocket(AddressInfos::AddressInfo remoteAddress) : localAddress(remoteAddress), socket(::socket(remoteAddress.ai->ai_family, remoteAddress.ai->ai_socktype, remoteAddress.ai->ai_protocol)) {
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   205
	}
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   206
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   207
	static std::shared_ptr<Socket> open(const SocketOptions& options) {
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   208
		auto socket = openClientSocket<UDPServerSocket>(options, SOCK_DGRAM, IPPROTO_UDP);
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   209
		auto ai = socket->localAddress.ai;
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   210
		int reuseAddr = true;
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   211
		check(::setsockopt(socket->socket.getFD(), SOL_SOCKET, SO_REUSEADDR, &reuseAddr, sizeof (reuseAddr)), "setsockopt SO_REUSEADDR");
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   212
		check(::bind(socket->socket.getFD(), ai->ai_addr, ai->ai_addrlen), "bind");
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   213
		return socket;
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   214
	}
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   215
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   216
	void send(const OutgoingMessage& message) override {
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   217
		// receive a message first to get a remote address:
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   218
		char buffer[8192];
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   219
		memset((char *) &remoteAddressForSending, 0, sizeof (remoteAddressForSending));
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   220
		socklen_t remoteAddressSize = sizeof (remoteAddressForSending);
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   221
		ssize_t msgSize = recvfrom(socket.getFD(), buffer, sizeof (buffer), 0, (sockaddr*) & remoteAddressForSending, &remoteAddressSize);
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   222
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   223
		// respond with our messsage:
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   224
		sendto(socket.getFD(), message.data.c_str(), message.data.size(), 0, (sockaddr*) & remoteAddressForSending, remoteAddressSize);
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   225
	}
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   226
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   227
	const IncomingMessage receive() override {
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   228
		char buffer[8192];
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   229
		sockaddr_in6 remoteAddress;
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   230
		memset((char *) &remoteAddress, 0, sizeof (remoteAddress));
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   231
		socklen_t remoteAddressSize = sizeof (remoteAddress);
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   232
		ssize_t msgSize = recvfrom(socket.getFD(), buffer, sizeof (buffer), 0, (sockaddr*) & remoteAddress, &remoteAddressSize);
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   233
		check(msgSize < 0, "recvfrom");
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   234
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   235
		IncomingMessage message(std::string(buffer, std::min(sizeof (buffer), (size_t) msgSize)));
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   236
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   237
		// TODO: move to a common method
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   238
		char hostBuffer[INET6_ADDRSTRLEN] = {0};
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   239
		if (remoteAddress.sin6_family == AF_INET) {
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   240
			sockaddr_in* remoteAddress4 = (sockaddr_in*) & remoteAddress;
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   241
			message.remoteHost = inet_ntop(remoteAddress4->sin_family, &remoteAddress4->sin_addr, hostBuffer, sizeof (hostBuffer)); // TODO: check 0 result
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   242
			message.remotePort = remoteAddress4->sin_port;
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   243
		} else if (remoteAddress.sin6_family == AF_INET6) {
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   244
			message.remoteHost = inet_ntop(remoteAddress.sin6_family, &remoteAddress.sin6_addr, hostBuffer, sizeof (hostBuffer)); // TODO: check 0 result
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   245
			message.remotePort = remoteAddress.sin6_port;
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   246
		}
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   247
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   248
		return message;
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   249
	}
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   250
};
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   251
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   252
class TCPClientSocket : public Socket {
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   253
private:
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   254
	AddressInfos::AddressInfo remoteAddress;
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   255
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   256
public:
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   257
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   258
	TCPClientSocket(AddressInfos::AddressInfo remoteAddress) : remoteAddress(remoteAddress) {
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   259
	}
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   260
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   261
	static std::shared_ptr<Socket> open(const SocketOptions& options) {
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   262
		return openClientSocket<TCPClientSocket>(options, SOCK_STREAM, IPPROTO_TCP);
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   263
	}
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   264
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   265
	void send(const OutgoingMessage& message) override {
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   266
		auto ai = remoteAddress.ai;
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   267
		FD s(::socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol));
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   268
		check(::connect(s.getFD(), ai->ai_addr, ai->ai_addrlen), "connect socket");
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   269
		ssize_t written = ::write(s.getFD(), message.data.c_str(), message.data.size());
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   270
		if (written != message.data.size()) throw std::logic_error("writing to the socket failed");
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   271
		// TODO: partial writes, repeat
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   272
	}
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   273
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   274
	const IncomingMessage receive() override {
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   275
		// TODO: TCP receive()
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   276
		return IncomingMessage("TODO: receive() a message");
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   277
	}
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   278
};
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   279
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   280
class TCPServerSocket : public Socket {
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   281
private:
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   282
	AddressInfos::AddressInfo localAddress;
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   283
	FD socket;
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   284
public:
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   285
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   286
	TCPServerSocket(AddressInfos::AddressInfo localAddress) : localAddress(localAddress), socket(::socket(localAddress.ai->ai_family, localAddress.ai->ai_socktype, localAddress.ai->ai_protocol)) {
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   287
	}
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   288
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   289
	static std::shared_ptr<Socket> open(const SocketOptions& options) {
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   290
		auto socket = openClientSocket<TCPServerSocket>(options, SOCK_STREAM, IPPROTO_TCP);
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   291
		auto ai = socket->localAddress.ai;
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   292
		int reuseAddr = true;
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   293
		check(::setsockopt(socket->socket.getFD(), SOL_SOCKET, SO_REUSEADDR, &reuseAddr, sizeof (reuseAddr)), "setsockopt SO_REUSEADDR");
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   294
		check(::bind(socket->socket.getFD(), ai->ai_addr, ai->ai_addrlen), "bind");
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   295
		check(::listen(socket->socket.getFD(), 10), "listen"); // TODO: configurable backlog connection count?
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   296
		return socket;
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   297
	}
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   298
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   299
	void send(const OutgoingMessage& message) override {
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   300
		FD clientSocket(accept(socket.getFD(), nullptr, 0));
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   301
		ssize_t written = ::write(clientSocket.getFD(), message.data.c_str(), message.data.size());
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   302
		if (written != message.data.size()) throw std::logic_error("writing to the socket failed");
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   303
		// TODO: partial writes, repeat
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   304
	}
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   305
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   306
	const IncomingMessage receive() override {
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   307
		// TODO: TCP receive()
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   308
		return IncomingMessage("TODO: receive() a message");
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   309
	}
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   310
};
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   311
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   312
class SCTPClientSocket : public MSGSocket {
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   313
private:
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   314
	AddressInfos::AddressInfo remoteAddress;
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   315
public:
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   316
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   317
	SCTPClientSocket(AddressInfos::AddressInfo remoteAddress) : remoteAddress(remoteAddress), MSGSocket(::socket(remoteAddress.ai->ai_family, remoteAddress.ai->ai_socktype, remoteAddress.ai->ai_protocol)) {
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   318
	}
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   319
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   320
	static std::shared_ptr<Socket> open(const SocketOptions& options) {
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   321
		auto socket = openClientSocket<SCTPClientSocket>(options, SOCK_STREAM, IPPROTO_SCTP);
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   322
		check(::connect(socket->socket.getFD(), socket->remoteAddress.ai->ai_addr, socket->remoteAddress.ai->ai_addrlen), "connect socket");
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   323
		return socket;
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   324
	}
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   325
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   326
	const IncomingMessage receive() override {
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   327
		// TODO: SCTP receive()
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   328
		return IncomingMessage("TODO: receive() a message");
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   329
	}
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   330
};
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   331
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   332
class UDSClientSocket : public MSGSocket {
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   333
public:
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   334
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   335
	UDSClientSocket(int fd) : MSGSocket(fd) {
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   336
	}
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   337
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   338
	static std::shared_ptr<Socket> open(const SocketOptions& options) {
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   339
		struct sockaddr_un address;
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   340
		std::string path = findOption(options, OPTION_PATH);
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   341
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   342
		memset(&address, 0x00, sizeof (address));
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   343
		address.sun_family = AF_UNIX;
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   344
		strncpy(address.sun_path, path.c_str(), path.size());
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   345
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   346
		int fd = ::socket(AF_UNIX, SOCK_STREAM, 0);
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   347
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   348
		auto socket = std::make_shared<UDSClientSocket>(fd);
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   349
		check(::connect(socket->socket.getFD(), (const sockaddr*) &address, sizeof (address)), "connect socket");
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   350
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   351
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   352
		if (findOption(options, "debug") == "true") { // TODO: undocumented feature → standardize or remove
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   353
			struct ucred credentials;
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   354
			socklen_t credentialsLength = sizeof (credentials);
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   355
			memset(&credentials, 0x00, credentialsLength);
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   356
			getsockopt(fd, SOL_SOCKET, SO_PEERCRED, &credentials, &credentialsLength);
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   357
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   358
			printf("uds.fd = %d\n", fd);
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   359
			printf("uds.path = %s\n", address.sun_path);
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   360
			printf("uds.server.pid = %d\n", credentials.pid);
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   361
			printf("uds.server.uid = %d\n", credentials.uid);
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   362
			printf("uds.server.gid = %d\n", credentials.gid);
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   363
		}
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   364
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   365
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   366
		return socket;
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   367
	}
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   368
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   369
	const IncomingMessage receive() override {
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   370
		// TODO: UDS receive()
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   371
		return IncomingMessage("TODO: receive() a message");
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   372
	}
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   373
};
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   374
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   375
template<const char* protocol, const char* role, const char* mode, typename SocketClass>
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   376
class TemplateSocketFactory : public SocketFactory {
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   377
public:
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   378
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   379
	bool canHandle(const SocketOptions& options) override {
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   380
		return findOption(options, OPTION_PROTOCOL) == protocol
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   381
				&& findOption(options, OPTION_ROLE) == role
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   382
				&& findOption(options, OPTION_MODE) == mode;
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   383
	}
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   384
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   385
	std::shared_ptr<Socket> open(const SocketOptions& options) override {
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   386
		return SocketClass::open(options);
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   387
	}
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   388
};
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   389
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   390
static std::vector<std::shared_ptr<SocketFactory>> factories
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   391
{
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   392
	std::make_shared<TemplateSocketFactory<PROTOCOL_TCP, ROLE_CLIENT, MODE_STREAM, TCPClientSocket >> (),
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   393
	std::make_shared<TemplateSocketFactory<PROTOCOL_TCP, ROLE_SERVER, MODE_STREAM, TCPServerSocket >> (),
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   394
	std::make_shared<TemplateSocketFactory<PROTOCOL_UDP, ROLE_CLIENT, MODE_DATAGRAM, UDPClientSocket >> (),
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   395
	std::make_shared<TemplateSocketFactory<PROTOCOL_UDP, ROLE_SERVER, MODE_DATAGRAM, UDPServerSocket >> (),
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   396
	std::make_shared<TemplateSocketFactory<PROTOCOL_SCTP, ROLE_CLIENT, MODE_STREAM, SCTPClientSocket >> (),
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   397
	std::make_shared<TemplateSocketFactory<PROTOCOL_SCTP, ROLE_SERVER, MODE_STREAM, UDPClientSocket >> (), // TODO: correct class
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   398
	std::make_shared<TemplateSocketFactory<PROTOCOL_UDS, ROLE_CLIENT, MODE_STREAM, UDSClientSocket >> (),
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   399
	std::make_shared<TemplateSocketFactory<PROTOCOL_UDS, ROLE_CLIENT, MODE_DATAGRAM, UDSClientSocket >> (), // TODO: correct class
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   400
	std::make_shared<TemplateSocketFactory<PROTOCOL_UDS, ROLE_SERVER, MODE_STREAM, UDSClientSocket >> (), // TODO: correct class
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   401
	std::make_shared<TemplateSocketFactory<PROTOCOL_UDS, ROLE_SERVER, MODE_DATAGRAM, UDSClientSocket >> (), // TODO: correct class
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   402
};
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   403
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   404
std::shared_ptr<SocketFactory> SocketFactory::find(const SocketOptions& options) {
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   405
	for (auto f : factories) if (f->canHandle(options)) return f;
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   406
	throw std::logic_error("Unable to find a SocketFactory"); // TODO: add relevant options?
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   407
}
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   408
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   409
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   410
}
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   411
}
2b57c8683ffe synchronize interface and common classes with relpipe-out-socket + implement basic UDPServerSocket::receive()
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   412
}