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.
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. |
The client routines are called by the client main program or the client stub procedures.
The following sections describe each client routine in detail.
A macro that destroys authentication information associated with an authentication handle.
void auth_destroy(AUTH *auth)
auth
RPC authentication client handle created by the authnone_create, authunix_create, or authunix_create_default routine.
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.
Creates and returns a null RPC authentication handle for the client process.
AUTH *authnone_create();
None.
This routine is for client processes that require no authentication. RPC uses it as a default when it creates a client handle.
Creates and returns an RPC authentication handle for the client process. Use this routine when the server requires UNIX-style authentication.
AUTH *authunix_create (char *host, int uid, int gid, int len, int gids);
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.
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.
Calls the authunix_create routine and provides default values as arguments.
AUTH *authunix_create_default()
See below.
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.
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.
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);
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.
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.
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.
Broadcasts a remote procedure call to all local networks, using the broadcast address.
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);
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. |
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 |
This routine returns diagnostic values defined in the CLNT.H file for enum clnt_stat.
A macro that calls a remote procedure.
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);
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.
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.
This routine returns diagnostic values defined in the CLNT.H file for enum clnt_stat.
A macro that changes or retrieves information about an RPC client process.
bool_t clnt_control(CLIENT *clnt, u_long code, void *info);
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.
This routine returns TRUE if it succeeds, and FALSE if it fails.
Creates an RPC client handle.
CLIENT *clnt_create(char *host, u_long prognum, u_long versnum, char *proto);
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.
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.
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.
A macro that destroys an RPC client handle.
void clnt_destroy(CLIENT *clnt);
clnt
Client handle returned by any of the client create routines.
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.
A macro that returns an error code indicating why an RPC call failed.
void clnt_geterr(CLIENT *clnt, struct rpc_err *errp);
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.
This routine is primarily for internal diagnostic use.
#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.
Return a message indicating why RPC could not create a client handle.
void clnt_pcreateerror(char *s);
char *clnt_spcreateerror(char *s);
s
String containing the message of your choice. The routines append an error message to this string.
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.
Return a message indicating why the callrpc or clnt_broadcast routine failed to create a client handle.
void clnt_perrno (enum clnt_stat stat);
char *clnt_sperrno (enum clnt_stat stat);
stat
Appropriate error condition. Values for stat are defined in the CLNT.H file.
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.
Return a message if the clnt_call routine fails.
void clnt_perror (CLIENT *clnt, char *s);
char *clnt_sperror (CLIENT *clnt, char *s);
clnt
See the Common Arguments table for a description of the above argument.
s
String containing the message to output.
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.
Returns an RPC client handle. The remote procedure call uses the IP transport.
CLIENT *clntraw_create (struct sockaddr_in *addr, u_long prognum, u_long versnum, int *sockp, u_long sendsize, u_long recvsize);
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.
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.
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.
Returns an RPC client handle. The remote procedure call uses the TCP transport.
CLIENT *clnttcp_create (struct sockaddr_in *addr, u_long prognum, u_long versnum, int *sockp, u_long sendsize, u_long recvsize);
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.
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.
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.
Returns an RPC client handle. The remote procedure call uses the UDP transport.
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);
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.
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.
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.
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.