github.com/bepass-org/wireguard-go@v1.0.4-rc2.0.20240304192354-ebce6572bc24/wiresocks/wiresocks.go (about)

     1  package wiresocks
     2  
     3  import (
     4  	"bytes"
     5  	"context"
     6  	"fmt"
     7  
     8  	"net/netip"
     9  
    10  	"github.com/MakeNowJust/heredoc/v2"
    11  	"github.com/bepass-org/wireguard-go/conn"
    12  	"github.com/bepass-org/wireguard-go/device"
    13  	"github.com/bepass-org/wireguard-go/tun/netstack"
    14  )
    15  
    16  // DeviceSetting contains the parameters for setting up a tun interface
    17  type DeviceSetting struct {
    18  	ipcRequest string
    19  	dns        []netip.Addr
    20  	deviceAddr []netip.Addr
    21  	mtu        int
    22  }
    23  
    24  // serialize the config into an IPC request and DeviceSetting
    25  func createIPCRequest(conf *DeviceConfig) (*DeviceSetting, error) {
    26  	var request bytes.Buffer
    27  
    28  	request.WriteString(fmt.Sprintf("private_key=%s\n", conf.SecretKey))
    29  
    30  	if conf.ListenPort != nil {
    31  		request.WriteString(fmt.Sprintf("listen_port=%d\n", *conf.ListenPort))
    32  	}
    33  
    34  	for _, peer := range conf.Peers {
    35  		request.WriteString(fmt.Sprintf(heredoc.Doc(`
    36  				public_key=%s
    37  				persistent_keepalive_interval=%d
    38  				preshared_key=%s
    39  			`),
    40  			peer.PublicKey, 1, peer.PreSharedKey,
    41  		))
    42  		if peer.Endpoint != nil {
    43  			request.WriteString(fmt.Sprintf("endpoint=%s\n", *peer.Endpoint))
    44  		}
    45  
    46  		if len(peer.AllowedIPs) > 0 {
    47  			for _, ip := range peer.AllowedIPs {
    48  				request.WriteString(fmt.Sprintf("allowed_ip=%s\n", ip.String()))
    49  			}
    50  		} else {
    51  			request.WriteString(heredoc.Doc(`
    52  				allowed_ip=0.0.0.0/0
    53  				allowed_ip=::0/0
    54  			`))
    55  		}
    56  	}
    57  
    58  	setting := &DeviceSetting{ipcRequest: request.String(), dns: conf.DNS, deviceAddr: conf.Endpoint, mtu: conf.MTU}
    59  	return setting, nil
    60  }
    61  
    62  // StartWireguard creates a tun interface on netstack given a configuration
    63  func StartWireguard(ctx context.Context, conf *DeviceConfig, verbose bool) (*VirtualTun, error) {
    64  	setting, err := createIPCRequest(conf)
    65  	if err != nil {
    66  		return nil, err
    67  	}
    68  
    69  	tun, tnet, err := netstack.CreateNetTUN(setting.deviceAddr, setting.dns, setting.mtu)
    70  	if err != nil {
    71  		return nil, err
    72  	}
    73  
    74  	logLevel := device.LogLevelVerbose
    75  	if !verbose {
    76  		logLevel = device.LogLevelSilent
    77  	}
    78  
    79  	dev := device.NewDevice(tun, conn.NewDefaultBind(), device.NewLogger(logLevel, ""), conf.Trick)
    80  	err = dev.IpcSet(setting.ipcRequest)
    81  	if err != nil {
    82  		return nil, err
    83  	}
    84  
    85  	err = dev.Up()
    86  	if err != nil {
    87  		return nil, err
    88  	}
    89  
    90  	return &VirtualTun{
    91  		Tnet:      tnet,
    92  		SystemDNS: len(setting.dns) == 0,
    93  		Verbose:   verbose,
    94  		Logger: DefaultLogger{
    95  			verbose: verbose,
    96  		},
    97  		Dev: dev,
    98  		Ctx: ctx,
    99  	}, nil
   100  }