github.com/GFW-knocker/wireguard@v1.0.1/ipc/uapi_unix.go (about)

     1  //go:build linux || darwin || freebsd || openbsd
     2  
     3  /* SPDX-License-Identifier: MIT
     4   *
     5   * Copyright (C) 2017-2023 WireGuard LLC. All Rights Reserved.
     6   */
     7  
     8  package ipc
     9  
    10  import (
    11  	"errors"
    12  	"fmt"
    13  	"net"
    14  	"os"
    15  
    16  	"golang.org/x/sys/unix"
    17  )
    18  
    19  const (
    20  	IpcErrorIO        = -int64(unix.EIO)
    21  	IpcErrorProtocol  = -int64(unix.EPROTO)
    22  	IpcErrorInvalid   = -int64(unix.EINVAL)
    23  	IpcErrorPortInUse = -int64(unix.EADDRINUSE)
    24  	IpcErrorUnknown   = -55 // ENOANO
    25  )
    26  
    27  // socketDirectory is variable because it is modified by a linker
    28  // flag in wireguard-android.
    29  var socketDirectory = "/var/run/wireguard"
    30  
    31  func sockPath(iface string) string {
    32  	return fmt.Sprintf("%s/%s.sock", socketDirectory, iface)
    33  }
    34  
    35  func UAPIOpen(name string) (*os.File, error) {
    36  	if err := os.MkdirAll(socketDirectory, 0o755); err != nil {
    37  		return nil, err
    38  	}
    39  
    40  	socketPath := sockPath(name)
    41  	addr, err := net.ResolveUnixAddr("unix", socketPath)
    42  	if err != nil {
    43  		return nil, err
    44  	}
    45  
    46  	oldUmask := unix.Umask(0o077)
    47  	defer unix.Umask(oldUmask)
    48  
    49  	listener, err := net.ListenUnix("unix", addr)
    50  	if err == nil {
    51  		return listener.File()
    52  	}
    53  
    54  	// Test socket, if not in use cleanup and try again.
    55  	if _, err := net.Dial("unix", socketPath); err == nil {
    56  		return nil, errors.New("unix socket in use")
    57  	}
    58  	if err := os.Remove(socketPath); err != nil {
    59  		return nil, err
    60  	}
    61  	listener, err = net.ListenUnix("unix", addr)
    62  	if err != nil {
    63  		return nil, err
    64  	}
    65  	return listener.File()
    66  }