// Copyright 2025 The frp Authors // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package main import ( "flag" "fmt" "net" "os" "os/signal" "syscall" v1 "github.com/fatedier/frp/pkg/config/v1" "github.com/fatedier/frp/pkg/vnet" ) func main() { // Parse command-line flags listenAddr := flag.String("listen", ":8000", "Server listen address (ip:port)") serverTUNAddr := flag.String("tun", "10.20.0.1/24", "Server TUN device address") flag.Parse() // Listen for incoming connections listener, err := net.Listen("tcp", *listenAddr) if err != nil { fmt.Printf("Failed to listen on %s: %v\n", *listenAddr, err) return } defer listener.Close() fmt.Printf("Server listening on %s\n", *listenAddr) fmt.Printf("Server TUN address: %s\n", *serverTUNAddr) // Set up vnet controller on the server serverCfg := v1.VirtualNetConfig{ Address: *serverTUNAddr, // Server TUN device address } serverController := vnet.NewController(serverCfg) if err := serverController.Init(); err != nil { fmt.Printf("Server init error: %v\n", err) return } // Start the controller go func() { if err := serverController.Run(); err != nil { fmt.Printf("Server run error: %v\n", err) } }() // Handle shutdown gracefully c := make(chan os.Signal, 1) signal.Notify(c, syscall.SIGINT, syscall.SIGTERM) go func() { <-c fmt.Println("\nShutting down server...") os.Exit(0) }() fmt.Println("Waiting for client connection...") // Accept and handle connections for { conn, err := listener.Accept() if err != nil { fmt.Printf("Error accepting connection: %v\n", err) continue } fmt.Printf("New client connected from %s\n", conn.RemoteAddr()) // Wrap the connection rwc := &readWriteCloserConn{conn} // Register the connection if err := serverController.RegisterServerConn("client", rwc); err != nil { fmt.Printf("Register server connection error: %v\n", err) conn.Close() continue } fmt.Println("VPN tunnel established with client") fmt.Printf("Server TUN: %s\n", *serverTUNAddr) } } // readWriteCloserConn wraps net.Conn as io.ReadWriteCloser type readWriteCloserConn struct { net.Conn } func (rwc *readWriteCloserConn) Read(p []byte) (n int, err error) { return rwc.Conn.Read(p) } func (rwc *readWriteCloserConn) Write(p []byte) (n int, err error) { return rwc.Conn.Write(p) } func (rwc *readWriteCloserConn) Close() error { return rwc.Conn.Close() }