9. RPC RTL Client Routines

Introduction

This chapter is for RPC programmers. It documents the client routines in the RPC Run-Time Library (RTL). These routines are the programming interface to RPC.

Common Arguments

Many client, Port Mapper, and server routines use the same arguments.

The below table lists these arguments and defines their purpose. Arguments that are unique to each routine are documented together with their respective routines in this and the following chapters

Argument

Purpose

args_ptr

Address of the buffer to contain the decoded RPC arguments.

auth

RPC authentication client handle created by the authnone_create, authunix_create, or authunix_create_default routine.

clnt

Client handle returned by any of the client create routines.

in

Input arguments for the service procedure.

inproc

XDR routine that encodes input arguments.

out

Results of the remote procedure call.

outproc

XDR routine that decodes output arguments.

procnum

Number of the service procedure.

prognum

Program number of the service program.

protocol

Transport protocol for the service. Must be IPPROTO_UDP or IPPROTO_TCP.

s

String containing the message of your choice. The routines append an error message to this string.

sockp

Socket to be used for this remote procedure call. If sockp is RPC_ANYSOCK, the routine creates a new socket and defines sockp. The clnt_destroy routine closes the socket.

 

If sockp is a value other than RPC_ANYSOCK, the routine uses this socket and ignores the internet address of the server.

versnum

Version number of the service program.

xdr_args

XDR procedure that describes the RPC arguments.

xdrs

Structure containing XDR encoding and decoding information.

xprt

RPC server handle.

 

Client Routines

The client routines are called by the client main program or the client stub procedures.

The following sections describe each client routine in detail.

 

 

 

 


 

auth_destroy

A macro that destroys authentication information associated with an authentication handle.

 

Format

void auth_destroy(AUTH *auth)

 

Argument

auth

RPC authentication client handle created by the authnone_create, authunix_create, or authunix_create_default routine.

 

Description

Use auth_destroy to free memory that was allocated for authentication handles. This routine undefines the value of auth by deallocating private data structures.

Do not use this memory space after auth_destroy has completed. You no longer own it.

 

 

 

 

 


 

authnone_create

Creates and returns a null RPC authentication handle for the client process.

 

Format

AUTH *authnone_create();

 

Arguments

None.

 

Description

This routine is for client processes that require no authentication. RPC uses it as a default when it creates a client handle.

 

 

 

 

 


 

authunix_create

Creates and returns an RPC authentication handle for the client process. Use this routine when the server requires UNIX-style authentication.

 

Format

AUTH *authunix_create (char *host, int uid, int gid, int len, int gids);

 

Arguments

host

Address of the name of the host that created the authentication information. This is usually the local host running the client process.

uid

User ID of the person who is executing this process.

gid

User's group ID.

len

Number of elements in the *gids array.

gids

Address of the array of groups to which the user belongs.

 

Description

Since the client does not validate the uid and gid, it is easy to impersonate an unauthorized user. Choose values the server expects to receive. The application must provide OpenVMS-to-UNIX authorization mapping.

You can use a Socket Library lookup routine to get the host name.

 

 

 

 

 


 

authunix_create_default

Calls the authunix_create routine and provides default values as arguments.

 

Format

AUTH *authunix_create_default()

 

Arguments

See below.

 

Description

Like the authunix_create routine, authunix_create_default provides UNIX-style authentication for the client process. However, authunix_create_default does not require you to enter any arguments. Instead, this routine provides default values for the arguments used by authunix_create, listed in the table below. 

Argument

Default Value

host

local host domain name

uid

getuid()

gid

getgid()

len

0

gids

0

 

You can replace this call with authunix_create and provide appropriate values.

 

Example

auth_destroy(client->cl_auth);
client->cl_auth = authunix_create_default();

This example overrides the authnone_create routine, where client is the value returned by the clnt_create, clntraw_create, clnttcp_create, or clntudp_create routine.

 

 

 

 

 


 

 

callrpc

Format

int callrpc (char *host, u_long prognum, u_long versnum, u_long procnum, xdrproc_t inproc, u_char *in, xdrproc_t outproc, u_char *out);

 

