uapi_unix.go raw
1 //go:build linux || darwin || freebsd || openbsd
2
3 /* SPDX-License-Identifier: MIT
4 *
5 * Copyright (C) 2017-2025 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 }
67