congestvpn/UdpVpnClient.cpp

58 lines
1.7 KiB
C++

#include <cstring>
#include "UdpVpnClient.hpp"
#include "ip_header.hpp"
UdpVpnClient::UdpVpnClient(const struct sockaddr_in6& server) : UdpVpn() {
memset(&_server_addr, 0, sizeof(_server_addr));
set_server(server);
}
void UdpVpnClient::set_server(const struct sockaddr_in6& server_addr) {
if(server_addr.sin6_family != AF_INET6)
throw UdpVpn::InitializationError("Server address must be IPv6");
memcpy(&_server_addr, &server_addr, sizeof(_server_addr));
}
void UdpVpnClient::receive_from_tun() {
VpnPacket packet(_vpn_mtu);
size_t nread = read_from_tun(packet);
if(nread == 0)
return;
kdebugf("Transmitting %s -> %s, size %d\n",
format_address(packet.get_ipv6_header().source.s6_addr),
format_address(packet.get_ipv6_header().dest.s6_addr),
nread);
packet.prepare_for_sending();
write_to_server(packet);
}
void UdpVpnClient::receive_from_udp() {
VpnPacket packet(_vpn_mtu);
sockaddr_in6 peer_addr;
size_t nread = read_from_udp(packet, peer_addr);
if(nread == 0)
return;
// Reinject into tun
kdebugf("Receiving packet #%u of size %d from %s\n",
packet.get_seqno(),
nread,
format_address(packet.get_ipv6_header().source.s6_addr));
_tun_dev.write(packet.get_payload(), packet.get_payload_size());
}
size_t UdpVpnClient::write_to_server(const VpnPacket& packet) {
ssize_t nsent;
nsent = sendto(_socket, packet.get_data(), packet.get_data_size(),
MSG_CONFIRM,
(const struct sockaddr*) &_server_addr, sizeof(_server_addr));
if(nsent < 0)
throw NetError("Could not send UDP packet", errno, true);
return (size_t) nsent;
}