BRL-CAD
Loading...
Searching...
No Matches
libpkg (Network Communications)

Files

file  pkg.h
 

Data Structures

struct  pkg_switch
 
struct  pkg_header
 
struct  pkg_conn
 

Macros

#define PKG_MAGIC   0x41FE
 
#define PKG_STREAMLEN   (32*1024)
 
#define PKC_NULL   ((struct pkg_conn *)0)
 
#define PKC_ERROR   ((struct pkg_conn *)(-1L))
 
#define pkg_send_vls(type, vlsp, pkg)    pkg_send( (type), bu_vls_addr((vlsp)), bu_vls_strlen((vlsp))+1, (pkg) )
 
#define PKG_ADDR_ENVVAR   "PKG_ADDR"
 
#define PKG_TRANSPORT_PREFER_ENVVAR   "PKG_TRANSPORT_PREFER"
 

Typedefs

typedef void(* pkg_callback) (struct pkg_conn *, char *)
 
typedef void(* pkg_errlog) (const char *msg)
 
typedef struct pkg_listener pkg_listener_t
 
typedef struct pkg_mux pkg_mux_t
 

Enumerations

enum  pkg_transport_t { PKG_TRANSPORT_AUTO = 0 , PKG_TRANSPORT_PIPE = 1 , PKG_TRANSPORT_SOCKET = 2 , PKG_TRANSPORT_TCP = 3 }
 

Functions

struct pkg_connpkg_open (const char *host, const char *service, const char *protocol, const char *username, const char *passwd, const struct pkg_switch *switchp, pkg_errlog errlog)
 
void pkg_close (struct pkg_conn *pc)
 
int pkg_process (struct pkg_conn *)
 
int pkg_suckin (struct pkg_conn *)
 
int pkg_send (int type, const char *buf, size_t len, struct pkg_conn *pc)
 
int pkg_2send (int type, const char *buf1, size_t len1, const char *buf2, size_t len2, struct pkg_conn *pc)
 
int pkg_stream (int type, const char *buf, size_t len, struct pkg_conn *pc)
 
int pkg_flush (struct pkg_conn *pc)
 
int pkg_waitfor (int type, char *buf, size_t len, struct pkg_conn *pc)
 
charpkg_bwaitfor (int type, struct pkg_conn *pc)
 
int pkg_block (struct pkg_conn *pc)
 
int pkg_get_read_fd (const struct pkg_conn *pc)
 
int pkg_get_write_fd (const struct pkg_conn *pc)
 
int pkg_is_stdio_mode (const struct pkg_conn *pc)
 
int pkg_set_send_buffer (struct pkg_conn *pc, size_t bytes)
 
int pkg_set_recv_buffer (struct pkg_conn *pc, size_t bytes)
 
int pkg_set_nodelay (struct pkg_conn *pc, int on)
 
int pkg_set_tls (struct pkg_conn *pc, void *tls_ctx, ptrdiff_t(*tls_read)(void *ctx, void *buf, size_t n), ptrdiff_t(*tls_write)(void *ctx, const void *buf, size_t n), void(*tls_free)(void *ctx))
 
struct pkg_connpkg_adopt_socket (int fd, const struct pkg_switch *switchp, pkg_errlog errlog)
 
int pkg_pair (struct pkg_conn **parent_end, struct pkg_conn **child_end, const struct pkg_switch *switchp, pkg_errlog errlog)
 
int pkg_pair_prefer (struct pkg_conn **parent_end, struct pkg_conn **child_end, const struct pkg_switch *switchp, pkg_errlog errlog, pkg_transport_t preferred)
 
const charpkg_child_addr_env (struct pkg_conn *pc)
 
const charpkg_child_addr (struct pkg_conn *pc)
 
struct pkg_connpkg_connect_addr (const char *addr, const struct pkg_switch *switchp, pkg_errlog errlog)
 
int pkg_ipc_addr (char *addr, size_t len, const char *name_hint)
 
int pkg_addr_is_ipc_listener (const char *addr)
 
struct pkg_connpkg_connect_env (const struct pkg_switch *switchp, pkg_errlog errlog)
 
struct pkg_connpkg_adopt_fds (int rfd, int wfd, const struct pkg_switch *switchp, pkg_errlog errlog)
 
struct pkg_connpkg_adopt_stdio (const struct pkg_switch *switchp, pkg_errlog errlog)
 
int pkg_move_high_fd (struct pkg_conn *pc, int min_fd)
 
pkg_listener_tpkg_listen (const char *service, const char *iface_or_null, int backlog, pkg_errlog errlog)
 
