package module
Version: v0.0.0-...-689a388 Latest Latest

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

Go to latest
Published: Mar 3, 2021 License: MPL-2.0 Imports: 15 Imported by: 2



GoDoc Go Report Card

This project implements ONC RPC (Sun RPC) as described in RFC 5531 in Go lang, primarily to be consumed as a ServerCodec and ClientCodec

The initial goal here is limited to enabling existing projects written in C and uses Sun RPC to be able to communicate with a server written in Go without the need for C projects to change their existing code.



Package sunrpc implements ONC RPC (Sun RPC) as described by RFC 5531.



View Source
const RPCProtocolVersion = 2

RPCProtocolVersion is the version of RPC protocol as described in RFC 5531


View Source
var (
	ErrInvalidFragmentSize    = errors.New("The RPC fragment size is invalid")
	ErrRPCMessageSizeExceeded = errors.New("The RPC message size is too big")

Internal errors

View Source
var (
	ErrProgUnavail = errors.New("Remote server has not exported program")
	ErrProcUnavail = errors.New("Remote server has no such procedure")
	ErrGarbageArgs = errors.New("Remote procedure cannot decode params")
	ErrSystemErr   = errors.New("System error on remote server")

Given that the remote server accepted the RPC call, following errors represent error status of an attempt to call remote procedure

View Source
var (
	ErrInvalidRPCMessageType = errors.New("Invalid RPC message type received")
	ErrInvalidRPCRepyType    = errors.New("Invalid RPC reply received. Reply type should be MsgAccepted or MsgDenied")
	ErrInvalidMsgDeniedType  = errors.New("Invalid MsgDenied reply. Possible values are RPCMismatch and AuthError")
	ErrInvalidMsgAccepted    = errors.New("Invalid MsgAccepted reply received")
	ErrAuthError             = errors.New("Remote server rejected identity of the caller")

These errors represent invalid replies from server and auth rejection.


func CmuxMatcher

func CmuxMatcher(progAndVersion ...uint32) func(io.Reader) bool

CmuxMatcher reads 28 bytes of the request to guess if the request is a Sun RPC Call. You can also match RPC requests targeted at specific program and version by passing variable params (hack for lack of function overloading)

func Dial

func Dial(network, address string) (*rpc.Client, error)

Dial connects to a Sun-RPC server at the specified network address

func DumpProcedureRegistry

func DumpProcedureRegistry()

DumpProcedureRegistry will print the entire procedure map. Use this for logging/debugging.

func GetProcedureName

func GetProcedureName(procedureID ProcedureID) (string, bool)

GetProcedureName will return a string containing procedure name and a bool value which is set to true only if the procedure is found in registry.

func NewClient

func NewClient(conn io.ReadWriteCloser) *rpc.Client

NewClient returns a new rpc.Client which internally uses Sun RPC codec

func NewClientCodec

func NewClientCodec(conn io.ReadWriteCloser, notifyClose chan<- io.ReadWriteCloser) rpc.ClientCodec

NewClientCodec returns a new rpc.ClientCodec using Sun RPC on conn. If a non-nil channel is passed as second argument, the conn is sent on that channel when Close() is called on conn.

func NewServerCodec

func NewServerCodec(conn io.ReadWriteCloser, notifyClose chan<- io.ReadWriteCloser) rpc.ServerCodec

NewServerCodec returns a new rpc.ServerCodec using Sun RPC on conn. If a non-nil channel is passed as second argument, the conn is sent on that channel when Close() is called on conn.

func PmapGetPort

func PmapGetPort(host string, programNumber, programVersion uint32, protocol Protocol) (uint32, error)

PmapGetPort returns the port number on which the program specified is awaiting call requests. If host is empty string, localhost is used.

func PmapSet

func PmapSet(programNumber, programVersion uint32, protocol Protocol, port uint32) (bool, error)

PmapSet creates port mapping of the program specified. It return true on success and false otherwise.

func PmapUnset

func PmapUnset(programNumber, programVersion uint32) (bool, error)

PmapUnset will unregister the program specified. It returns true on success and false otherwise.

func ReadFullRecord

func ReadFullRecord(conn io.Reader) ([]byte, error)

ReadFullRecord reads the entire RPC message from network and returns a a []byte sequence which contains the record.

func RegisterProcedure

func RegisterProcedure(procedure Procedure, validateProcName bool) error

RegisterProcedure will register the procedure in the registry.

func RemoveProcedure

func RemoveProcedure(procedure interface{})

RemoveProcedure takes a string or ProcedureID struct as argument and deletes the corresponding procedure from procedure registry.

func WriteFullRecord

func WriteFullRecord(conn io.Writer, data []byte) (int64, error)

WriteFullRecord writes the fully formed RPC message reply to network by breaking it into one or more record fragments.


type AcceptStat

type AcceptStat int32

AcceptStat is an enumeration representing the status of procedure called

const (
	Success      AcceptStat = iota // RPC executed successfully
	ProgUnavail                    // Remote hasn't exported the program
	ProgMismatch                   // Remote can't support version number
	ProcUnavail                    // Program can't support procedure
	GarbageArgs                    // Procedure can't decode params
	SystemErr                      // Other errors

Given that a call message was accepted, the following is the status of an attempt to call a remote procedure

type AcceptedReply

type AcceptedReply struct {
	Verf         OpaqueAuth
	Stat         AcceptStat    `xdr:"union"`
	MismatchInfo MismatchReply `xdr:"unioncase=2"` // ProgMismatch


AcceptedReply contains reply accepted by the RPC server. Note that there could be an error even though the call was accepted.

type AuthFlavor

type AuthFlavor int32

AuthFlavor represents the type of authentication used

const (
	AuthNone  AuthFlavor = iota // No authentication
	AuthSys                     // Unix style (uid+gids)
	AuthShort                   // Short hand unix style
	AuthDh                      // DES style (encrypted timestamp)
	AuthKerb                    // Keberos Auth
	AuthRSA                     // RSA authentication
	RPCsecGss                   // GSS-based RPC security

Sun-assigned authentication flavor numbers

type AuthStat

type AuthStat int32

AuthStat represents the reason for authentication failure

const (
	AuthOk           AuthStat = iota // Success
	AuthBadcred                      // Bad credential (seal broken)
	AuthRejectedcred                 // Client must begin new session
	AuthBadverf                      // Bad verifier (seal broken)
	AuthRejectedVerf                 // Verifier expired or replayed
	AuthTooweak                      // Rejected for security reasons
	AuthInvalidresp                  // Bogus response verifier
	AuthFailed                       // Reason unknown

Why authentication failed

type CallBody

type CallBody struct {
	RPCVersion uint32     // must be equal to 2
	Program    uint32     // Remote program
	Version    uint32     // Remote program's version
	Procedure  uint32     // Procedure number
	Cred       OpaqueAuth // Authentication credential
	Verf       OpaqueAuth // Authentication verifier

CallBody represents the body of a RPC Call

type ErrProgMismatch

type ErrProgMismatch struct {
	Low  uint32
	High uint32

ErrProgMismatch contains the lowest and highest version of program version supported by the remote program

func (ErrProgMismatch) Error

func (e ErrProgMismatch) Error() string

type ErrRPCMismatch

type ErrRPCMismatch struct {
	Low  uint32
	High uint32

ErrRPCMismatch contains the lowest and highest version of RPC protocol supported by the remote server

func (ErrRPCMismatch) Error

func (e ErrRPCMismatch) Error() string

type MismatchReply

type MismatchReply struct {
	Low  uint32
	High uint32

MismatchReply is used in ProgMismatch and RPCMismatch cases to denote lowest and highest version of RPC version or program version supported

type MsgType

type MsgType int32

MsgType is an enumeration representing the type of RPC message

const (
	Call  MsgType = 0
	Reply MsgType = 1

A RPC message can be of two types: call or reply

type OpaqueAuth

type OpaqueAuth struct {
	Flavor AuthFlavor
	Body   []byte

OpaqueAuth is a structure with AuthFlavor enumeration followed by up to 400 bytes that are opaque to (uninterpreted by) the RPC protocol implementation.

type PortMapping

type PortMapping struct {
	Program  uint32
	Version  uint32
	Protocol uint32
	Port     uint32

PortMapping is a mapping between (program, version, protocol) to port number

func PmapGetMaps

func PmapGetMaps(host string) ([]PortMapping, error)

PmapGetMaps returns a list of PortMapping entries present in portmapper's database. If host is empty string, localhost is used.

type Procedure

type Procedure struct {
	ID   ProcedureID
	Name string

Procedure represents a ProcedureID and name pair.

type ProcedureID

type ProcedureID struct {
	ProgramNumber   uint32
	ProgramVersion  uint32
	ProcedureNumber uint32

ProcedureID uniquely identifies a remote procedure

func GetProcedureID

func GetProcedureID(procedureName string) (ProcedureID, bool)

GetProcedureID will return ProcedureID given the procedure name. It also returns a bool which is set to true only if the procedure is found in the registry.

type Program

type Program interface {
	Name() string
	Number() uint32
	Version() uint32
	Procedures() []Procedure

Program is an interface that every RPC program can implement and use internally for convenience during procedure registration

type Protocol

type Protocol uint32

Protocol is a type representing the protocol (TCP or UDP) over which the program/server being registered listens on.

const (
	// IPProtoTCP is the protocol number for TCP/IP
	IPProtoTCP Protocol = 6
	// IPProtoUDP is the protocol number for UDP/IP
	IPProtoUDP Protocol = 17

type RPCMsg

type RPCMsg struct {
	Xid   uint32
	Type  MsgType   `xdr:"union"`
	CBody CallBody  `xdr:"unioncase=0"`
	RBody ReplyBody `xdr:"unioncase=1"`

RPCMsg represents a complete RPC message (call or reply)

type RejectStat

type RejectStat int32

RejectStat is an enumeration representing the reason for rejection

const (
	RPCMismatch RejectStat = 0 // RPC version number != 2
	AuthError   RejectStat = 1 // Remote can't authenticate caller

Why call was rejected

type RejectedReply

type RejectedReply struct {
	Stat         RejectStat    `xdr:"union"`
	MismatchInfo MismatchReply `xdr:"unioncase=0"` // RPCMismatch
	AuthStat     AuthStat      `xdr:"unioncase=1"` // AuthError

RejectedReply represents a reply to a call rejected by the RPC server. The / call can be ejected for two reasons: either the server is not running a compatible version of the RPC protocol (RPCMismatch) or the server rejects the identity of the caller (AuthError)

type ReplyBody

type ReplyBody struct {
	Stat   ReplyStat     `xdr:"union"`
	Areply AcceptedReply `xdr:"unioncase=0"`
	Rreply RejectedReply `xdr:"unioncase=1"`

ReplyBody represents a generic RPC reply to a `Call`

type ReplyStat

type ReplyStat int32

ReplyStat is an enumeration representing the type of reply

const (
	MsgAccepted ReplyStat = 0
	MsgDenied   ReplyStat = 1

A reply to a call message can take two forms: the message was either accepted or rejected


Path Synopsis
Example go implementation of `rpcinfo -p` command
Example go implementation of `rpcinfo -p` command

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
t or T : Toggle theme light dark auto
y or Y : Canonical URL