client

package
v1.1.0 Latest Latest
Warning

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

Go to latest
Published: Jun 11, 2026 License: MIT Imports: 6 Imported by: 0

Documentation

Overview

Package client implements the client side of the connectionless (datagram) DCE/RPC protocol machine ([C706] chapter 10), layered on a datagram transport (network/dcerpc/v4/transport) and the connectionless PDU codec (network/dcerpc/v4/pdu).

Unlike the connection-oriented client, there is no Bind: a call is established implicitly by the first request PDU, which carries the activity UUID, interface identity, and a per-activity sequence number. The client fragments the request stub into request PDUs, transmits them, and then drives a receive loop that handles the server's flow-control and status PDUs:

  • fack — flow-control acknowledgement; the client may send more fragments.
  • working — the server is processing the call; the client keeps waiting.
  • nocall — the server has not seen the call; the client retransmits.
  • response— output fragments, reassembled until the lastfrag PDU arrives.
  • fault / reject — the call failed; returned as *FaultError / *RejectError.

When no PDU arrives before the transport timeout, the client retransmits the request fragments (while still awaiting any response) or sends a ping (while awaiting further response fragments), giving up after the configured limits.

NOT YET IMPLEMENTED (documented limitations):

  • The conv callback interface (conv_who_are_you) used for at-most-once verification of non-idempotent calls; mark calls idempotent for now.
  • Windowed burst flow control: all request fragments are sent immediately rather than throttled to the server's advertised fack window. This is correct for the small, typically single-fragment requests connectionless RPC carries, and the server's nocall/fack still drive retransmission.
  • Broadcast and maybe (no-response) calls, and client-side cancel.

References:

Index

Constants

View Source
const (
	// DefaultMaxRequests is how many times the request burst is retransmitted before
	// the client gives up waiting for the server to acknowledge the call.
	DefaultMaxRequests = 5
	// DefaultMaxPings is how many pings are sent, while a response is outstanding,
	// before the client gives up.
	DefaultMaxPings = 5
	// DefaultFackWindow is the receive window, in fragments, advertised in the facks
	// the client sends for inbound response fragments.
	DefaultFackWindow = 8
	// DefaultMaxReceives bounds the total number of PDUs a single call will process
	// before giving up. It is a backstop against a server that floods non-terminal
	// PDUs (endless working/fack/ping or PDUs for other conversations), which would
	// otherwise spin the receive loop forever since such PDUs do not trip the
	// retransmission or ping limits. It is set far above any plausible fragment count.
	DefaultMaxReceives = 1 << 20
)

Default flow-control limits ([C706] chapter 10: MAX_REQUESTS, MAX_PINGS).

Variables

View Source
var ErrNoResponse = errors.New("dcerpc(cl): no response within retransmission limits")

ErrNoResponse is returned when the server never produces a response within the configured retransmission and ping limits.

Functions

This section is empty.

Types

type CallRequest

type CallRequest struct {
	// Object is the optional object UUID; leave zero for none.
	Object guid.GUID
	// Interface is the interface (abstract syntax) UUID.
	Interface guid.GUID
	// InterfaceVersion is the interface major version (the if_vers field).
	InterfaceVersion uint32
	// OpNum is the operation number within the interface.
	OpNum uint16
	// Stub is the NDR-marshalled input parameters.
	Stub []byte
	// Idempotent marks the call idempotent, allowing safe retransmission without
	// at-most-once verification.
	Idempotent bool
}

CallRequest describes one connectionless RPC call.

type Client

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

Client drives connectionless calls over a single activity (conversation).

func New

func New(t transport.Transport, opts ...Option) *Client

New returns a connectionless client bound to the given datagram transport. Unless WithActivityID is supplied, a fresh random activity UUID is generated.

func (*Client) ActivityID

func (c *Client) ActivityID() guid.GUID

ActivityID returns the activity UUID identifying this client's conversation.

func (*Client) Call

func (c *Client) Call(req CallRequest) ([]byte, error)

Call performs a single connectionless RPC call and returns the reassembled response stub (the NDR-marshalled output parameters). A server fault or reject is returned as *FaultError or *RejectError.

type FaultError

type FaultError struct{ Status uint32 }

FaultError reports a fault PDU returned by the server, carrying its status code.

func (*FaultError) Error

func (e *FaultError) Error() string

type Option

type Option func(*Client)

Option configures a Client.

func WithActivityID

func WithActivityID(id guid.GUID) Option

WithActivityID sets a fixed activity UUID instead of a random one (useful for tests and for resuming a known conversation).

func WithMaxPings

func WithMaxPings(n int) Option

WithMaxPings overrides the ping limit.

func WithMaxReceives

func WithMaxReceives(n int) Option

WithMaxReceives overrides the per-call cap on the total number of PDUs processed before giving up (the flood backstop).

func WithMaxRequests

func WithMaxRequests(n int) Option

WithMaxRequests overrides the request retransmission limit.

type RejectError

type RejectError struct{ Status uint32 }

RejectError reports a reject PDU returned by the server, carrying its status code.

func (*RejectError) Error

func (e *RejectError) Error() string

Jump to

Keyboard shortcuts

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