mirror of
https://github.com/net-byte/vtun
synced 2024-03-14 10:50:03 +08:00
add comments
This commit is contained in:
parent
d3a5d1b7de
commit
321870d194
2
common/cache/cache.go
vendored
2
common/cache/cache.go
vendored
@ -6,8 +6,10 @@ import (
|
||||
"github.com/patrickmn/go-cache"
|
||||
)
|
||||
|
||||
// The global cache
|
||||
var _cache = cache.New(30*time.Minute, 10*time.Minute)
|
||||
|
||||
// GetCache returns the cache
|
||||
func GetCache() *cache.Cache {
|
||||
return _cache
|
||||
}
|
||||
|
@ -1,11 +1,14 @@
|
||||
package cipher
|
||||
|
||||
// The default key
|
||||
var _key = []byte("vtun@2022")
|
||||
|
||||
// SetKey sets the key
|
||||
func SetKey(key string) {
|
||||
_key = []byte(key)
|
||||
}
|
||||
|
||||
// XOR encrypts the data
|
||||
func XOR(src []byte) []byte {
|
||||
_klen := len(_key)
|
||||
for i := 0; i < len(src); i++ {
|
||||
|
@ -1,5 +1,6 @@
|
||||
package config
|
||||
|
||||
// The config struct
|
||||
type Config struct {
|
||||
DeviceName string
|
||||
LocalAddr string
|
||||
|
@ -2,21 +2,28 @@ package counter
|
||||
|
||||
import "sync/atomic"
|
||||
|
||||
// totalReadBytes is the total number of bytes read
|
||||
var _totalReadBytes uint64 = 0
|
||||
|
||||
// totalWrittenBytes is the total number of bytes written
|
||||
var _totalWrittenBytes uint64 = 0
|
||||
|
||||
// IncrReadBytes increments the number of bytes read
|
||||
func IncrReadBytes(n int) {
|
||||
atomic.AddUint64(&_totalReadBytes, uint64(n))
|
||||
}
|
||||
|
||||
//IncrWrittenBytes increments the number of bytes written
|
||||
func IncrWrittenBytes(n int) {
|
||||
atomic.AddUint64(&_totalWrittenBytes, uint64(n))
|
||||
}
|
||||
|
||||
// GetReadBytes returns the number of bytes read
|
||||
func GetReadBytes() uint64 {
|
||||
return _totalReadBytes
|
||||
}
|
||||
|
||||
// GetWrittenBytes returns the number of bytes written
|
||||
func GetWrittenBytes() uint64 {
|
||||
return _totalWrittenBytes
|
||||
}
|
||||
|
@ -15,6 +15,7 @@ import (
|
||||
"github.com/net-byte/vtun/common/config"
|
||||
)
|
||||
|
||||
// ConnectServer connects to the server with the given address.
|
||||
func ConnectServer(config config.Config) net.Conn {
|
||||
net.DefaultResolver = &net.Resolver{
|
||||
PreferGo: true,
|
||||
@ -47,6 +48,7 @@ func ConnectServer(config config.Config) net.Conn {
|
||||
return c
|
||||
}
|
||||
|
||||
// GetInterfaceName returns the name of interface
|
||||
func GetInterface() (name string) {
|
||||
ifaces := getAllInterfaces()
|
||||
if len(ifaces) == 0 {
|
||||
@ -63,6 +65,7 @@ func GetInterface() (name string) {
|
||||
return name
|
||||
}
|
||||
|
||||
// getAllInterfaces returns all interfaces
|
||||
func getAllInterfaces() []net.Interface {
|
||||
ifaces, err := net.Interfaces()
|
||||
if err != nil {
|
||||
@ -82,6 +85,7 @@ func getAllInterfaces() []net.Interface {
|
||||
return outInterfaces
|
||||
}
|
||||
|
||||
// isPhysicalInterface returns true if the interface is physical
|
||||
func isPhysicalInterface(addr string) bool {
|
||||
prefixArray := []string{"ens", "enp", "enx", "eno", "eth", "en0", "wlan", "wlp", "wlo", "wlx", "wifi0", "lan0"}
|
||||
for _, pref := range prefixArray {
|
||||
@ -92,6 +96,7 @@ func isPhysicalInterface(addr string) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
// Lookup IP address of the given hostname
|
||||
func LookupIP(domain string) net.IP {
|
||||
ips, err := net.LookupIP(domain)
|
||||
if err != nil || len(ips) == 0 {
|
||||
@ -101,32 +106,39 @@ func LookupIP(domain string) net.IP {
|
||||
return ips[0]
|
||||
}
|
||||
|
||||
// IsIPv4 returns true if the packet is IPv4s
|
||||
func IsIPv4(packet []byte) bool {
|
||||
flag := packet[0] >> 4
|
||||
return flag == 4
|
||||
}
|
||||
|
||||
// IsIPv6 returns true if the packet is IPv6s
|
||||
func IsIPv6(packet []byte) bool {
|
||||
flag := packet[0] >> 4
|
||||
return flag == 6
|
||||
}
|
||||
|
||||
// GetIPv4Src returns the IPv4 source address of the packet
|
||||
func GetIPv4Src(packet []byte) net.IP {
|
||||
return net.IPv4(packet[12], packet[13], packet[14], packet[15])
|
||||
}
|
||||
|
||||
// GEtIPv4Dst returns the IPv4 destination address of the packet
|
||||
func GetIPv4Dst(packet []byte) net.IP {
|
||||
return net.IPv4(packet[16], packet[17], packet[18], packet[19])
|
||||
}
|
||||
|
||||
// GetIPv6Src returns the IPv6 source address of the packet
|
||||
func GetIPv6Src(packet []byte) net.IP {
|
||||
return net.IP(packet[8:24])
|
||||
}
|
||||
|
||||
// GetIPv6Dst returns the IPv6 destination address of the packet
|
||||
func GetIPv6Dst(packet []byte) net.IP {
|
||||
return net.IP(packet[24:40])
|
||||
}
|
||||
|
||||
// GetSrcKey returns the source key of the packet
|
||||
func GetSrcKey(packet []byte) string {
|
||||
key := ""
|
||||
if IsIPv4(packet) && len(packet) >= 20 {
|
||||
@ -137,6 +149,7 @@ func GetSrcKey(packet []byte) string {
|
||||
return key
|
||||
}
|
||||
|
||||
// GetdstKey returns the destination key of the packets
|
||||
func GetDstKey(packet []byte) string {
|
||||
key := ""
|
||||
if IsIPv4(packet) && len(packet) >= 20 {
|
||||
@ -147,6 +160,7 @@ func GetDstKey(packet []byte) string {
|
||||
return key
|
||||
}
|
||||
|
||||
// ExecuteCommand executes the given command
|
||||
func ExecCmd(c string, args ...string) string {
|
||||
log.Printf("exec cmd: %v %v:", c, args)
|
||||
cmd := exec.Command(c, args...)
|
||||
@ -161,6 +175,7 @@ func ExecCmd(c string, args ...string) string {
|
||||
return strings.ReplaceAll(s, "\n", "")
|
||||
}
|
||||
|
||||
// GetLocalGatewayOnLinux returns the local gateway IP address on Linux
|
||||
func GetLocalGatewayOnLinux(ipv4 bool) string {
|
||||
if ipv4 {
|
||||
return ExecCmd("sh", "-c", "route -n | grep 'UG[ \t]' | awk 'NR==1{print $2}'")
|
||||
@ -168,6 +183,7 @@ func GetLocalGatewayOnLinux(ipv4 bool) string {
|
||||
return ExecCmd("sh", "-c", "route -6 -n | grep 'UG[ \t]' | awk 'NR==1{print $2}'")
|
||||
}
|
||||
|
||||
// GetLocalGatewayOnMac returns the local gateway IP address on MacOS
|
||||
func GetLocalGatewayOnMac(ipv4 bool) string {
|
||||
if ipv4 {
|
||||
return ExecCmd("sh", "-c", "route -n get default | grep 'gateway' | awk 'NR==1{print $2}'")
|
||||
|
@ -17,6 +17,7 @@ import (
|
||||
"github.com/songgao/water"
|
||||
)
|
||||
|
||||
// StartClient starts the grpc client
|
||||
func StartClient(config config.Config) {
|
||||
log.Printf("vtun grpc client started on %v", config.LocalAddr)
|
||||
iface := tun.CreateTun(config)
|
||||
@ -47,6 +48,7 @@ func StartClient(config config.Config) {
|
||||
}
|
||||
}
|
||||
|
||||
// tunToGrpc sends packets from tun to grpc
|
||||
func tunToGrpc(config config.Config, iface *water.Interface) {
|
||||
packet := make([]byte, config.MTU)
|
||||
for {
|
||||
@ -68,6 +70,7 @@ func tunToGrpc(config config.Config, iface *water.Interface) {
|
||||
}
|
||||
}
|
||||
|
||||
// grpcToTun sends packets from grpc to tun
|
||||
func grpcToTun(config config.Config, stream proto.GrpcServe_TunnelClient, iface *water.Interface) {
|
||||
for {
|
||||
packet, err := stream.Recv()
|
||||
|
@ -17,17 +17,20 @@ import (
|
||||
"github.com/songgao/water"
|
||||
)
|
||||
|
||||
// The StreamService is the implementation of the StreamServer interface
|
||||
type StreamService struct {
|
||||
proto.UnimplementedGrpcServeServer
|
||||
config config.Config
|
||||
iface *water.Interface
|
||||
}
|
||||
|
||||
// Tunnel implements the StreamServer interface
|
||||
func (s *StreamService) Tunnel(srv proto.GrpcServe_TunnelServer) error {
|
||||
toServer(srv, s.config, s.iface)
|
||||
return nil
|
||||
}
|
||||
|
||||
// StartServer starts the grpc server
|
||||
func StartServer(config config.Config) {
|
||||
log.Printf("vtun grpc server started on %v", config.LocalAddr)
|
||||
iface := tun.CreateTun(config)
|
||||
@ -49,6 +52,7 @@ func StartServer(config config.Config) {
|
||||
}
|
||||
}
|
||||
|
||||
// toClient sends packets from tun to grpc
|
||||
func toClient(config config.Config, iface *water.Interface) {
|
||||
packet := make([]byte, config.MTU)
|
||||
for {
|
||||
@ -68,6 +72,7 @@ func toClient(config config.Config, iface *water.Interface) {
|
||||
}
|
||||
}
|
||||
|
||||
// toServer sends packets from grpc to tun
|
||||
func toServer(srv proto.GrpcServe_TunnelServer, config config.Config, iface *water.Interface) {
|
||||
for {
|
||||
packet, err := srv.Recv()
|
||||
|
7
main.go
7
main.go
@ -52,6 +52,7 @@ func main() {
|
||||
stopApp(config)
|
||||
}
|
||||
|
||||
// initConfig initializes the config
|
||||
func initConfig(config *config.Config) {
|
||||
if !config.ServerMode && config.GlobalMode {
|
||||
host, _, err := net.SplitHostPort(config.ServerAddr)
|
||||
@ -71,6 +72,7 @@ func initConfig(config *config.Config) {
|
||||
log.Printf("init config:%s", string(json))
|
||||
}
|
||||
|
||||
// startApp starts the app
|
||||
func startApp(config config.Config) {
|
||||
switch config.Protocol {
|
||||
case "udp":
|
||||
@ -106,7 +108,8 @@ func startApp(config config.Config) {
|
||||
}
|
||||
}
|
||||
|
||||
// stopApp stops the app
|
||||
func stopApp(config config.Config) {
|
||||
tun.Reset(config)
|
||||
log.Printf("stopped!!!")
|
||||
tun.ResetTun(config)
|
||||
log.Printf("vtun stopped")
|
||||
}
|
||||
|
@ -9,25 +9,30 @@ import (
|
||||
"github.com/patrickmn/go-cache"
|
||||
)
|
||||
|
||||
// The global cache for register
|
||||
var _register *cache.Cache
|
||||
|
||||
func init() {
|
||||
_register = cache.New(30*time.Minute, 3*time.Minute)
|
||||
}
|
||||
|
||||
// AddClientIP adds a client ip to the register
|
||||
func AddClientIP(ip string) {
|
||||
_register.Add(ip, 0, cache.DefaultExpiration)
|
||||
}
|
||||
|
||||
// DeleteClientIP deletes a client ip from the register
|
||||
func DeleteClientIP(ip string) {
|
||||
_register.Delete(ip)
|
||||
}
|
||||
|
||||
// ExistClientIP checks if the client ip is in the register
|
||||
func ExistClientIP(ip string) bool {
|
||||
_, ok := _register.Get(ip)
|
||||
return ok
|
||||
}
|
||||
|
||||
// keepAlive keeps the client ip alive
|
||||
func KeepAliveClientIP(ip string) {
|
||||
if ExistClientIP(ip) {
|
||||
_register.Increment(ip, 1)
|
||||
@ -36,6 +41,7 @@ func KeepAliveClientIP(ip string) {
|
||||
}
|
||||
}
|
||||
|
||||
// PickClientIP picks a client ip from the register
|
||||
func PickClientIP(cidr string) (clientIP string, prefixLength string) {
|
||||
ip, ipNet, err := net.ParseCIDR(cidr)
|
||||
if err != nil {
|
||||
@ -59,7 +65,8 @@ func PickClientIP(cidr string) (clientIP string, prefixLength string) {
|
||||
return "", ""
|
||||
}
|
||||
|
||||
func ListClientIP() []string {
|
||||
// ListClientIPs returns the client ips in the register
|
||||
func ListClientIPs() []string {
|
||||
result := []string{}
|
||||
for k := range _register.Items() {
|
||||
result = append(result, k)
|
||||
@ -67,11 +74,13 @@ func ListClientIP() []string {
|
||||
return result
|
||||
}
|
||||
|
||||
// addressCount returns the number of addresses in a CIDR network.
|
||||
func addressCount(network *net.IPNet) uint64 {
|
||||
prefixLen, bits := network.Mask.Size()
|
||||
return 1 << (uint64(bits) - uint64(prefixLen))
|
||||
}
|
||||
|
||||
// incr increments the ip by 1
|
||||
func incr(IP net.IP) net.IP {
|
||||
IP = checkIPv4(IP)
|
||||
incIP := make([]byte, len(IP))
|
||||
@ -85,6 +94,7 @@ func incr(IP net.IP) net.IP {
|
||||
return incIP
|
||||
}
|
||||
|
||||
// checkIPv4 checks if the ip is IPv4
|
||||
func checkIPv4(ip net.IP) net.IP {
|
||||
if v4 := ip.To4(); v4 != nil {
|
||||
return v4
|
||||
|
@ -14,7 +14,7 @@ import (
|
||||
"github.com/songgao/water"
|
||||
)
|
||||
|
||||
// Start tls client
|
||||
// StartClient starts the tls client
|
||||
func StartClient(config config.Config) {
|
||||
log.Printf("vtun tls client started on %v", config.LocalAddr)
|
||||
iface := tun.CreateTun(config)
|
||||
@ -37,6 +37,7 @@ func StartClient(config config.Config) {
|
||||
}
|
||||
}
|
||||
|
||||
// tunToTLS sends packets from tun to tls
|
||||
func tunToTLS(config config.Config, iface *water.Interface) {
|
||||
packet := make([]byte, config.MTU)
|
||||
for {
|
||||
@ -59,6 +60,7 @@ func tunToTLS(config config.Config, iface *water.Interface) {
|
||||
}
|
||||
}
|
||||
|
||||
// tlsToTun sends packets from tls to tun
|
||||
func tlsToTun(config config.Config, tlsconn net.Conn, iface *water.Interface) {
|
||||
defer tlsconn.Close()
|
||||
packet := make([]byte, config.MTU)
|
||||
|
@ -15,7 +15,7 @@ import (
|
||||
"github.com/songgao/water"
|
||||
)
|
||||
|
||||
//Start tls server
|
||||
// StartServer starts the tls server
|
||||
func StartServer(config config.Config) {
|
||||
log.Printf("vtun tls server started on %v", config.LocalAddr)
|
||||
iface := tun.CreateTun(config)
|
||||
@ -51,6 +51,7 @@ func StartServer(config config.Config) {
|
||||
}
|
||||
}
|
||||
|
||||
// toClient sends packets from iface to tlsconn
|
||||
func toClient(config config.Config, iface *water.Interface) {
|
||||
packet := make([]byte, config.MTU)
|
||||
for {
|
||||
@ -70,7 +71,7 @@ func toClient(config config.Config, iface *water.Interface) {
|
||||
}
|
||||
}
|
||||
|
||||
// todo fallback to http
|
||||
// toServer sends packets from tlsconn to iface
|
||||
func toServer(config config.Config, tlsconn net.Conn, iface *water.Interface) {
|
||||
defer tlsconn.Close()
|
||||
packet := make([]byte, config.MTU)
|
||||
|
@ -11,6 +11,7 @@ import (
|
||||
"github.com/songgao/water"
|
||||
)
|
||||
|
||||
// CreateTun creates a tun interface
|
||||
func CreateTun(config config.Config) (iface *water.Interface) {
|
||||
c := water.Config{DeviceType: water.TUN}
|
||||
if config.DeviceName != "" {
|
||||
@ -25,6 +26,7 @@ func CreateTun(config config.Config) (iface *water.Interface) {
|
||||
return iface
|
||||
}
|
||||
|
||||
// ConfigTun configures the tun interface
|
||||
func configTun(config config.Config, iface *water.Interface) {
|
||||
os := runtime.GOOS
|
||||
ip, _, err := net.ParseCIDR(config.CIDR)
|
||||
@ -91,7 +93,8 @@ func configTun(config config.Config, iface *water.Interface) {
|
||||
}
|
||||
}
|
||||
|
||||
func Reset(config config.Config) {
|
||||
// ResetTun resets the tun interface
|
||||
func ResetTun(config config.Config) {
|
||||
os := runtime.GOOS
|
||||
if os == "darwin" && !config.ServerMode && config.GlobalMode {
|
||||
netutil.ExecCmd("route", "add", "default", config.LocalGateway)
|
||||
|
@ -12,7 +12,7 @@ import (
|
||||
"golang.org/x/net/ipv6"
|
||||
)
|
||||
|
||||
// Start udp client
|
||||
// StartClient starts the udp client
|
||||
func StartClient(config config.Config) {
|
||||
log.Printf("vtun udp client started on %v", config.LocalAddr)
|
||||
iface := tun.CreateTun(config)
|
||||
@ -45,6 +45,7 @@ func StartClient(config config.Config) {
|
||||
c.tunToUdp()
|
||||
}
|
||||
|
||||
// The client struct
|
||||
type Client struct {
|
||||
config config.Config
|
||||
iface *water.Interface
|
||||
@ -52,6 +53,7 @@ type Client struct {
|
||||
serverAddr *net.UDPAddr
|
||||
}
|
||||
|
||||
// udpToTun sends packets from udp to tun
|
||||
func (c *Client) udpToTun() {
|
||||
packet := make([]byte, c.config.MTU)
|
||||
for {
|
||||
@ -66,6 +68,8 @@ func (c *Client) udpToTun() {
|
||||
c.iface.Write(b)
|
||||
}
|
||||
}
|
||||
|
||||
// tunToUdp sends packets from tun to udp
|
||||
func (c *Client) tunToUdp() {
|
||||
packet := make([]byte, c.config.MTU)
|
||||
for {
|
||||
|
@ -15,7 +15,7 @@ import (
|
||||
"golang.org/x/net/ipv6"
|
||||
)
|
||||
|
||||
// Start udp server
|
||||
// StartServer starts the udp server
|
||||
func StartServer(config config.Config) {
|
||||
log.Printf("vtun udp server started on %v", config.LocalAddr)
|
||||
iface := tun.CreateTun(config)
|
||||
@ -44,6 +44,7 @@ func StartServer(config config.Config) {
|
||||
s.udpToTun()
|
||||
}
|
||||
|
||||
// the server struct
|
||||
type Server struct {
|
||||
config config.Config
|
||||
iface *water.Interface
|
||||
@ -51,6 +52,7 @@ type Server struct {
|
||||
connCache *cache.Cache
|
||||
}
|
||||
|
||||
// tunToUdp sends packets from tun to udp
|
||||
func (s *Server) tunToUdp() {
|
||||
packet := make([]byte, s.config.MTU)
|
||||
for {
|
||||
@ -70,6 +72,7 @@ func (s *Server) tunToUdp() {
|
||||
}
|
||||
}
|
||||
|
||||
// udpToTun sends packets from udp to tun
|
||||
func (s *Server) udpToTun() {
|
||||
packet := make([]byte, s.config.MTU)
|
||||
for {
|
||||
|
@ -14,7 +14,7 @@ import (
|
||||
"github.com/songgao/water"
|
||||
)
|
||||
|
||||
// Start websocket client
|
||||
// StartClient starts the ws client
|
||||
func StartClient(config config.Config) {
|
||||
log.Printf("vtun websocket client started on %v", config.LocalAddr)
|
||||
iface := tun.CreateTun(config)
|
||||
@ -31,6 +31,7 @@ func StartClient(config config.Config) {
|
||||
}
|
||||
}
|
||||
|
||||
// wsToTun sends packets from ws to tun
|
||||
func wsToTun(config config.Config, wsconn net.Conn, iface *water.Interface) {
|
||||
defer wsconn.Close()
|
||||
for {
|
||||
@ -49,6 +50,7 @@ func wsToTun(config config.Config, wsconn net.Conn, iface *water.Interface) {
|
||||
}
|
||||
}
|
||||
|
||||
// tunToWs sends packets from tun to ws
|
||||
func tunToWs(config config.Config, iface *water.Interface) {
|
||||
packet := make([]byte, config.MTU)
|
||||
for {
|
||||
|
@ -22,7 +22,7 @@ import (
|
||||
"github.com/songgao/water"
|
||||
)
|
||||
|
||||
// Start websocket server
|
||||
// StartServer starts the ws server
|
||||
func StartServer(config config.Config) {
|
||||
iface := tun.CreateTun(config)
|
||||
// server -> client
|
||||
@ -88,7 +88,7 @@ func StartServer(config config.Config) {
|
||||
if !checkPermission(w, r, config) {
|
||||
return
|
||||
}
|
||||
io.WriteString(w, strings.Join(register.ListClientIP(), "\r\n"))
|
||||
io.WriteString(w, strings.Join(register.ListClientIPs(), "\r\n"))
|
||||
})
|
||||
|
||||
http.HandleFunc("/register/prefix/ipv4", func(w http.ResponseWriter, r *http.Request) {
|
||||
@ -132,6 +132,8 @@ func StartServer(config config.Config) {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// checkPermission checks the permission of the request
|
||||
func checkPermission(w http.ResponseWriter, req *http.Request, config config.Config) bool {
|
||||
key := req.Header.Get("key")
|
||||
if key != config.Key {
|
||||
@ -142,6 +144,7 @@ func checkPermission(w http.ResponseWriter, req *http.Request, config config.Con
|
||||
return true
|
||||
}
|
||||
|
||||
// toClient sends data to client
|
||||
func toClient(config config.Config, iface *water.Interface) {
|
||||
packet := make([]byte, config.MTU)
|
||||
for {
|
||||
@ -162,6 +165,7 @@ func toClient(config config.Config, iface *water.Interface) {
|
||||
}
|
||||
}
|
||||
|
||||
// toServer sends data to server
|
||||
func toServer(config config.Config, wsconn net.Conn, iface *water.Interface) {
|
||||
defer wsconn.Close()
|
||||
for {
|
||||
|
Loading…
Reference in New Issue
Block a user