ninep: Index | Files

package protocol

import ""


Package Files

client.go genout.go protocol.go server.go types.go


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
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

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

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

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
const (
    EPERM   = 1
    ENOENT  = 2
    EIO     = 5
    EACCES  = 13
    EEXIST  = 17
    ENOTDIR = 20
    EINVAL  = 22

Error values

const DefaultAddr = ":5640"


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",

func Dispatch Uses

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 Uses

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

func MarshalRclunkPkt Uses

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

func MarshalRcreatePkt Uses

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

func MarshalRerrorPkt Uses

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

func MarshalRflushPkt Uses

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

func MarshalRopenPkt Uses

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

func MarshalRreadPkt Uses

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

func MarshalRremovePkt Uses

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

func MarshalRstatPkt Uses

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

func MarshalRversionPkt Uses

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

func MarshalRwalkPkt Uses

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

func MarshalRwritePkt Uses

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

func MarshalRwstatPkt Uses

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

func MarshalTattachPkt Uses

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

func MarshalTclunkPkt Uses

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

func MarshalTcreatePkt Uses

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

func MarshalTflushPkt Uses

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

func MarshalTopenPkt Uses

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

func MarshalTreadPkt Uses

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

func MarshalTremovePkt Uses

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

func MarshalTstatPkt Uses

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

func MarshalTversionPkt Uses

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

func MarshalTwalkPkt Uses

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

func MarshalTwritePkt Uses

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

func MarshalTwstatPkt Uses

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

func Marshaldir Uses

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

func ServerError Uses

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

func UnmarshalRattachPkt Uses

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

func UnmarshalRcreatePkt Uses

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

func UnmarshalRopenPkt Uses

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

func UnmarshalRversionPkt Uses

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

func UnmarshalRwalkPkt Uses

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

func UnmarshalRwritePkt Uses

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

func UnmarshalTattachPkt Uses

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

func UnmarshalTclunkPkt Uses

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

func UnmarshalTcreatePkt Uses

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

func UnmarshalTflushPkt Uses

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

func UnmarshalTopenPkt Uses

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

func UnmarshalTreadPkt Uses

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

func UnmarshalTremovePkt Uses

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

func UnmarshalTstatPkt Uses

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

func UnmarshalTversionPkt Uses

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

func UnmarshalTwalkPkt Uses

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

func UnmarshalTwritePkt Uses

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

func UnmarshalTwstatPkt Uses

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

type Client Uses

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 Uses

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

func (*Client) CallTattach Uses

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

func (*Client) CallTclunk Uses

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

func (*Client) CallTcreate Uses

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

func (*Client) CallTflush Uses

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

func (*Client) CallTopen Uses

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

func (*Client) CallTread Uses

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

func (*Client) CallTremove Uses

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

func (*Client) CallTstat Uses

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

func (*Client) CallTversion Uses

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

func (*Client) CallTwalk Uses

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

func (*Client) CallTwrite Uses

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

func (*Client) CallTwstat Uses

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

func (*Client) GetFID Uses

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 Uses

func (c *Client) GetTag() Tag

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

func (*Client) IO Uses

func (c *Client) IO()

func (*Client) String Uses

func (c *Client) String() string

type ClientOpt Uses

type ClientOpt func(*Client) error

rpc servers

type Count Uses

type Count int32

Types contained in 9p messages.

type Data Uses

type Data []byte

Types contained in 9p messages.

type DataCnt16 Uses

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 Uses

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 Uses

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

type DirPkt Uses

type DirPkt struct {
    D Dir

type Dispatcher Uses

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

type Error Uses

type Error struct {
    Err string

Error represents a 9P2000 error

type FID Uses

type FID uint32

Types contained in 9p messages.

type File Uses

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 Uses

type FileServer struct {
    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 Uses

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 Uses

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

func (*Listener) Accept Uses

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 Uses

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 Uses

func (l *Listener) Shutdown() error

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

func (*Listener) String Uses

func (l *Listener) String() string

type ListenerOpt Uses

type ListenerOpt func(*Listener) error

type MType Uses

type MType uint8

Types contained in 9p messages.

const (
    Tversion MType = 100 + iota

9P2000 message types

type MaxSize Uses

type MaxSize uint32

Types contained in 9p messages.

type Mode Uses

type Mode uint8

Types contained in 9p messages.

type NineServer Uses

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 Uses

type NsCreator func() NineServer

type NumEntries Uses

type NumEntries uint16

Types contained in 9p messages.

type Offset Uses

type Offset uint64

Types contained in 9p messages.

type Perm Uses

type Perm uint32

Types contained in 9p messages.

type QID Uses

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 Uses

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

type RPCReply Uses

type RPCReply struct {
    // contains filtered or unexported fields

type RattachPkt Uses

type RattachPkt struct {

type RclunkPkt Uses

type RclunkPkt struct {

type RcreatePkt Uses

type RcreatePkt struct {
    OQID   QID
    IOUnit MaxSize

type RerrorPkt Uses

type RerrorPkt struct {
    Error string

type RflushPkt Uses

type RflushPkt struct {

type RopenPkt Uses

type RopenPkt struct {
    OQID   QID
    IOUnit MaxSize

type RreadPkt Uses

type RreadPkt struct {
    Data []byte

type RremovePkt Uses

type RremovePkt struct {

type RstatPkt Uses

type RstatPkt struct {
    B []DataCnt16

type RversionPkt Uses

type RversionPkt struct {
    RMsize   MaxSize
    RVersion string

type RwalkPkt Uses

type RwalkPkt struct {
    QIDs []QID

type RwritePkt Uses

type RwritePkt struct {
    RLen Count

type RwstatPkt Uses

type RwstatPkt struct {

type Server Uses

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 Uses

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

func (*Server) SrvRclunk Uses

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

func (*Server) SrvRcreate Uses

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

func (*Server) SrvRflush Uses

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

func (*Server) SrvRopen Uses

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

func (*Server) SrvRread Uses

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

func (*Server) SrvRremove Uses

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

func (*Server) SrvRstat Uses

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

func (*Server) SrvRversion Uses

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

func (*Server) SrvRwalk Uses

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

func (*Server) SrvRwrite Uses

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

func (*Server) SrvRwstat Uses

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

type Service Uses

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 Uses

type Tag uint16

Types contained in 9p messages.

func UnmarshalRclunkPkt Uses

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

func UnmarshalRerrorPkt Uses

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

func UnmarshalRflushPkt Uses

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

func UnmarshalRreadPkt Uses

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

func UnmarshalRremovePkt Uses

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

func UnmarshalRstatPkt Uses

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

func UnmarshalRwstatPkt Uses

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

type TattachPkt Uses

type TattachPkt struct {
    Uname string
    Aname string

type TclunkPkt Uses

type TclunkPkt struct {

type TcreatePkt Uses

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

type TflushPkt Uses

type TflushPkt struct {
    OTag Tag

type TopenPkt Uses

type TopenPkt struct {
    Omode Mode

type Tracer Uses

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

type TreadPkt Uses

type TreadPkt struct {
    Off  Offset
    Len  Count

type TremovePkt Uses

type TremovePkt struct {

type TstatPkt Uses

type TstatPkt struct {

type TversionPkt Uses

type TversionPkt struct {
    TMsize   MaxSize
    TVersion string

type TwalkPkt Uses

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

type TwritePkt Uses

type TwritePkt struct {
    Off  Offset
    Data []byte

type TwstatPkt Uses

type TwstatPkt struct {
    B    []DataCnt16

Package protocol imports 9 packages (graph) and is imported by 8 packages. Updated 2020-07-12. Refresh now. Tools for package owners.