struct pkg_connpkg_accept (pkg_listener_t *L, const struct pkg_switch *switchp, pkg_errlog errlog, int nonblocking)
 
int pkg_get_listener_fd (const pkg_listener_t *L)
 
int pkg_get_listener_port (const pkg_listener_t *L)
 
void pkg_listener_close (pkg_listener_t *L)
 
pkg_mux_tpkg_mux_create (void)
 
void pkg_mux_destroy (pkg_mux_t *m)
 
int pkg_mux_add_conn (pkg_mux_t *m, const struct pkg_conn *pc)
 
int pkg_mux_add_listener (pkg_mux_t *m, const pkg_listener_t *L)
 
int pkg_mux_add_fd (pkg_mux_t *m, int fd, int is_socket)
 
void pkg_mux_remove_fd (pkg_mux_t *m, int fd)
 
int pkg_mux_wait (pkg_mux_t *m, int timeout_ms)
 
int pkg_mux_is_ready_conn (const pkg_mux_t *m, const struct pkg_conn *pc)
 
int pkg_mux_is_ready_listener (const pkg_mux_t *m, const pkg_listener_t *L)
 
int pkg_mux_is_ready_fd (const pkg_mux_t *m, int fd)
 
unsigned short pkg_gshort (char *buf)
 
unsigned long pkg_glong (char *buf)
 
charpkg_pshort (char *buf, unsigned short s)
 
charpkg_plong (char *buf, unsigned long l)
 
const charpkg_version (void)
 

Detailed Description

Macro Definition Documentation

◆ PKG_MAGIC

#define PKG_MAGIC   0x41FE

Format of the message header as it is transmitted over the network connection. Internet network order is used. User Code should access pkc_len and pkc_type rather than looking into the header directly. Users should never need to know what this header looks like.

Definition at line 73 of file pkg.h.

◆ PKG_STREAMLEN

#define PKG_STREAMLEN   (32*1024)

Definition at line 80 of file pkg.h.

◆ PKC_NULL

#define PKC_NULL   ((struct pkg_conn *)0)

Definition at line 135 of file pkg.h.

◆ PKC_ERROR

#define PKC_ERROR   ((struct pkg_conn *)(-1L))

Definition at line 136 of file pkg.h.

◆ pkg_send_vls

#define pkg_send_vls (   type,
  vlsp,
  pkg 
)     pkg_send( (type), bu_vls_addr((vlsp)), bu_vls_strlen((vlsp))+1, (pkg) )

Sends a VLS as a given message type across a pkg connection.

Definition at line 142 of file pkg.h.

◆ PKG_ADDR_ENVVAR

#define PKG_ADDR_ENVVAR   "PKG_ADDR"

Environment variable read by a child to find its IPC channel address.

Definition at line 384 of file pkg.h.

◆ PKG_TRANSPORT_PREFER_ENVVAR

#define PKG_TRANSPORT_PREFER_ENVVAR   "PKG_TRANSPORT_PREFER"

Optional transport preference hint for pkg_pair().

Definition at line 387 of file pkg.h.

Typedef Documentation

◆ pkg_callback

typedef void(* pkg_callback) (struct pkg_conn *, char *)

Definition at line 56 of file pkg.h.

◆ pkg_errlog

typedef void(* pkg_errlog) (const char *msg)

Definition at line 57 of file pkg.h.

◆ pkg_listener_t

Definition at line 501 of file pkg.h.

◆ pkg_mux_t

Definition at line 521 of file pkg.h.

Enumeration Type Documentation

◆ pkg_transport_t

Transport type for probing preference.

Enumerator
PKG_TRANSPORT_AUTO 

Use default probe order.

PKG_TRANSPORT_PIPE 

Anonymous pipe transport.

PKG_TRANSPORT_SOCKET 

POSIX socketpair transport.

PKG_TRANSPORT_TCP 

TCP loopback transport.

Definition at line 390 of file pkg.h.

Function Documentation

◆ pkg_open()

struct pkg_conn * pkg_open ( const char host,
const char service,
const char protocol,
const char username,
const char passwd,
const struct pkg_switch switchp,
pkg_errlog  errlog 
)
extern

Open a network connection to a host/server.

Returns PKC_ERROR on error.

◆ pkg_close()

void pkg_close ( struct pkg_conn pc)
extern

Close a network connection.

Gracefully release the connection block and close the connection.

◆ pkg_process()

int pkg_process ( struct pkg_conn )
extern

◆ pkg_suckin()

int pkg_suckin ( struct pkg_conn )
extern

Suck all data from the operating system into the internal buffer.

