protocol

package
v0.0.0-...-d30a6d4 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 24, 2020 License: BSD-3-Clause Imports: 9 Imported by: 24

Documentation

Index

Constants

View Source
const (
	MSIZE   = 2*1048576 + IOHDRSZ // default message size (1048576+IOHdrSz)
	IOHDRSZ = 24                  // the non-data size of the Twrite messages
	PORT    = 564                 // default port for 9P file servers
	NumFID  = 1 << 16
	QIDLen  = 13
)
View Source
const (
	QTDIR     = 0x80 // directories
	QTAPPEND  = 0x40 // append only files
	QTEXCL    = 0x20 // exclusive use files
	QTMOUNT   = 0x10 // mounted channel
	QTAUTH    = 0x08 // authentication file
	QTTMP     = 0x04 // non-backed-up file
	QTSYMLINK = 0x02 // symbolic link (Unix, 9P2000.u)
	QTLINK    = 0x01 // hard link (Unix, 9P2000.u)
	QTFILE    = 0x00
)

QID types

View Source
const (
	OREAD   = 0x0    // open read-only
	OWRITE  = 0x1    // open write-only
	ORDWR   = 0x2    // open read-write
	OEXEC   = 0x3    // execute (== read but check execute permission)
	OTRUNC  = 0x10   // or'ed in (except for exec), truncate file first
	OCEXEC  = 0x20   // or'ed in, close on exec
	ORCLOSE = 0x40   // or'ed in, remove on close
	OAPPEND = 0x80   // or'ed in, append only
	OEXCL   = 0x1000 // or'ed in, exclusive client use
)

Flags for the mode field in Topen and Tcreate messages

View Source
const (
	DMDIR    = 0x80000000 // mode bit for directories
	DMAPPEND = 0x40000000 // mode bit for append only files
	DMEXCL   = 0x20000000 // mode bit for exclusive use files
	DMMOUNT  = 0x10000000 // mode bit for mounted channel
	DMAUTH   = 0x08000000 // mode bit for authentication file
	DMTMP    = 0x04000000 // mode bit for non-backed-up file
	DMREAD   = 0x4        // mode bit for read permission
	DMWRITE  = 0x2        // mode bit for write permission
	DMEXEC   = 0x1        // mode bit for execute permission
)

File modes

View Source
const (
	NOTAG Tag = 0xFFFF     // no tag specified
	NOFID FID = 0xFFFFFFFF // no fid specified
	// We reserve tag NOTAG and tag 0. 0 is a troublesome value to pass
	// around, since it is also a default value and using it can hide errors
	// in the code.
	NumTags = 1<<16 - 2
)
View Source
const (
	EPERM   = 1
	ENOENT  = 2
	EIO     = 5
	EACCES  = 13
	EEXIST  = 17
	ENOTDIR = 20
	EINVAL  = 22
)

Error values

View Source
const DefaultAddr = ":5640"

Variables

View Source
var (
	RPCNames = map[MType]string{
		Tversion: "Tversion",
		Rversion: "Rversion",
		Tauth:    "Tauth",
		Rauth:    "Rauth",
		Tattach:  "Tattach",
		Rattach:  "Rattach",
		Terror:   "Terror",
		Rerror:   "Rerror",
		Tflush:   "Tflush",
		Rflush:   "Rflush",
		Twalk:    "Twalk",
		Rwalk:    "Rwalk",
		Topen:    "Topen",
		Ropen:    "Ropen",
		Tcreate:  "Tcreate",
		Rcreate:  "Rcreate",
		Tread:    "Tread",
		Rread:    "Rread",
		Twrite:   "Twrite",
		Rwrite:   "Rwrite",
		Tclunk:   "Tclunk",
		Rclunk:   "Rclunk",
		Tremove:  "Tremove",
		Rremove:  "Rremove",
		Tstat:    "Tstat",
		Rstat:    "Rstat",
		Twstat:   "Twstat",
		Rwstat:   "Rwstat",
	}
)

Functions

func Dispatch

func Dispatch(s *Server, b *bytes.Buffer, t MType) error

Dispatch dispatches request to different functions. It's also the the first place we try to establish server semantics. We could do this with interface assertions and such a la rsc/fuse but most people I talked do disliked that. So we don't. If you want to make things optional, just define the ones you want to implement in this case.

func MarshalRattachPkt

func MarshalRattachPkt(b *bytes.Buffer, t Tag, QID QID)

func MarshalRclunkPkt

func MarshalRclunkPkt(b *bytes.Buffer, t Tag)

func MarshalRcreatePkt

func MarshalRcreatePkt(b *bytes.Buffer, t Tag, OQID QID, IOUnit MaxSize)

