srv

package
v0.17.0 Latest Latest
Warning

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

Go to latest
Published: Mar 2, 2017 License: Apache-2.0, BSD-3-Clause Imports: 7 Imported by: 0

Documentation

Overview

The srv package provides definitions and functions used to implement a 9P2000 file server.

Index

Constants

View Source
const (
	DbgPrintFcalls  = (1 << iota) // print all 9P messages on stderr
	DbgPrintPackets               // print the raw packets on stderr
	DbgLogFcalls                  // keep the last N 9P messages (can be accessed over http)
	DbgLogPackets                 // keep the last N 9P messages (can be accessed over http)
)

Debug flags

Variables

View Source
var Ebadoffset error = &p.Error{"bad offset in directory read", p.EINVAL}
View Source
var Ebaduse error = &p.Error{"bad use of fid", p.EINVAL}
View Source
var Edirchange error = &p.Error{"cannot convert between files and directories", p.EINVAL}
View Source
var Eexist = &p.Error{"file already exists", p.EEXIST}
View Source
var Einuse error = &p.Error{"fid already in use", p.EINVAL}
View Source
var Enoauth error = &p.Error{"no authentication required", p.EINVAL}
View Source
var Enoent = &p.Error{"file not found", p.ENOENT}
View Source
var Enotdir error = &p.Error{"not a directory", p.ENOTDIR}
View Source
var Enotempty = &p.Error{"directory not empty", p.EPERM}
View Source
var Enotimpl error = &p.Error{"not implemented", p.EINVAL}
View Source
var Enouser error = &p.Error{"unknown user", p.EINVAL}
View Source
var Eopen error = &p.Error{"fid already opened", p.EINVAL}
View Source
var Eperm error = &p.Error{"permission denied", p.EPERM}
View Source
var Etoolarge error = &p.Error{"i/o count too large", p.EINVAL}
View Source
var Eunknownfid error = &p.Error{"unknown fid", p.EINVAL}

Functions

This section is empty.

Types

type AuthOps

type AuthOps interface {
	// AuthInit is called when the user starts the authentication
	// process on Fid afid. The user that is being authenticated
	// is referred by afid.User. The function should return the Qid
	// for the authentication file, or an Error if the user can't be
	// authenticated
	AuthInit(afid *Fid, aname string) (*p.Qid, error)

	// AuthDestroy is called when an authentication fid is destroyed.
	AuthDestroy(afid *Fid)

	// AuthCheck is called after the authentication process is finished
	// when the user tries to attach to the file server. If the function
	// returns nil, the authentication was successful and the user has
	// permission to access the files.
	AuthCheck(fid *Fid, afid *Fid, aname string) error

	// AuthRead is called when the user attempts to read data from an
	// authentication fid.
	AuthRead(afid *Fid, offset uint64, data []byte) (count int, err error)

	// AuthWrite is called when the user attempts to write data to an
	// authentication fid.
	AuthWrite(afid *Fid, offset uint64, data []byte) (count int, err error)
}

Authentication operations. The file server should implement them if it requires user authentication. The authentication in 9P2000 is done by creating special authentication fids and performing I/O operations on them. Once the authentication is done, the authentication fid can be used by the user to get access to the actual files.

type Conn

type Conn struct {
	sync.Mutex
	Srv        *Srv
	Msize      uint32 // maximum size of 9P2000 messages for the connection
	Dotu       bool   // if true, both the client and the server speak 9P2000.u
	Id         string // used for debugging and stats
	Debuglevel int
	// contains filtered or unexported fields
}

The Conn type represents a connection from a client to the file server

func (*Conn) FidGet

func (conn *Conn) FidGet(fidno uint32) *Fid

Lookup a Fid struct based on the 32-bit identifier sent over the wire. Returns nil if the fid is not found. Increases the reference count of the returned fid. The user is responsible to call DecRef once it no longer needs it.

func (*Conn) FidNew

func (conn *Conn) FidNew(fidno uint32) *Fid

Creates a new Fid struct for the fidno integer. Returns nil if the Fid for that number already exists. The returned fid has reference count set to 1.

func (*Conn) LocalAddr

func (conn *Conn) LocalAddr() net.Addr

func (*Conn) RemoteAddr

func (conn *Conn) RemoteAddr() net.Addr