This is done with large buffers, to maximize the efficiency of the data transfer from kernel to user.

It is expected that the read() system call will return as much data as the kernel has, UP TO the size indicated. The only time the read() may be expected to block is when the kernel does not have any data at all. Thus, it is wise to call call this routine only if:

 a)  select() has indicated the presence of data, or
 b)  blocking is acceptable.

This routine is the only place where data is taken off the network. All input is appended to the internal buffer for later processing.

Subscripting was used for pkc_incur/pkc_inend to avoid having to recompute pointers after a realloc().

Returns - -1 on error 0 on EOF 1 success

◆ pkg_send()

int pkg_send ( int  type,
const char buf,
size_t  len,
struct pkg_conn pc 
)
extern

Send a message on the connection.

Send the user's data, prefaced with an identifying header which contains a message type value. All header fields are exchanged in "network order".

Note that the whole message (header + data) should be transmitted by TCP with only one TCP_PUSH at the end, due to the use of writev().

Returns number of bytes of user data actually sent.

◆ pkg_2send()

int pkg_2send ( int  type,
const char buf1,
size_t  len1,
const char buf2,
size_t  len2,
struct pkg_conn pc 
)
extern

Send a two part message on the connection.

Exactly like pkg_send, except user's data is located in two disjoint buffers, rather than one. Fiendishly useful!

◆ pkg_stream()

int pkg_stream ( int  type,
const char buf,
size_t  len,
struct pkg_conn pc 
)
extern

Send a message that doesn't need a push.

Exactly like pkg_send except no "push" is necessary here. If the packet is sufficiently small (MAXQLEN) it will be placed in the pkc_stream buffer (after flushing this buffer if there insufficient room). If it is larger than this limit, it is sent via pkg_send (who will do a pkg_flush if there is already data in the stream queue).

Returns number of bytes of user data actually sent (or queued).

◆ pkg_flush()

int pkg_flush ( struct pkg_conn pc)
extern

Empty the stream buffer of any queued messages.

Flush any pending data in the pkc_stream buffer.

Returns < 0 on failure, else number of bytes sent.

◆ pkg_waitfor()

int pkg_waitfor ( int  type,
char buf,
size_t  len,
struct pkg_conn pc 
)
extern

Wait for a specific msg, user buf, processing others.

This routine implements a blocking read on the network connection until a message of 'type' type is received. This can be useful for implementing the synchronous portions of a query/reply exchange. All messages of any other type are processed by pkg_block().

Returns the length of the message actually received, or -1 on error.

◆ pkg_bwaitfor()

char * pkg_bwaitfor ( int  type,
struct pkg_conn pc 
)
extern

Wait for specific msg, malloc buf, processing others.

This routine implements a blocking read on the network connection until a message of 'type' type is received. This can be useful for implementing the synchronous portions of a query/reply exchange. All messages of any other type are processed by pkg_block().

The buffer to contain the actual message is acquired via malloc(), and the caller must free it.

Returns pointer to message buffer, or NULL.

◆ pkg_block()

int pkg_block ( struct pkg_conn pc)
extern

Wait until a full message has been read.

This routine blocks, waiting for one complete message to arrive from the network. The actual handling of the message is done with _pkg_dispatch(), which invokes the user-supplied message handler.

This routine can be used in a loop to pass the time while waiting for a flag to be changed by the arrival of an asynchronous message, or for the arrival of a message of uncertain type.

The companion routine is pkg_process(), which does not block.

Control returns to the caller after one full message is processed. Returns -1 on error, etc.

◆ pkg_get_read_fd()

int pkg_get_read_fd ( const struct pkg_conn pc)
extern

Return the file descriptor a caller should pass to select(), poll(), QSocketNotifier, libuv, etc. for read-readiness notification.

Hides the distinction between bidirectional sockets (where read and write share a single fd) and pipe-pair connections (where the read end is a separate fd kept internally as pkc_in_fd). Callers should use this in preference to looking at pkc_fd / pkc_in_fd directly.

Returns -1 on error.

◆ pkg_get_write_fd()

int pkg_get_write_fd ( const struct pkg_conn pc)
extern

Return the file descriptor used for write-readiness notification. Equal to pkg_get_read_fd() for bidirectional transports (TCP / socketpair); for pipe-pair connections this is the write fd.

Returns -1 on error.

◆ pkg_is_stdio_mode()

int pkg_is_stdio_mode ( const struct pkg_conn pc)
extern