func MarshalRerrorPkt

func MarshalRerrorPkt(b *bytes.Buffer, t Tag, Error string)

func MarshalRflushPkt

func MarshalRflushPkt(b *bytes.Buffer, t Tag)

func MarshalRopenPkt

func MarshalRopenPkt(b *bytes.Buffer, t Tag, OQID QID, IOUnit MaxSize)

func MarshalRreadPkt

func MarshalRreadPkt(b *bytes.Buffer, t Tag, Data []uint8)

func MarshalRremovePkt

func MarshalRremovePkt(b *bytes.Buffer, t Tag)

func MarshalRstatPkt

func MarshalRstatPkt(b *bytes.Buffer, t Tag, B []byte)

func MarshalRversionPkt

func MarshalRversionPkt(b *bytes.Buffer, t Tag, RMsize MaxSize, RVersion string)

func MarshalRwalkPkt

func MarshalRwalkPkt(b *bytes.Buffer, t Tag, QIDs []QID)

func MarshalRwritePkt

func MarshalRwritePkt(b *bytes.Buffer, t Tag, RLen Count)

func MarshalRwstatPkt

func MarshalRwstatPkt(b *bytes.Buffer, t Tag)

func MarshalTattachPkt

func MarshalTattachPkt(b *bytes.Buffer, t Tag, SFID FID, AFID FID, Uname string, Aname string)

func MarshalTclunkPkt

func MarshalTclunkPkt(b *bytes.Buffer, t Tag, OFID FID)

func MarshalTcreatePkt

func MarshalTcreatePkt(b *bytes.Buffer, t Tag, OFID FID, Name string, CreatePerm Perm, Omode Mode)

func MarshalTflushPkt

func MarshalTflushPkt(b *bytes.Buffer, t Tag, OTag Tag)

func MarshalTopenPkt

func MarshalTopenPkt(b *bytes.Buffer, t Tag, OFID FID, Omode Mode)

func MarshalTreadPkt

func MarshalTreadPkt(b *bytes.Buffer, t Tag, OFID FID, Off Offset, Len Count)

func MarshalTremovePkt

func MarshalTremovePkt(b *bytes.Buffer, t Tag, OFID FID)

func MarshalTstatPkt

func MarshalTstatPkt(b *bytes.Buffer, t Tag, OFID FID)

func MarshalTversionPkt

func MarshalTversionPkt(b *bytes.Buffer, t Tag, TMsize MaxSize, TVersion string)

func MarshalTwalkPkt

func MarshalTwalkPkt(b *bytes.Buffer, t Tag, SFID FID, NewFID FID, Paths []string)

func MarshalTwritePkt

func MarshalTwritePkt(b *bytes.Buffer, t Tag, OFID FID, Off Offset, Data []uint8)

func MarshalTwstatPkt

func MarshalTwstatPkt(b *bytes.Buffer, t Tag, OFID FID, B []byte)

func Marshaldir

func Marshaldir(b *bytes.Buffer, D Dir)

func ServerError

func ServerError(b *bytes.Buffer, s string)

func UnmarshalRattachPkt

func UnmarshalRattachPkt(b *bytes.Buffer) (QID QID, t Tag, err error)

func UnmarshalRcreatePkt

func UnmarshalRcreatePkt(b *bytes.Buffer) (OQID QID, IOUnit MaxSize, t Tag, err error)

func UnmarshalRopenPkt

func UnmarshalRopenPkt(b *bytes.Buffer) (OQID QID, IOUnit MaxSize, t Tag, err error)

func UnmarshalRversionPkt

func UnmarshalRversionPkt(b *bytes.Buffer) (RMsize MaxSize, RVersion string, t Tag, err error)

func UnmarshalRwalkPkt

func UnmarshalRwalkPkt(b *bytes.Buffer) (QIDs []QID, t Tag, err error)

func UnmarshalRwritePkt

func UnmarshalRwritePkt(b *bytes.Buffer) (RLen Count, t Tag, err error)

func UnmarshalTattachPkt

func UnmarshalTattachPkt(b *bytes.Buffer) (SFID FID, AFID FID, Uname string, Aname string, t Tag, err error)

func UnmarshalTclunkPkt

func UnmarshalTclunkPkt(b *bytes.Buffer) (OFID FID, t Tag, err error)

func UnmarshalTcreatePkt

func UnmarshalTcreatePkt(b *bytes.Buffer) (OFID FID, Name string, CreatePerm Perm, Omode Mode, t Tag, err error)

func UnmarshalTflushPkt

func UnmarshalTflushPkt(b *bytes.Buffer) (OTag Tag, t Tag, err error)