func (*Conn) String

func (conn *Conn) String() string

type ConnOps

type ConnOps interface {
	ConnOpened(*Conn)
	ConnClosed(*Conn)
}

Connection operations. These should be implemented if the file server needs to be called when a connection is opened or closed.

type FClunkOp

type FClunkOp interface {
	Clunk(fid *FFid) error
}

type FCreateOp

type FCreateOp interface {
	Create(fid *FFid, name string, perm uint32) (*File, error)
}

If the FCreateOp interface is implemented, the Create operation will be called when the client attempts to create a file in the File implementing the interface. If not implemented, "permission denied" error will be send back. If successful, the operation should call (*File)Add() to add the created file to the directory. The operation returns the created file, or the error occured while creating it.

type FDestroyOp

type FDestroyOp interface {
	FidDestroy(fid *FFid)
}

type FFid

type FFid struct {
	F   *File
	Fid *Fid
	// contains filtered or unexported fields
}

type FFlags

type FFlags int
const (
	Fremoved FFlags = 1 << iota
)

type FOpenOp

type FOpenOp interface {
	Open(fid *FFid, mode uint8) error
}

type FReadOp

type FReadOp interface {
	Read(fid *FFid, buf []byte, offset uint64) (int, error)
}

If the FReadOp interface is implemented, the Read operation will be called to read from the file. If not implemented, "permission denied" error will be send back. The operation returns the number of bytes read, or the error occured while reading.

type FRemoveOp

type FRemoveOp interface {
	Remove(*FFid) error
}

If the FRemoveOp interface is implemented, the Remove operation will be called when the client attempts to create a file in the File implementing the interface. If not implemented, "permission denied" error will be send back. The operation returns nil if successful, or the error that occured while removing the file.

type FStatOp

type FStatOp interface {
	Stat(fid *FFid) error
}

The FStatOp interface provides a single operation (Stat) that will be called before a file stat is sent back to the client. If implemented, the operation should update the data in the File struct.

type FWriteOp

type FWriteOp interface {
	Write(fid *FFid, data []byte, offset uint64) (int, error)
}

If the FWriteOp interface is implemented, the Write operation will be called to write to the file. If not implemented, "permission denied" error will be send back. The operation returns the number of bytes written, or the error occured while writing.

type FWstatOp

type FWstatOp interface {
	Wstat(*FFid, *p.Dir) error
}

The FWstatOp interface provides a single operation (Wstat) that will be called when the client requests the File metadata to be modified. If implemented, the operation will be called when Twstat message is received. If not implemented, "permission denied" error will be sent back. If the operation returns an Error, the error is send back to the client.

type Fid

type Fid struct {
	sync.Mutex

	Fconn     *Conn       // Connection the Fid belongs to
	Omode     uint8       // Open mode (p.O* flags), if the fid is opened
	Type      uint8       // Fid type (p.QT* flags)
	Diroffset uint64      // If directory, the next valid read position
	User      p.User      // The Fid's user
	Aux       interface{} // Can be used by the file server implementation for per-Fid data
	// contains filtered or unexported fields
}

The Fid type identifies a file on the file server. A new Fid is created when the user attaches to the file server (the Attach operation), or when Walk-ing to a file. The Fid values are created automatically by the srv implementation. The FidDestroy operation is called when a Fid is destroyed.

func (*Fid) DecRef

func (fid *Fid) DecRef()

Decrease the reference count for the fid. When the reference count reaches 0, the fid is no longer valid.

func (*Fid) IncRef

func (fid *Fid) IncRef()

Increase the reference count for the fid.

type FidOps

type FidOps interface {
	FidDestroy(*Fid)
}

Fid operations. This interface should be implemented if the file server needs to be called when a Fid is destroyed.

type File

type File struct {
	sync.Mutex
	p.Dir

	Parent *File // parent

	Ops interface{}
	// contains filtered or unexported fields
}

The File type represents a file (or directory) served by the file server.

func (*File) Add

func (f *File) Add(dir *File, name string, uid p.User, gid p.Group, mode uint32, ops interface{}) error

Initializes the fields of a file and add it to a directory. Returns nil if successful, or an error.

func (*File) CheckPerm

func (f *File) CheckPerm(user p.User, perm uint32) bool