Arguments

host

Host where the procedure resides.

prognum, versnum, procnum, inproc, in, outproc, out

See the Common Arguments table for a description of the above arguments.

Description

The callrpc routine performs the same functions as the clnt_create and clnt_destroy routines.

Since the callrpc routine uses the UDP transport protocol, messages can be no larger than 8Kbytes. This routine does not allow you to control timeouts or authentication.

If you want to use the TCP transport, use the clnt_create or clnttcp_create routine.

 

Returns

The callrpc routine returns zero if it succeeds, and the value of enum clnt_stat cast to an integer if it fails.

You can use the clnt_perrno routine to translate failure status codes into messages.

 

 

 

 

 


 

clnt_broadcast

Broadcasts a remote procedure call to all local networks, using the broadcast address.

 

Format

enum clnt_stat clnt_broadcast (u_long prognum, u_long versnum, u_long procnum, xdrproc_t inproc, u_char *in, xdrproc_t outproc, u_char *out, resultproc_t eachresult);

 

Arguments

prognum, versnum, procnum, inproc, in, outproc, out

See the Common Arguments table for a description of the above arguments.

eachresult

Each time clnt_broadcast receives a response, it calls the eachresult routine. If eachresult returns zero, clnt_broadcast waits for more replies. If eachresult returns a nonzero value, clnt_broadcast stops waiting for replies. The eachresult routine uses this form:

int eachresult(u_char *out, struct sockaddr_in * addr)

out

Contains the results of the remote procedure call, in the local data format.

*addr

Is the address of the host that sent the results.

 

Description

The clnt_broadcast routine performs the same functions as the callrpc routine. However, clnt_broadcast sends a message to all local networks, using the broadcast address. The clnt_broadcast routine uses the UDP protocol.

The below table indicates how large a broadcast message can be.

Line

Maximum Size

Ethernet

1500 bytes

proNet

2044 bytes

Returns

This routine returns diagnostic values defined in the CLNT.H file for enum clnt_stat.

 

 

 

 

 


 

clnt_call

A macro that calls a remote procedure.

 

Format

enum clnt_stat clnt_call (CLIENT *clnt, u_long procnum, xdrproc_t inproc, u_char *in, xdrproc_t outproc, u_char *out, struct timeval tout);

 

Arguments

clnt, procnum, inproc, in, outproc, out

See the Common Arguments table for a description of the above arguments.

tout

Time allowed for the results to return to the client, in seconds and microseconds. If you use the clnt_control routine to change the CLSET_TIMEOUT code, this argument is ignored.

 

Description

Use the clnt_call routine after using clnt_create. After you have finished with the client handle, use the clnt_destroy routine. You can use the clnt_perror routine to print messages for any errors that occurred.

 

Returns

This routine returns diagnostic values defined in the CLNT.H file for enum clnt_stat.

 

 

 

 

 


 

clnt_control

A macro that changes or retrieves information about an RPC client process.

 

Format

bool_t clnt_control(CLIENT *clnt, u_long code, void *info);

 

Arguments

clnt

Client handle returned by any of the client create routines.

code

Code listed in the below table.

Code

Type

Purpose

CLSET_TIMEOUT

struct timeval

Set total timeout

CLGET_TIMEOUT

struct timeval

Get total timeout

CLSET_RETRY_TIMEOUT*

struct timeval

Set retry timeout

CLGET_RETRY_TIMEOUT*

struct timeval

Get retry timeout

CLGET_SERVER_ADDR

struct sockaddr_in

Get server address

* Valid only for the UDP transport protocol.

The timeval is specified in seconds and microseconds. The total timeout is the length of time that the client waits for a reply. The default total timeout is 25 seconds.

The retry time is the length of time that UDP waits for the server to reply before transmitting the request. The default retry timeout is 5 seconds. You might want to increase the retry time if your network is slow.

For example, suppose the total timeout is 10 seconds and the retry time is five seconds. The client sends the request and waits five seconds. If the client does not receive a reply, it sends the request again. If the client does not receive a reply within five seconds, it does not send the request again.