func UnmarshalTopenPkt

func UnmarshalTopenPkt(b *bytes.Buffer) (OFID FID, Omode Mode, t Tag, err error)

func UnmarshalTreadPkt

func UnmarshalTreadPkt(b *bytes.Buffer) (OFID FID, Off Offset, Len Count, t Tag, err error)

func UnmarshalTremovePkt

func UnmarshalTremovePkt(b *bytes.Buffer) (OFID FID, t Tag, err error)

func UnmarshalTstatPkt

func UnmarshalTstatPkt(b *bytes.Buffer) (OFID FID, t Tag, err error)

func UnmarshalTversionPkt

func UnmarshalTversionPkt(b *bytes.Buffer) (TMsize MaxSize, TVersion string, t Tag, err error)

func UnmarshalTwalkPkt

func UnmarshalTwalkPkt(b *bytes.Buffer) (SFID FID, NewFID FID, Paths []string, t Tag, err error)

func UnmarshalTwritePkt

func UnmarshalTwritePkt(b *bytes.Buffer) (OFID FID, Off Offset, Data []uint8, t Tag, err error)

func UnmarshalTwstatPkt

func UnmarshalTwstatPkt(b *bytes.Buffer) (OFID FID, B []byte, t Tag, err error)

Types

type Client

type Client struct {
	Tags       chan Tag
	FID        uint64
	RPC        []*RPCCall
	ToNet      io.WriteCloser
	FromNet    io.ReadCloser
	FromClient chan *RPCCall
	FromServer chan *RPCReply
	Msize      uint32
	Dead       bool
	Trace      Tracer
}

Client implements a 9p client. It has a chan containing all tags, a scalar FID which is incremented to provide new FIDS (all FIDS for a given client are unique), an array of MaxTag-2 RPC structs, a ReadWriteCloser for IO, and two channels for a server goroutine: one down which RPCalls are pushed and another from which RPCReplys return. Once a client is marked Dead all further requests to it will fail. The ToNet/FromNet are separate so we can use io.Pipe for testing.

func NewClient

func NewClient(opts ...ClientOpt) (*Client, error)

func (*Client) CallTattach

func (c *Client) CallTattach(SFID FID, AFID FID, Uname string, Aname string) (QID QID, err error)

func (*Client) CallTclunk

func (c *Client) CallTclunk(OFID FID) (err error)

func (*Client) CallTcreate

func (c *Client) CallTcreate(OFID FID, Name string, CreatePerm Perm, Omode Mode) (OQID QID, IOUnit MaxSize, err error)

func (*Client) CallTflush

func (c *Client) CallTflush(OTag Tag) (err error)

func (*Client) CallTopen

func (c *Client) CallTopen(OFID FID, Omode Mode) (OQID QID, IOUnit MaxSize, err error)

func (*Client) CallTread

func (c *Client) CallTread(OFID FID, Off Offset, Len Count) (Data []uint8, err error)

func (*Client) CallTremove

func (c *Client) CallTremove(OFID FID) (err error)

func (*Client) CallTstat

func (c *Client) CallTstat(OFID FID) (B []byte, err error)

func (*Client) CallTversion

func (c *Client) CallTversion(TMsize MaxSize, TVersion string) (RMsize MaxSize, RVersion string, err error)

func (*Client) CallTwalk

func (c *Client) CallTwalk(SFID FID, NewFID FID, Paths []string) (QIDs []QID, err error)

func (*Client) CallTwrite

func (c *Client) CallTwrite(OFID FID, Off Offset, Data []uint8) (RLen Count, err error)

func (*Client) CallTwstat

func (c *Client) CallTwstat(OFID FID, B []byte) (err error)

func (*Client) GetFID

func (c *Client) GetFID() FID

GetFID gets a fid to be used to identify a resource for a 9p client. For a given lifetime of a 9p client, FIDS are unique (i.e. not reused as in many 9p client libraries).

func (*Client) GetTag

func (c *Client) GetTag() Tag

GetTag gets a tag to be used to identify a message.

func (*Client) IO

func (c *Client) IO()

func (*Client) String

func (c *Client) String() string

type ClientOpt

type ClientOpt func(*Client) error

rpc servers

type Count

type Count int32

Types contained in 9p messages.

type Data

type Data []byte

Types contained in 9p messages.

type DataCnt16

type DataCnt16 byte // []byte with a 16-bit count.

Some []byte fields are encoded with a 16-bit length, e.g. stat data. We use this type to tag such fields. The parameters are still []byte, this was just the only way I could think of to make the stub generator do the right thing.

type Dir

