Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add sunos support #39

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
111 changes: 111 additions & 0 deletions ipc/uapi_solaris.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
/* SPDX-License-Identifier: MIT
*
* Copyright (C) 2017-2023 WireGuard LLC. All Rights Reserved.
*/

package ipc

import (
"net"
"os"

"golang.org/x/sys/unix"
)

type UAPIListener struct {
listener net.Listener // unix socket listener
connNew chan net.Conn
connErr chan error
evPort *unix.EventPort
}

func (l *UAPIListener) Accept() (net.Conn, error) {
for {
select {
case conn := <-l.connNew:
return conn, nil

case err := <-l.connErr:
return nil, err
}
}
}

func (l *UAPIListener) Close() error {
err1 := l.evPort.Close()
err2 := l.listener.Close()
if err1 != nil {
return err1
}
return err2
}

func (l *UAPIListener) Addr() net.Addr {
return l.listener.Addr()
}

func UAPIListen(name string, file *os.File) (net.Listener, error) {
listener, err := net.FileListener(file)
if err != nil {
return nil, err
}

uapi := &UAPIListener{
listener: listener,
connNew: make(chan net.Conn, 1),
connErr: make(chan error, 1),
}

if unixListener, ok := listener.(*net.UnixListener); ok {
unixListener.SetUnlinkOnClose(true)
}

socketPath := sockPath(name)

uapi.evPort, err = unix.NewEventPort()
if err != nil {
return nil, err
}
stat, err := os.Lstat(socketPath)
if err != nil {
return nil, err
}
err = uapi.evPort.AssociatePath(socketPath, stat, unix.FILE_MODIFIED|unix.FILE_ATTRIB|unix.FILE_NOFOLLOW, nil)
if err != nil {
return nil, err
}

go func(l *UAPIListener) {
for {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you confirm that you've tested that this loop works as expected in a variety of circumstances?

// start with lstat to avoid race condition
if _, err := os.Lstat(socketPath); os.IsNotExist(err) {
l.connErr <- err
return
}
_, perr := l.evPort.GetOne(nil)
Copy link
Member

@zx2c4 zx2c4 Mar 13, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

_, err := l.evPort.GetOne(nil)

if perr == unix.EINTR {
// If we were interrupted, resume watching.
continue
}
if perr != nil {
l.connErr <- perr
return
}
}
}(uapi)

// watch for new connections

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No need for this new line.

go func(l *UAPIListener) {
for {
conn, err := l.listener.Accept()
if err != nil {
l.connErr <- err
break
}
l.connNew <- conn
}
}(uapi)

return uapi, nil
}
2 changes: 1 addition & 1 deletion ipc/uapi_unix.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
//go:build linux || darwin || freebsd || openbsd
//go:build linux || darwin || freebsd || openbsd || solaris || illumos

/* SPDX-License-Identifier: MIT
*
Expand Down