github.com/bugfan/wireguard-go@v0.0.0-20230720020150-a7b2fa340c66/ipc/uapi_windows.go (about)

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