mirror of https://github.com/tailscale/tailscale/
safesocket, paths: add Plan 9 support
Updates #5794 Change-Id: I69150ec18d101f55baabb38613512cde858447cb Co-authored-by: Brad Fitzpatrick <bradfitz@tailscale.com> Signed-off-by: Skip Tavakkolian <skip.tavakkolian@gmail.com>pull/9271/head
parent
51d3220153
commit
6fd1961cd7
@ -0,0 +1,124 @@
|
||||
// Copyright (c) Tailscale Inc & AUTHORS
|
||||
// SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
//go:build plan9
|
||||
|
||||
package safesocket
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net"
|
||||
"os"
|
||||
"syscall"
|
||||
"time"
|
||||
|
||||
"golang.org/x/sys/plan9"
|
||||
)
|
||||
|
||||
// Plan 9's devsrv srv(3) is a server registry and
|
||||
// it is conventionally bound to "/srv" in the default
|
||||
// namespace. It is "a one level directory for holding
|
||||
// already open channels to services". Post one end of
|
||||
// a pipe to "/srv/tailscale.sock" and use the other
|
||||
// end for communication with a requestor. Plan 9 pipes
|
||||
// are bidirectional.
|
||||
|
||||
type plan9SrvAddr string
|
||||
|
||||
func (sl plan9SrvAddr) Network() string {
|
||||
return "/srv"
|
||||
}
|
||||
|
||||
func (sl plan9SrvAddr) String() string {
|
||||
return string(sl)
|
||||
}
|
||||
|
||||
// There is no net.FileListener for Plan 9 at this time
|
||||
type plan9SrvListener struct {
|
||||
name string
|
||||
srvf *os.File
|
||||
file *os.File
|
||||
}
|
||||
|
||||
func (sl *plan9SrvListener) Accept() (net.Conn, error) {
|
||||
// sl.file is the server end of the pipe that's
|
||||
// connected to /srv/tailscale.sock
|
||||
return plan9FileConn{name: sl.name, file: sl.file}, nil
|
||||
}
|
||||
|
||||
func (sl *plan9SrvListener) Close() error {
|
||||
sl.file.Close()
|
||||
return sl.srvf.Close()
|
||||
}
|
||||
|
||||
func (sl *plan9SrvListener) Addr() net.Addr {
|
||||
return plan9SrvAddr(sl.name)
|
||||
}
|
||||
|
||||
type plan9FileConn struct {
|
||||
name string
|
||||
file *os.File
|
||||
}
|
||||
|
||||
func (fc plan9FileConn) Read(b []byte) (n int, err error) {
|
||||
return fc.file.Read(b)
|
||||
}
|
||||
func (fc plan9FileConn) Write(b []byte) (n int, err error) {
|
||||
return fc.file.Write(b)
|
||||
}
|
||||
func (fc plan9FileConn) Close() error {
|
||||
return fc.file.Close()
|
||||
}
|
||||
func (fc plan9FileConn) LocalAddr() net.Addr {
|
||||
return plan9SrvAddr(fc.name)
|
||||
}
|
||||
func (fc plan9FileConn) RemoteAddr() net.Addr {
|
||||
return plan9SrvAddr(fc.name)
|
||||
}
|
||||
func (fc plan9FileConn) SetDeadline(t time.Time) error {
|
||||
return syscall.EPLAN9
|
||||
}
|
||||
func (fc plan9FileConn) SetReadDeadline(t time.Time) error {
|
||||
return syscall.EPLAN9
|
||||
}
|
||||
func (fc plan9FileConn) SetWriteDeadline(t time.Time) error {
|
||||
return syscall.EPLAN9
|
||||
}
|
||||
|
||||
func connect(s *ConnectionStrategy) (net.Conn, error) {
|
||||
f, err := os.OpenFile(s.path, os.O_RDWR, 0666)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return plan9FileConn{name: s.path, file: f}, nil
|
||||
}
|
||||
|
||||
// Create an entry in /srv, open a pipe, write the
|
||||
// client end to the entry and return the server
|
||||
// end of the pipe to the caller. When the server
|
||||
// end of the pipe is closed, /srv name associated
|
||||
// with it will be removed (controlled by ORCLOSE flag)
|
||||
func listen(path string) (net.Listener, error) {
|
||||
const O_RCLOSE = 64 // remove on close; should be in plan9 package
|
||||
var pip [2]int
|
||||
|
||||
err := plan9.Pipe(pip[:])
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer plan9.Close(pip[1])
|
||||
|
||||
srvfd, err := plan9.Create(path, plan9.O_WRONLY|plan9.O_CLOEXEC|O_RCLOSE, 0600)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
srv := os.NewFile(uintptr(srvfd), path)
|
||||
|
||||
_, err = fmt.Fprintf(srv, "%d", pip[1])
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &plan9SrvListener{name: path, srvf: srv, file: os.NewFile(uintptr(pip[0]), path)}, nil
|
||||
}
|
Loading…
Reference in New Issue