If you use CLSET_TIMEOUT to set the timeout, the clnt_call routine ignores the timeout parameter it receives for all future calls.

info

Address of the information being changed or retrieved.

 

Returns

This routine returns TRUE if it succeeds, and FALSE if it fails.

 

 

 

 

 


 

clnt_create

Creates an RPC client handle.

 

Format

CLIENT *clnt_create(char *host, u_long prognum, u_long versnum, char *proto);

 

Arguments

host

Address of the string containing the name of the remote host where the server is located.

prognum, versnum

See the Common Arguments table for a description of the above arguments.

proto

Address of a string containing the name of the transport protocol. Valid values are UDP and TCP.

 

Description

The clnt_create routine creates an RPC client handle for prognum. An RPC client handle is a structure containing information about the RPC client. The client can use the UDP or TCP transport protocol.

This routine uses the Port Mapper. You cannot control the local port.

The default sizes of the send and receive buffers are 8800 bytes for the UDP transport, and 4000 bytes for the TCP transport.

The retry time for the UDP transport is five seconds.

Use the clnt_create routine instead of the callrpc or clnt_broadcast routines if you want to use one of the following:

·         The TCP transport

·         An authentication other than null

·         More than one active client at the same time

You can also use clntraw_create to use the IP protocol, clnttcp_create to use the TCP protocol, or clntudp_create to use the UDP protocol.

The clnt_create routine uses the global variable rpc_createerr. rpc_createerr is a structure that contains the most recent service creation error. Use rpc_createerr if you want the client program to handle the error. The value of rpc_createerr is set by any RPC client creation routine that does not succeed.

The rpc_createerr variable is defined in the CLNT.H file.

Returns

The clnt_create routine returns the address of the client handle, or zero (if it could not create the client handle).

If the clnt_create routine fails, you can use the clnt_pcreateerror routine to obtain diagnostic information.

 

 

 

 

 


 

clnt_destroy

A macro that destroys an RPC client handle.

 

Format

void clnt_destroy(CLIENT *clnt);

 

Argument

clnt

Client handle returned by any of the client create routines.

 

Description

The clnt_destroy routine destroys the client's RPC handle by deallocating all memory related to the handle. The client is undefined after the clnt_destroy call.

If the clnt_create routine had previously opened a socket, this routine closes the socket. Otherwise, the socket remains open.

 

 

 

 

 


 

clnt_geterr

A macro that returns an error code indicating why an RPC call failed.

 

Format

void clnt_geterr(CLIENT *clnt, struct rpc_err *errp);

 

Arguments

clnt

Client handle returned by any of the client create routines.

errp

Address of the structure containing information that indicates why an RPC call failed. This information is the same as clnt_stat contains, plus one of the following: the C error number, the range of server versions supported, or authentication errors.

 

Description

This routine is primarily for internal diagnostic use.

 

Example

#define PROGRAM 1
#define VERSION 1

CLIENT          *clnt;
struct rpc_err  err;

clnt = clnt_create("server name", PROGRAM, VERSION, "udp");

/* calls to RPC library */

clnt_geterr(clnt, &err);

This example creates a UDP client handle and performs some additional RPC processing. If an RPC call fails, clnt_geterr returns the error code.

 

 

 

 

 


 

clnt_pcreateerror / clnt_spcreateerror

Return a message indicating why RPC could not create a client handle.

 

Format

void clnt_pcreateerror(char *s);
char *clnt_spcreateerror(char *s);

 

Argument

s

String containing the message of your choice. The routines append an error message to this string.

 

Description

The clnt_pcreateerror routine prints a message to SYS$OUTPUT.

The clnt_spcreateerror routine returns the address of a string. Use this routine if:

·         You want to save the string.

·         You do not want to use printf to print the message.

·         The message format is different from the one that clnt_perrno supports.

The clnt_pcreateerror routine overwrites the string it returns, unless you save the results.

Use these routines when the clnt_create, clntraw_create, clnttcp_create, or clntudp_create routine fails.

 

 

 

 

 


 

clnt_perrno / clnt_sperrno