Checks if the specified user has permission to perform certain operation on a file. Perm contains one or more of p.DMREAD, p.DMWRITE, and p.DMEXEC.

func (*File) Find

func (p *File) Find(name string) *File

Looks for a file in a directory. Returns nil if the file is not found.

func (*File) Remove

func (f *File) Remove()

Removes a file from its parent directory.

func (*File) Rename

func (f *File) Rename(name string) error

type FlushOp

type FlushOp interface {
	Flush(*Req)
}

Flush operation. This interface should be implemented if the file server can flush pending requests. If the interface is not implemented, requests that were passed to the file server implementation won't be flushed. The flush method should call the (req *Req) srv.Flush() method if the flush was successful so the request can be marked appropriately.

type Fsrv

type Fsrv struct {
	Srv
	Root *File
}

The Fsrv can be used to create file servers that serve simple trees of synthetic files.

func NewFileSrv

func NewFileSrv(root *File) *Fsrv

Creates a file server with root as root directory

func (*Fsrv) Attach

func (s *Fsrv) Attach(req *Req)

func (*Fsrv) Clunk

func (*Fsrv) Clunk(req *Req)

func (*Fsrv) Create

func (*Fsrv) Create(req *Req)

func (*Fsrv) FidDestroy

func (*Fsrv) FidDestroy(ffid *Fid)

func (*Fsrv) Open

func (*Fsrv) Open(req *Req)

func (*Fsrv) Read

func (*Fsrv) Read(req *Req)

func (*Fsrv) Remove

func (*Fsrv) Remove(req *Req)

func (*Fsrv) Stat

func (*Fsrv) Stat(req *Req)

func (*Fsrv) Walk

func (*Fsrv) Walk(req *Req)

func (*Fsrv) Write

func (*Fsrv) Write(req *Req)

func (*Fsrv) Wstat

func (*Fsrv) Wstat(req *Req)

type Req

type Req struct {
	sync.Mutex
	Tc     *p.Fcall // Incoming 9P2000 message
	Rc     *p.Fcall // Outgoing 9P2000 response
	Fid    *Fid     // The Fid value for all messages that contain fid[4]
	Afid   *Fid     // The Fid value for the messages that contain afid[4] (Tauth and Tattach)
	Newfid *Fid     // The Fid value for the messages that contain newfid[4] (Twalk)
	Conn   *Conn    // Connection that the request belongs to
	// contains filtered or unexported fields
}

The Req type represents a 9P2000 request. Each request has a T-message (Tc) and a R-message (Rc). If the ReqProcessOps don't override the default behavior, the implementation initializes Fid, Afid and Newfid values and automatically keeps track on when the Fids should be destroyed.

func (*Req) Flush

func (req *Req) Flush()

Should be called to cancel a request. Should only be called from the Flush operation if the FlushOp is implemented.

func (*Req) PostProcess

func (req *Req) PostProcess()

Performs the post processing required if the (*Req) Process() method is called for a request. The file server implementer should call it only if the file server implements the ReqProcessOps within the ReqRespond operation.

func (*Req) Process

func (req *Req) Process()

Performs the default processing of a request. Initializes the Fid, Afid and Newfid fields and calls the appropriate ReqOps operation for the message. The file server implementer should call it only if the file server implements the ReqProcessOps within the ReqProcess operation.

func (*Req) Respond

func (req *Req) Respond()

The Respond method sends response back to the client. The req.Rc value should be initialized and contain valid 9P2000 message. In most cases the file server implementer shouldn't call this method directly. Instead one of the RespondR* methods should be used.

func (*Req) RespondError

func (req *Req) RespondError(err interface{})

Respond to the request with Rerror message

func (*Req) RespondRattach

func (req *Req) RespondRattach(aqid *p.Qid)

Respond to the request with Rattach message

func (*Req) RespondRauth

func (req *Req) RespondRauth(aqid *p.Qid)

Respond to the request with Rauth message

func (*Req) RespondRclunk

func (req *Req) RespondRclunk()

Respond to the request with Rclunk message

func (*Req) RespondRcreate

func (req *Req) RespondRcreate(qid *p.Qid, iounit uint32)

Respond to the request with Rcreate message

func (*Req) RespondRflush

func (req *Req) RespondRflush()

Respond to the request with Rflush message

