github.com/GFW-knocker/wireguard@v1.0.1/ipc/uapi_windows.go (about) 1 /* SPDX-License-Identifier: MIT 2 * 3 * Copyright (C) 2017-2023 WireGuard LLC. All Rights Reserved. 4 */ 5 6 package ipc 7 8 import ( 9 "net" 10 11 "github.com/GFW-knocker/wireguard/ipc/namedpipe" 12 "golang.org/x/sys/windows" 13 ) 14 15 // TODO: replace these with actual standard windows error numbers from the win package 16 const ( 17 IpcErrorIO = -int64(5) 18 IpcErrorProtocol = -int64(71) 19 IpcErrorInvalid = -int64(22) 20 IpcErrorPortInUse = -int64(98) 21 IpcErrorUnknown = -int64(55) 22 ) 23 24 type UAPIListener struct { 25 listener net.Listener // unix socket listener 26 connNew chan net.Conn 27 connErr chan error 28 kqueueFd int 29 keventFd int 30 } 31 32 func (l *UAPIListener) Accept() (net.Conn, error) { 33 for { 34 select { 35 case conn := <-l.connNew: 36 return conn, nil 37 38 case err := <-l.connErr: 39 return nil, err 40 } 41 } 42 } 43 44 func (l *UAPIListener) Close() error { 45 return l.listener.Close() 46 } 47 48 func (l *UAPIListener) Addr() net.Addr { 49 return l.listener.Addr() 50 } 51 52 var UAPISecurityDescriptor *windows.SECURITY_DESCRIPTOR 53 54 func init() { 55 var err error 56 UAPISecurityDescriptor, err = windows.SecurityDescriptorFromString("O:SYD:P(A;;GA;;;SY)(A;;GA;;;BA)S:(ML;;NWNRNX;;;HI)") 57 if err != nil { 58 panic(err) 59 } 60 } 61 62 func UAPIListen(name string) (net.Listener, error) { 63 listener, err := (&namedpipe.ListenConfig{ 64 SecurityDescriptor: UAPISecurityDescriptor, 65 }).Listen(`\\.\pipe\ProtectedPrefix\Administrators\WireGuard\` + name) 66 if err != nil { 67 return nil, err 68 } 69 70 uapi := &UAPIListener{ 71 listener: listener, 72 connNew: make(chan net.Conn, 1), 73 connErr: make(chan error, 1), 74 } 75 76 go func(l *UAPIListener) { 77 for { 78 conn, err := l.listener.Accept() 79 if err != nil { 80 l.connErr <- err 81 break 82 } 83 l.connNew <- conn 84 } 85 }(uapi) 86 87 return uapi, nil 88 }