Return a message indicating why the callrpc or clnt_broadcast routine failed to create a client handle.

 

Format

void clnt_perrno (enum clnt_stat stat);
char *clnt_sperrno (enum clnt_stat stat);

 

Argument

stat

Appropriate error condition. Values for stat are defined in the CLNT.H file.

 

Description

The clnt_perrno routine prints a message to SYS$OUTPUT.

The clnt_sperrno routine returns the address of a string. Use this routine instead if:

·         You want to save the string.

·         You do not want to use printf to print the message.

·         The message format is different from the one that clnt_perrno supports.

To save the string, copy it into your own memory space.

 

 

 

 


 

clnt_perror / clnt_sperror

Return a message if the clnt_call routine fails.

Format

void clnt_perror (CLIENT *clnt, char *s);
char *clnt_sperror (CLIENT *clnt, char *s);

 

Arguments

clnt

See the Common Arguments table for a description of the above argument.

s

String containing the message to output.

 

Description

Use these routines after clnt_call.

The clnt_perrorc routine prints an error message to SYS$OUTPUT.

The clnt_sperror routine returns a string. Use this routine if:

·         You want to save the string.

·         You do not want to use printf to print the message.

·         The message format is different from the one that clnt_perror supports.

The clnt_sperror routine overwrites the string with each call. Copy the string into your own memory space if you want to save it.

 

 

 

 


 

clntraw_create

Returns an RPC client handle. The remote procedure call uses the IP transport.

 

Format

CLIENT *clntraw_create (struct sockaddr_in *addr, u_long prognum, u_long versnum, int *sockp, u_long sendsize, u_long recvsize);

 

Arguments

addr, prognum, versnum

See the Common Arguments table for a description of the above arguments.

sockp

Socket to be used for this remote procedure call. sockp can specify the local address and port number. If sockp is RPC_ANYSOCK, then a port number is assigned. The example shown for the clntudp_create routine shows how to set up sockp to specify a port. See the Common Arguments table for a description of sockp and RPC_ANYSOCK.

addr

Internet address of the host on which the server resides.

sendsize

Size of the send buffer. If you enter a value less than 100, then 4000 is used as the default.

recvsize

Size of the receive buffer. If you enter a value less than 100, then 4000 is used as the default.

 

Description

The clntraw_create routine creates an RPC client handle for addr, prognum, and versnum. The client uses the IP transport. The routine is similar to the clnt_create routine, except clnttcp_create allows you to specify a socket and buffer sizes. If you specify the port number as zero by using addr->sin_port, the Port Mapper provides the number of the port on which the remote program is listening.

The transport used to pass messages to the service is actually a buffer within the process's address space, so the corresponding RPC server should live in the same address space (see also svcraw_create). This allows simulation of RPC and getting RPC overheads, such as round-trip times, without kernel interference.

The clnttcp_create routine uses the global variable rpc_createerr, which is a structure that contains the most recent service creation error. Use rpc_createerr if you want the client program to handle the error. The value of rpc_createerr is set by any RPC client creation routine that does not succeed. The rpc_createerr variable is defined in the CLNT.H file.

 

Returns

The clntraw_createroutine returns the address of the client handle, or zero (if it could not create the client handle). If the routine fails, use the clnt_pcreateerror routine to obtain additional diagnostic information.

 

 

 

 


 

clnttcp_create

Returns an RPC client handle. The remote procedure call uses the TCP transport.

 

Format

CLIENT *clnttcp_create (struct sockaddr_in *addr, u_long prognum, u_long versnum, int *sockp, u_long sendsize, u_long recvsize);

 

Arguments

addr, prognum, versnum

See the Common Arguments table for a description of the above arguments.

sockp

Socket to be used for this remote procedure call. sockp can specify the local address and port number. If sockp is RPC_ANYSOCK, then a port number is assigned. The example shown for the clntudp_create routine shows how to set up sockp to specify a port. See the Common Arguments table for a description of sockp and RPC_ANYSOCK.

addr

Internet address of the host on which the server resides.

sendsize

Size of the send buffer. If you enter a value less than 100, then 4000 is used as the default.

