congestvpn/UdpVpnServer.cpp

54 lines
1.5 KiB
C++
Raw Permalink Normal View History

#include <cstring>
#include "UdpVpnServer.hpp"
#include "ip_header.hpp"
UdpVpnServer::UdpVpnServer(in_port_t port) : UdpVpn() {
memset(&_bind_addr, 0, sizeof(_bind_addr));
bind(in6addr_any, port);
}
UdpVpnServer::UdpVpnServer(const struct in6_addr& bind_addr6, in_port_t port)
: UdpVpn()
{
memset(&_bind_addr, 0, sizeof(_bind_addr));
bind(bind_addr6, port);
}
void UdpVpnServer::acquire_peer(
TunnelledPacket& packet,
const sockaddr_in6& peer_ext_addr)
{
if(_peer)
return; // Refusing a connection if we already have one
// TODO: reset state at some point/if connection broken
if(!packet.parse_as_ipv6())
return;
const in6_addr& peer_inner_addr = packet.get_ipv6_header().source;
_peer = std::make_unique<VpnPeer>(this, peer_ext_addr, peer_inner_addr);
packet.get_packet().set_peer(_peer.get());
debugf("Got new peer %s:%d -- %s\n",
format_address(peer_ext_addr.sin6_addr.s6_addr),
htons(peer_ext_addr.sin6_port),
format_address(peer_inner_addr.s6_addr));
}
void UdpVpnServer::bind(const struct in6_addr& bind_addr6, in_port_t port) {
int rc;
_bind_addr.sin6_family = AF_INET6;
_bind_addr.sin6_port = htons(port);
_bind_addr.sin6_addr = bind_addr6;
rc = ::bind(
_socket, (const struct sockaddr*)&_bind_addr, sizeof(_bind_addr));
if(rc < 0) {
throw UdpVpn::InitializationError("Cannot bind socket", errno, true);
}
debugf("> Listening on port %d\n", port);
}