type Dir struct {
	Type    uint16
	Dev     uint32
	QID     QID    // file's QID
	Mode    uint32 // permissions and flags
	Atime   uint32 // last access time in seconds
	Mtime   uint32 // last modified time in seconds
	Length  uint64 // file length in bytes
	Name    string // file name
	User    string // owner name
	Group   string // group name
	ModUser string // name of the last user that modified the file
}

Dir describes a file

func Unmarshaldir

func Unmarshaldir(b *bytes.Buffer) (D Dir, err error)

type DirPkt

type DirPkt struct {
	D Dir
}

type Dispatcher

type Dispatcher func(s *Server, b *bytes.Buffer, t MType) error

type Error

type Error struct {
	Err string
}

Error represents a 9P2000 error

type FID

type FID uint32

Types contained in 9p messages.

type File

type File struct {
}

A File is defined by a QID. File Servers never see a FID. There are two channels. The first is for normal requests. The second is for Flushes. File server code always checks the flush channel first. At the same time, server code puts the flush into both channels, so the server code has some idea when the flush entered the queue. This is very similar to how MSI-X works on PCIe ...

type FileServer

type FileServer struct {
	Server
	Versioned bool
}

Server maintains file system server state. This is inclusive of RPC server state plus more. In our case when we walk to a fid we kick off a goroutine to manage it. As a result we need a map of Tag to FID so we know what to do about Tflush.

type Listener

type Listener struct {

	// TCP address to listen on, default is DefaultAddr
	Addr string

	// Trace function for logging
	Trace Tracer
	// contains filtered or unexported fields
}

func NewListener

func NewListener(nsCreator NsCreator, opts ...ListenerOpt) (*Listener, error)

func (*Listener) Accept

func (l *Listener) Accept(conn net.Conn) error

Accept a new connection, typically called via Serve but may be called directly if there's a connection from an exotic listener.

func (*Listener) Serve

func (l *Listener) Serve(ln net.Listener) error

Serve accepts incoming connections on the Listener and calls e.Accept on each connection.

func (*Listener) Shutdown

func (l *Listener) Shutdown() error

Shutdown closes all active listeners. It does not close all active connections but probably should.

func (*Listener) String

func (l *Listener) String() string

type ListenerOpt

type ListenerOpt func(*Listener) error

type MType

type MType uint8

Types contained in 9p messages.

const (
	Tversion MType = 100 + iota
	Rversion
	Tauth
	Rauth
	Tattach
	Rattach
	Terror
	Rerror
	Tflush
	Rflush
	Twalk
	Rwalk
	Topen
	Ropen
	Tcreate
	Rcreate
	Tread
	Rread
	Twrite
	Rwrite
	Tclunk
	Rclunk
	Tremove
	Rremove
	Tstat
	Rstat
	Twstat
	Rwstat
	Tlast
)

9P2000 message types

type MaxSize

type MaxSize uint32

Types contained in 9p messages.

type Mode

type Mode uint8

Types contained in 9p messages.

type NineServer

type NineServer interface {
	Rversion(MaxSize, string) (MaxSize, string, error)
	Rattach(FID, FID, string, string) (QID, error)
	Rwalk(FID, FID, []string) ([]QID, error)
	Ropen(FID, Mode) (QID, MaxSize, error)
	Rcreate(FID, string, Perm, Mode) (QID, MaxSize, error)
	Rstat(FID) ([]byte, error)
	Rwstat(FID, []byte) error
	Rclunk(FID) error
	Rremove(FID) error
	Rread(FID, Offset, Count) ([]byte, error)
	Rwrite(FID, Offset, []byte) (Count, error)
	Rflush(Otag Tag) error
}

type NsCreator

type NsCreator func() NineServer

type NumEntries

type NumEntries uint16

Types contained in 9p messages.

type Offset

type Offset uint64

Types contained in 9p messages.

type Perm

type Perm uint32

Types contained in 9p messages.

type QID

type QID struct {
	Type    uint8  // type of the file (high 8 bits of the mode)
	Version uint32 // version number for the path
	Path    uint64 // server's unique identification of the file
}

File identifier

type RPCCall

type RPCCall struct {
	Reply chan []byte
	// contains filtered or unexported fields
}

type RPCReply

type RPCReply struct {
	// contains filtered or unexported fields
}

type RattachPkt

type RattachPkt struct {
	QID QID
}

type RclunkPkt

type RclunkPkt struct {
}

type RcreatePkt

type RcreatePkt struct {
	OQID   QID
	IOUnit MaxSize
}

type RerrorPkt

type RerrorPkt struct {
	Error string
}

type RflushPkt

type RflushPkt struct {
}

