|
@@ -4,11 +4,12 @@ namespace AstrogateTunnel {
|
|
|
|
|
|
private static Socket socket;
|
|
|
private static int tun_fd;
|
|
|
-
|
|
|
+
|
|
|
private static string ifname;
|
|
|
private static InetSocketAddress server_address;
|
|
|
private static InetSocketAddress client_address;
|
|
|
-
|
|
|
+
|
|
|
+ private static Socket vpn_socket;
|
|
|
private static InetAddress vpn_network;
|
|
|
private static InetAddress vpn_netmask;
|
|
|
private static InetAddress vpn_ip;
|
|
@@ -30,13 +31,6 @@ namespace AstrogateTunnel {
|
|
|
socket = new Socket(server_address.family, SocketType.DATAGRAM, SocketProtocol.UDP);
|
|
|
socket.bind(client_address, false);
|
|
|
|
|
|
- // Open tun device
|
|
|
- tun_fd = handle_posix_error("opening tun device", Posix.open("/dev/net/tun", Posix.O_RDWR));
|
|
|
-
|
|
|
- // Create tunnel device
|
|
|
- var request = generate_ifreq();
|
|
|
- handle_posix_error("creating tun interface", Linux.ioctl(tun_fd, IfTun.Tun.SETIFF, &request));
|
|
|
-
|
|
|
// Register with server
|
|
|
var registration_message = new uint8[] { 'R' };
|
|
|
socket.connect(server_address);
|
|
@@ -69,6 +63,14 @@ namespace AstrogateTunnel {
|
|
|
return -3;
|
|
|
}
|
|
|
|
|
|
+ // Open tun device
|
|
|
+ tun_fd = handle_posix_error("opening tun device", Posix.open("/dev/net/tun", Posix.O_RDWR));
|
|
|
+
|
|
|
+ // Create tunnel device
|
|
|
+ var request = generate_ifreq();
|
|
|
+ handle_posix_error("creating tun interface", Linux.ioctl(tun_fd, IfTun.Tun.SETIFF, &request));
|
|
|
+ vpn_socket = new Socket(vpn_network.family, SocketType.DATAGRAM, SocketProtocol.UDP);
|
|
|
+
|
|
|
uint16 mtu_val = 0;
|
|
|
Memory.copy(&mtu_val, mtu_dat, sizeof(uint16));
|
|
|
mtu = mtu_val.to_big_endian();
|
|
@@ -81,19 +83,19 @@ namespace AstrogateTunnel {
|
|
|
|
|
|
request.ifr_flags = 0;
|
|
|
request.ifr_mtu = mtu;
|
|
|
- handle_posix_error(@"setting MTU for $ifname", Linux.ioctl(socket.fd, Linux.Network.SIOCSIFMTU, &request));
|
|
|
+ handle_posix_error(@"setting MTU for $ifname", Linux.ioctl(vpn_socket.fd, Linux.Network.SIOCSIFMTU, &request));
|
|
|
|
|
|
request.ifr_flags |= Linux.Network.IfFlag.UP;
|
|
|
- handle_posix_error(@"bringing $ifname up", Linux.ioctl(socket.fd, Linux.Network.SIOCSIFFLAGS, &request));
|
|
|
+ handle_posix_error(@"bringing $ifname up", Linux.ioctl(vpn_socket.fd, Linux.Network.SIOCSIFFLAGS, &request));
|
|
|
|
|
|
address_to_posix(vpn_ip, &request.ifr_addr);
|
|
|
- handle_posix_error(@"setting IP address for $ifname", Linux.ioctl(socket.fd, Linux.Network.SIOCSIFADDR, &request));
|
|
|
+ handle_posix_error(@"setting IP address for $ifname", Linux.ioctl(vpn_socket.fd, Linux.Network.SIOCSIFADDR, &request));
|
|
|
|
|
|
address_to_posix(vpn_netmask, &request.ifr_addr);
|
|
|
- handle_posix_error(@"setting subnet mask for $ifname", Linux.ioctl(socket.fd, Linux.Network.SIOCSIFNETMASK, &request));
|
|
|
+ handle_posix_error(@"setting subnet mask for $ifname", Linux.ioctl(vpn_socket.fd, Linux.Network.SIOCSIFNETMASK, &request));
|
|
|
|
|
|
address_to_posix(vpn_network, &request.ifr_addr);
|
|
|
- handle_posix_error(@"setting destination network for $ifname", Linux.ioctl(socket.fd, Linux.Network.SIOCSIFDSTADDR, &request));
|
|
|
+ handle_posix_error(@"setting destination network for $ifname", Linux.ioctl(vpn_socket.fd, Linux.Network.SIOCSIFDSTADDR, &request));
|
|
|
}
|
|
|
catch(Error e) {
|
|
|
print(@"Fatal error: $(e.message)\n");
|
|
@@ -162,7 +164,7 @@ namespace AstrogateTunnel {
|
|
|
print(@"Linking IP $(address)\n");
|
|
|
var route = build_rtentry(address);
|
|
|
|
|
|
- var res = Linux.ioctl(socket.fd, Linux.Network.SIOCADDRT, &route);
|
|
|
+ var res = Linux.ioctl(vpn_socket.fd, Linux.Network.SIOCADDRT, &route);
|
|
|
if(res < 0 && errno != Posix.EEXIST) {
|
|
|
handle_posix_error(@"adding route to $address", res);
|
|
|
}
|
|
@@ -175,7 +177,7 @@ namespace AstrogateTunnel {
|
|
|
var address = new InetAddress.from_bytes(buffer[1:buffer.length], vpn_ip.family);
|
|
|
print(@"Uninking IP $(address)\n");
|
|
|
var route = build_rtentry(address);
|
|
|
- handle_posix_error(@"adding route to $address", Linux.ioctl(socket.fd, Linux.Network.SIOCDELRT, &route));
|
|
|
+ handle_posix_error(@"adding route to $address", Linux.ioctl(vpn_socket.fd, Linux.Network.SIOCDELRT, &route));
|
|
|
}
|
|
|
|
|
|
private Linux.Network.RtEntry build_rtentry(InetAddress address) {
|