Return non-zero if the connection uses split read/write fds (i.e. the unidirectional pipe transport; pkc_in_fd != pkc_out_fd). Use this in preference to inspecting pkc_fd / pkc_in_fd / pkc_out_fd directly so future transport changes remain source-compatible.

◆ pkg_set_send_buffer()

int pkg_set_send_buffer ( struct pkg_conn pc,
size_t  bytes 
)
extern

Set the kernel send-buffer size on the underlying socket (equivalent to setsockopt(SOL_SOCKET, SO_SNDBUF)).

Silently succeeds (returns 0) for transports where send-buffer tuning is not applicable (pipe / split-fd connections).

Returns 0 on success, -1 on error.

◆ pkg_set_recv_buffer()

int pkg_set_recv_buffer ( struct pkg_conn pc,
size_t  bytes 
)
extern

Set the kernel receive-buffer size on the underlying socket (equivalent to setsockopt(SOL_SOCKET, SO_RCVBUF)).

Silently succeeds (returns 0) for transports where receive-buffer tuning is not applicable. Returns 0 on success, -1 on error.

◆ pkg_set_nodelay()

int pkg_set_nodelay ( struct pkg_conn pc,
int  on 
)
extern

Set TCP_NODELAY on the underlying socket. No-op on non-TCP transports. Returns 0 on success, -1 on error.

◆ pkg_set_tls()