type RopenPkt

type RopenPkt struct {
	OQID   QID
	IOUnit MaxSize
}

type RreadPkt

type RreadPkt struct {
	Data []byte
}

type RremovePkt

type RremovePkt struct {
}

type RstatPkt

type RstatPkt struct {
	B []DataCnt16
}

type RversionPkt

type RversionPkt struct {
	RMsize   MaxSize
	RVersion string
}

type RwalkPkt

type RwalkPkt struct {
	QIDs []QID
}

type RwritePkt

type RwritePkt struct {
	RLen Count
}

type RwstatPkt

type RwstatPkt struct {
}

type Server

type Server struct {
	NS NineServer
	D  Dispatcher

	// Versioned is set to true on the first call to Tversion
	Versioned bool
}

Server is a 9p server. For now it's extremely serial. But we will use a chan for replies to ensure that we can go to a more concurrent one later.

func (*Server) SrvRattach

func (s *Server) SrvRattach(b *bytes.Buffer) (err error)

func (*Server) SrvRclunk

func (s *Server) SrvRclunk(b *bytes.Buffer) (err error)

func (*Server) SrvRcreate

func (s *Server) SrvRcreate(b *bytes.Buffer) (err error)

func (*Server) SrvRflush

func (s *Server) SrvRflush(b *bytes.Buffer) (err error)

func (*Server) SrvRopen

func (s *Server) SrvRopen(b *bytes.Buffer) (err error)

func (*Server) SrvRread

func (s *Server) SrvRread(b *bytes.Buffer) (err error)

func (*Server) SrvRremove

func (s *Server) SrvRremove(b *bytes.Buffer) (err error)

func (*Server) SrvRstat

func (s *Server) SrvRstat(b *bytes.Buffer) (err error)

func (*Server) SrvRversion

func (s *Server) SrvRversion(b *bytes.Buffer) (err error)

func (*Server) SrvRwalk

func (s *Server) SrvRwalk(b *bytes.Buffer) (err error)

func (*Server) SrvRwrite

func (s *Server) SrvRwrite(b *bytes.Buffer) (err error)

func (*Server) SrvRwstat

func (s *Server) SrvRwstat(b *bytes.Buffer) (err error)

type Service

type Service func(func() error, chan FID)

A service is a closure which returns an error or nil. It writes its result down the provided channel. It looks for flushes on the flushchan before doing its function, and will respond to all flushes while any are pending.

type Tag

type Tag uint16

Types contained in 9p messages.

func UnmarshalRclunkPkt

func UnmarshalRclunkPkt(b *bytes.Buffer) (t Tag, err error)

func UnmarshalRerrorPkt

func UnmarshalRerrorPkt(b *bytes.Buffer) (Error string, t Tag, err error)

func UnmarshalRflushPkt

func UnmarshalRflushPkt(b *bytes.Buffer) (t Tag, err error)

func UnmarshalRreadPkt

func UnmarshalRreadPkt(b *bytes.Buffer) (Data []uint8, t Tag, err error)

func UnmarshalRremovePkt

func UnmarshalRremovePkt(b *bytes.Buffer) (t Tag, err error)

func UnmarshalRstatPkt

func UnmarshalRstatPkt(b *bytes.Buffer) (B []byte, t Tag, err error)

func UnmarshalRwstatPkt

func UnmarshalRwstatPkt(b *bytes.Buffer) (t Tag, err error)

type TattachPkt

type TattachPkt struct {
	SFID  FID
	AFID  FID
	Uname string
	Aname string
}

type TclunkPkt

type TclunkPkt struct {
	OFID FID
}

type TcreatePkt

type TcreatePkt struct {
	OFID       FID
	Name       string
	CreatePerm Perm
	Omode      Mode
}

type TflushPkt

type TflushPkt struct {
	OTag Tag
}

type TopenPkt

type TopenPkt struct {
	OFID  FID
	Omode Mode
}

type Tracer

type Tracer func(string, ...interface{})

type TreadPkt

type TreadPkt struct {
	OFID FID
	Off  Offset
	Len  Count
}

type TremovePkt

type TremovePkt struct {
	OFID FID
}

type TstatPkt

type TstatPkt struct {
	OFID FID
}

type TversionPkt

type TversionPkt struct {
	TMsize   MaxSize
	TVersion string
}

type TwalkPkt

type TwalkPkt struct {
	SFID   FID
	NewFID FID
	Paths  []string
}

type TwritePkt

type TwritePkt struct {
	OFID FID
	Off  Offset
	Data []byte
}

type TwstatPkt

type TwstatPkt struct {
	OFID FID
	B    []DataCnt16
}

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL