github.com/sagernet/wireguard-go@v0.0.0-20231215174105-89dec3b2f3e8/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 }