int pkg_set_tls ( struct pkg_conn pc,
void tls_ctx,
ptrdiff_t(*)(void *ctx, void *buf, size_t n)  tls_read,
ptrdiff_t(*)(void *ctx, const void *buf, size_t n)  tls_write,
void(*)(void *ctx tls_free 
)
extern

Install a TLS / framing-cipher I/O shim on the connection.

When tls_read / tls_write are non-NULL they completely replace the raw read()/write() calls inside pkg_suckin(), pkg_send(), pkg_2send(), and pkg_flush(). tls_ctx is the opaque context pointer forwarded as the first argument to both callbacks.

tls_free (if non-NULL) is invoked by pkg_close() before closing the underlying transport, giving the TLS layer a chance to send a clean close_notify and free its own state.

Returns 0 on success, -1 on error.

◆ pkg_adopt_socket()

struct pkg_conn * pkg_adopt_socket ( int  fd,
const struct pkg_switch switchp,
pkg_errlog  errlog 
)
extern

Wrap an already-connected socket fd in a pkg_conn without performing any network connect/accept.

Replaces the historical pattern of allocating a pkg_conn and hand-initialising pkc_magic / pkc_fd / pkc_switch / pkc_left etc. Used by callers that obtain a connected socket from another framework (Tcl/Qt) and want to drive it through libpkg's framing protocol.

On Windows this also performs WinSock initialisation if necessary.

Returns a pkg_conn handle on success, PKC_ERROR on failure.

◆ pkg_pair()

int pkg_pair ( struct pkg_conn **  parent_end,
struct pkg_conn **  child_end,
const struct pkg_switch switchp,
pkg_errlog  errlog 
)
extern

Create a connected pair of pkg_conn handles.

Probe order: pipe -> socketpair -> TCP loopback (or use preferred). Returns 0 on success, -1 on failure.

◆ pkg_pair_prefer()

int pkg_pair_prefer ( struct pkg_conn **  parent_end,
struct pkg_conn **  child_end,
const struct pkg_switch switchp,
pkg_errlog  errlog,
pkg_transport_t  preferred 
)
extern

◆ pkg_child_addr_env()

const char * pkg_child_addr_env ( struct pkg_conn pc)
extern

Return a "KEY=VALUE" env string for passing to a spawned child. The pointer is valid until pkg_close(). Format: "PKG_ADDR=<addr>". For pair transports, the address may be a child-side or parent-side local IPC string, depending on which end is being exported.

◆ pkg_child_addr()

const char * pkg_child_addr ( struct pkg_conn pc)
extern

Return just the raw address string (e.g. "pipe:4,7" or "socket:5") for use in argv["-I addr"] style arguments to a child process. Pair transports may also return parent-side variants such as "pipe_parent:4,7" and "socket_parent:5". The pointer is valid until pkg_close().

◆ pkg_connect_addr()

struct pkg_conn * pkg_connect_addr ( const char addr,
const struct pkg_switch switchp,
pkg_errlog  errlog 
)
extern

Connect an IPC endpoint from an address string. Supports child-side and parent-side pair addresses, reusable local IPC listener addresses returned by pkg_ipc_addr(), plus TCP loopback. Callers should treat local IPC listener addresses as opaque strings. Returns pkg_conn* on success, PKC_ERROR on failure.

◆ pkg_ipc_addr()

int pkg_ipc_addr ( char addr,
size_t  len,
const char name_hint 
)
extern

Create an opaque local IPC listener address suitable for this process.

The resulting address string is for local same-host communication and is intended to be passed unchanged to a server's pkg_listen() and client-side pkg_connect_addr() calls. It does not bind the listener itself. The concrete transport is selected by libpkg for the current platform. Current implementations include POSIX FIFO/UNIX-domain transports and Windows named pipes; callers must not parse the returned address. Platforms may support inherited endpoint IPC via pkg_pair() even when they do not provide a reusable listener transport here.

Returns 0 on success, -1 if no local listener transport is available.

◆ pkg_addr_is_ipc_listener()

int pkg_addr_is_ipc_listener ( const char addr)
extern

Return non-zero when addr names a reusable listener-style IPC endpoint, as opposed to a single inherited connected endpoint.

◆ pkg_connect_env()

struct pkg_conn * pkg_connect_env ( const struct pkg_switch switchp,
pkg_errlog  errlog 
)
extern

Connect using the PKG_ADDR env var (child side).

◆ pkg_adopt_fds()

struct pkg_conn * pkg_adopt_fds ( int  rfd,
int  wfd,
const struct pkg_switch switchp,
pkg_errlog  errlog 
)
extern

Wrap an already-open fd pair into a pkg_conn.

◆ pkg_adopt_stdio()

struct pkg_conn * pkg_adopt_stdio ( const struct pkg_switch switchp,
pkg_errlog  errlog 
)
extern

Wrap stdin(0)/stdout(1) as a pkg connection (inetd/pipe mode).

◆ pkg_move_high_fd()

int pkg_move_high_fd ( struct pkg_conn pc,
int  min_fd 
)
extern

Move the connection's fds above min_fd. Returns 0 on success, -1 on error.

◆ pkg_listen()

pkg_listener_t * pkg_listen ( const char service,
const char iface_or_null,
int  backlog,
pkg_errlog  errlog 
)
extern

◆ pkg_accept()

struct pkg_conn * pkg_accept ( pkg_listener_t L,
const struct pkg_switch switchp,
pkg_errlog  errlog,
int  nonblocking 
)
extern

◆ pkg_get_listener_fd()

int pkg_get_listener_fd ( const pkg_listener_t L)
extern

◆ pkg_get_listener_port()

int pkg_get_listener_port ( const pkg_listener_t L)
extern

◆ pkg_listener_close()

void pkg_listener_close ( pkg_listener_t L)
extern

◆ pkg_mux_create()

pkg_mux_t * pkg_mux_create ( void  )
extern

◆ pkg_mux_destroy()

void pkg_mux_destroy ( pkg_mux_t m)
extern

◆ pkg_mux_add_conn()

int pkg_mux_add_conn ( pkg_mux_t m,
const struct pkg_conn pc 
)
extern

◆ pkg_mux_add_listener()

int pkg_mux_add_listener ( pkg_mux_t m,
const pkg_listener_t L 
)
extern

◆ pkg_mux_add_fd()

int pkg_mux_add_fd ( pkg_mux_t m,
int  fd,
int  is_socket 
)
extern

◆ pkg_mux_remove_fd()

void pkg_mux_remove_fd ( pkg_mux_t m,
int  fd 
)
extern

◆ pkg_mux_wait()

int pkg_mux_wait ( pkg_mux_t m,
int  timeout_ms 
)
extern

◆ pkg_mux_is_ready_conn()

int pkg_mux_is_ready_conn ( const pkg_mux_t m,
const struct pkg_conn pc 
)
extern

◆ pkg_mux_is_ready_listener()

int pkg_mux_is_ready_listener ( const pkg_mux_t m,
const pkg_listener_t L 
)
extern

◆ pkg_mux_is_ready_fd()

int pkg_mux_is_ready_fd ( const pkg_mux_t m,
int  fd 
)
extern

◆ pkg_gshort()

unsigned short pkg_gshort ( char buf)
extern

Get a 16-bit short from a char[2] array

◆ pkg_glong()

unsigned long pkg_glong ( char buf)
extern

Get a 32-bit long from a char[4] array

◆ pkg_pshort()

char * pkg_pshort ( char buf,
unsigned short  s 
)
extern

Put a 16-bit short into a char[2] array

◆ pkg_plong()

char * pkg_plong ( char buf,
unsigned long  l 
)
extern

Put a 32-bit long into a char[4] array

◆ pkg_version()

const char * pkg_version ( void  )
extern

returns a human-readable string describing this version of the LIBPKG library.