67 lines
2 KiB
C++
67 lines
2 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() {
|
|
char buffer[1500];
|
|
size_t nread = read_from_tun(buffer, 1500);
|
|
if(nread == 0)
|
|
return;
|
|
|
|
// Parse inner packet header -- assume IPv6 for now [FIXME]
|
|
IPv6Header inner_header;
|
|
if(!parse_ipv6_header(buffer, nread, inner_header)) {
|
|
// Not a valid header -- ignore the packet
|
|
debugf("Ignoring outgoing packet with invalid header\n");
|
|
return;
|
|
}
|
|
|
|
kdebugf("Transmitting %s -> %s, size %d\n",
|
|
format_address(inner_header.source.s6_addr),
|
|
format_address(inner_header.dest.s6_addr),
|
|
nread);
|
|
|
|
write_to_server(buffer, nread);
|
|
}
|
|
|
|
void UdpVpnClient::receive_from_udp() {
|
|
char buffer[1500];
|
|
sockaddr_in6 peer_addr;
|
|
size_t nread = read_from_udp(buffer, 1500, peer_addr);
|
|
|
|
// Parse inner packet header -- assume IPv6 for now [FIXME]
|
|
IPv6Header inner_header;
|
|
if(!parse_ipv6_header(buffer, nread, inner_header)) {
|
|
// Not a valid header -- ignore the packet
|
|
debugf("Ignoring packet with invalid header\n");
|
|
return;
|
|
}
|
|
|
|
// Reinject into tun
|
|
kdebugf("Receiving packet of size %d from peer\n", nread);
|
|
_tun_dev.write(buffer, nread);
|
|
}
|
|
|
|
size_t UdpVpnClient::write_to_server(const char* data, size_t len) {
|
|
ssize_t nsent;
|
|
|
|
nsent = sendto(_socket, data, len, 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;
|
|
}
|