recvsize

Size of the receive buffer. If you enter a value less than 100, then 4000 is used as the default.

 

Description

The clnttcp_create routine creates an RPC client handle for addr, prognum, and versnum. The client uses the TCP transport. The routine is similar to the clnt_create routine, except clnttcp_create allows you to specify a socket and buffer sizes. If you specify the port number as zero by using addr->sin_port, the Port Mapper provides the number of the port on which the remote program is listening.

The clnttcp_createroutine uses the global variable rpc_createerr. rpc_createerr is a structure that contains the most recent service creation error. Use rpc_createerr if you want the client program to handle the error. The value of rpc_createerr is set by any RPC client creation routine that does not succeed. The rpc_createerr variable is defined in the CLNT.H file.

 

Returns

The clnttcp_create routine returns the address of the client handle, or zero (if it could not create the client handle). If the routine fails, use the clnt_pcreateerror routine to obtain additional diagnostic information.

 

 

 

 


 

clntudp_create / clntudp_bufcreate

Returns an RPC client handle. The remote procedure call uses the UDP transport.

 

Format

CLIENT *clntudp_create (struct sockaddr_in *addr, u_long prognum, u_long versnum, struct timeval wait, int *sockp);

CLIENT *clntudp_bufcreate (struct sockaddr_in *addr, u_long prognum, u_long versnum, struct timeval wait, int *sockp, u_long sendsize, u_long recvsize);

 

Arguments

addr

Internet address of the host on which the server resides.

prognum, versnum, sockp

See the Common Arguments table for a description of the above arguments.

wait

Time interval the client waits before resending the call message. This value changes the CLSET_RETRY_TIMEOUT code. The clnt_call routine uses this value.

sendsize

Size of the send buffer. If you enter a value less than 100, then 4000 is used as the default.

recvsize

Size of the receive buffer. If you enter a value less than 100, then 4000 is used as the default.

 

Description

These routines create an RPC client handle for addr, prognum, and versnum. The client uses the UDP transport protocol.

If you specify the port number as zero by using addr->sin_port, the Port Mapper provides the number of the port on which the remote program is listening.

 

Note: Use the clntudp_create routine only for procedures that handle messages shorter than 8K bytes. Use the clntudp_bufcreate routine for procedures that handle messages longer than 8K bytes.

 

 

The clntudp_create routine uses the global variable rpc_createerr. rpc_createerr is a structure that contains the most recent service creation error. Use rpc_createerr if you want the client program to handle the error. The value of rpc_createerr is set by any RPC client creation routine that does not succeed.

The rpc_createerr variable is defined in the CLNT.H file.

 

Example

main()
{
  int     sock;
  u_long  prog = PROGRAM, vers = VERSION;
  CLIENT  *clnt;
  struct sockaddr_in      local_addr, remote_addr;
  struct timeval  timeout = { 35, 0},
                  retry = { 5, 0};

  remote_addr.sin_family = AF_INET;
  remote_addr.sin_port = 0;  /* consult the remote port mapper */
  remote_addr.sin_addr.s_addr = 0x04030201; /* internet
  addr 1.2.3.4 */

  local_addr.sin_family = AF_INET;
  local_addr.sin_port = 12345;                /* use port 12345 */
  local_addr.sin_addr.s_addr = 0x05030201;    /* internet addr 1.2.3.5 */

  sock = socket( AF_INET, SOCK_DGRAM, 0);

  /* bind the socket to the local addr */
  bind( sock, &local_addr, sizeof( local_addr));

  /* create a client that uses the local IA and port given above */
  clnt = clntudp_create( &remote_addr, prog, vers, retry, &sock);

  /* use a connection timeout of 35 seconds, not the default */
  clnt_control( clnt, CLSET_TIMEOUT, &timeout);


  /*call the server here*/
}

This example defines a socket structure, binds the socket, and creates a UDP client handle.

 

Returns

These routines return the address of the client handle, or zero (if they cannot create the client handle).

If these routines fail, you can obtain additional diagnostic information by using the clnt_pcreateerror routine.