func (*Req) RespondRopen

func (req *Req) RespondRopen(qid *p.Qid, iounit uint32)

Respond to the request with Ropen message

func (*Req) RespondRread

func (req *Req) RespondRread(data []byte)

Respond to the request with Rread message

func (*Req) RespondRremove

func (req *Req) RespondRremove()

Respond to the request with Rremove message

func (*Req) RespondRstat

func (req *Req) RespondRstat(st *p.Dir)

Respond to the request with Rstat message

func (*Req) RespondRversion

func (req *Req) RespondRversion(msize uint32, version string)

Respond to the request with Rversion message

func (*Req) RespondRwalk

func (req *Req) RespondRwalk(wqids []p.Qid)

Respond to the request with Rwalk message

func (*Req) RespondRwrite

func (req *Req) RespondRwrite(count uint32)

Respond to the request with Rwrite message

func (*Req) RespondRwstat

func (req *Req) RespondRwstat()

Respond to the request with Rwstat message

type ReqOps

type ReqOps interface {
	Attach(*Req)
	Walk(*Req)
	Open(*Req)
	Create(*Req)
	Read(*Req)
	Write(*Req)
	Clunk(*Req)
	Remove(*Req)
	Stat(*Req)
	Wstat(*Req)
}

Request operations. This interface should be implemented by all file servers. The operations correspond directly to most of the 9P2000 message types.

type ReqProcessOps

type ReqProcessOps interface {
	// Called when a new request is received from the client. If the
	// interface is not implemented, (req *Req) srv.Process() method is
	// called. If the interface is implemented, it is the user's
	// responsibility to call srv.Process. If srv.Process isn't called,
	// Fid, Afid and Newfid fields in Req are not set, and the ReqOps
	// methods are not called.
	ReqProcess(*Req)

	// Called when a request is responded, i.e. when (req *Req)srv.Respond()
	// is called and before the response is sent. If the interface is not
	// implemented, (req *Req) srv.PostProcess() method is called to finalize
	// the request. If the interface is implemented and ReqProcess calls
	// the srv.Process method, ReqRespond should call the srv.PostProcess
	// method.
	ReqRespond(*Req)
}

Request operations. This interface should be implemented if the file server needs to bypass the default request process, or needs to perform certain operations before the (any) request is processed, or before (any) response sent back to the client.

type Srv

type Srv struct {
	sync.Mutex
	Id         string  // Used for debugging and stats
	Msize      uint32  // Maximum size of the 9P2000 messages supported by the server
	Dotu       bool    // If true, the server supports the 9P2000.u extension
	Debuglevel int     // debug level
	Upool      p.Users // Interface for finding users and groups known to the file server
	Maxpend    int     // Maximum pending outgoing requests
	Log        *p.Logger
	// contains filtered or unexported fields
}

The Srv type contains the basic fields used to control the 9P2000 file server. Each file server implementation should create a value of Srv type, initialize the values it cares about and pass the struct to the (Srv *) srv.Start(ops) method together with the object that implements the file server operations.

func (*Srv) NewConn

func (srv *Srv) NewConn(c net.Conn)

func (*Srv) Start

func (srv *Srv) Start(ops interface{}) bool

The Start method should be called once the file server implementor initializes the Srv struct with the preferred values. It sets default values to the fields that are not initialized and creates the goroutines required for the server's operation. The method receives an empty interface value, ops, that should implement the interfaces the file server is interested in. Ops must implement the ReqOps interface.

func (*Srv) StartListener

func (srv *Srv) StartListener(l net.Listener) error

Start listening on the specified network and address for incoming connections. Once a connection is established, create a new Conn value, read messages from the socket, send them to the specified server, and send back responses received from the server.

func (*Srv) StartNetListener

func (srv *Srv) StartNetListener(ntype, addr string) error

func (*Srv) String

func (srv *Srv) String() string

type StatsOps

type StatsOps interface {
	// contains filtered or unexported methods
}

Directories

Path Synopsis
examples
tlsramfs
Listen on SSL connection, can be used as an example with p/clnt/examples/tls.go Sample certificate was copied from the Go source code
Listen on SSL connection, can be used as an example with p/clnt/examples/tls.go Sample certificate was copied from the Go source code
ufs

Jump to

Keyboard shortcuts

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