2 .\" Must use -- tbl and pic -- with this one
4 .\" @(#)rpc.prog.ms 2.3 88/08/11 4.0 RPCSRC
5 .\" $FreeBSD: src/lib/libc/rpc/PSD.doc/rpc.prog.ms,v 1.1.14.1 2000/11/24 09:36:30 ru Exp $
9 .if \\n%=1 .tl ''- % -''
13 .\" prevent excess underlining in nroff
15 .OH 'Remote Procedure Call Programming Guide''Page %'
16 .EH 'Page %''Remote Procedure Call Programming Guide'
18 \&Remote Procedure Call Programming Guide
20 .IX "Network Programming" "" "" "" PAGE MAJOR
21 .IX "RPC Programming Guide"
23 This document assumes a working knowledge of network theory. It is
24 intended for programmers who wish to write network applications using
25 remote procedure calls (explained below), and who want to understand
26 the RPC mechanisms usually hidden by the
30 is described in detail in the previous chapter, the
31 .I "\fBrpcgen\fP \fIProgramming Guide\fP".
35 .IX rpcgen "" \fIrpcgen\fP
36 Before attempting to write a network application, or to convert an
37 existing non-network application to run over the network, you may want to
38 understand the material in this chapter. However, for most applications,
39 you can circumvent the need to cope with the details presented here by using
42 .I "Generating XDR Routines"
43 section of that chapter contains the complete source for a working RPC
44 service\(ema remote directory listing service which uses
46 to generate XDR routines as well as client and server stubs.
49 What are remote procedure calls? Simply put, they are the high-level
50 communications paradigm used in the operating system.
51 RPC presumes the existence of
52 low-level networking mechanisms (such as TCP/IP and UDP/IP), and upon them
53 it implements a logical client to server communications system designed
54 specifically for the support of network applications. With RPC, the client
55 makes a procedure call to send a data packet to the server. When the
56 packet arrives, the server calls a dispatch routine, performs whatever
57 service is requested, sends back the reply, and the procedure call returns
64 The RPC interface can be seen as being divided into three layers.\**
66 For a complete specification of the routines in the remote procedure
72 .I "The Highest Layer:"
73 .IX RPC "The Highest Layer"
74 The highest layer is totally transparent to the operating system,
75 machine and network upon which is is run. It's probably best to
76 think of this level as a way of
79 a \fIpart of\fP RPC proper. Programmers who write RPC routines
80 should (almost) always make this layer available to others by way
81 of a simple C front end that entirely hides the networking.
83 To illustrate, at this level a program can simply make a call to
85 a C routine which returns the number of users on a remote machine.
86 The user is not explicitly aware of using RPC \(em they simply
87 call a procedure, just as they would call
90 .I "The Middle Layer:"
91 .IX RPC "The Middle Layer"
92 The middle layer is really \*QRPC proper.\*U Here, the user doesn't
93 need to consider details about sockets, the UNIX system, or other low-level
94 implementation mechanisms. They simply make remote procedure calls
95 to routines on other machines. The selling point here is simplicity.
96 It's this layer that allows RPC to pass the \*Qhello world\*U test \(em
97 simple things should be simple. The middle-layer routines are used
98 for most applications.
100 RPC calls are made with the system routines
105 The first two of these are the most fundamental:
107 obtains a unique system-wide procedure-identification number, and
109 actually executes a remote procedure call. At the middle level, a
112 is implemented by way of these two routines.
114 The middle layer is unfortunately rarely used in serious programming
115 due to its inflexibility (simplicity). It does not allow timeout
116 specifications or the choice of transport. It allows no UNIX
117 process control or flexibility in case of errors. It doesn't support
118 multiple kinds of call authentication. The programmer rarely needs
119 all these kinds of control, but one or two of them is often necessary.
121 .I "The Lowest Layer:"
122 .IX RPC "The Lowest Layer"
123 The lowest layer does allow these details to be controlled by the
124 programmer, and for that reason it is often necessary. Programs
125 written at this level are also most efficient, but this is rarely a
126 real issue \(em since RPC clients and servers rarely generate
129 Although this document only discusses the interface to C,
130 remote procedure calls can be made from any language.
131 Even though this document discusses RPC
132 when it is used to communicate
133 between processes on different machines,
134 it works just as well for communication
135 between different processes on the same machine.
142 Here is a diagram of the RPC paradigm:
144 \fBFigure 1-1\fI Network Communication with the Remote Reocedure Call\fR
147 L1: arrow down 1i "client " rjust "program " rjust
148 L2: line right 1.5i "\fIcallrpc\fP" "function"
149 move up 1.5i; line dotted down 6i; move up 4.5i
151 L3: arrow down 1i "invoke " rjust "service " rjust
152 L4: arrow right 1.5i "call" "service"
153 L5: arrow down 1i " service" ljust " executes" ljust
154 L6: arrow left 1.5i "\fIreturn\fP" "answer"
155 L7: arrow down 1i "request " rjust "completed " rjust
157 arrow left 1.5i "\fIreturn\fP" "reply"
158 L9: arrow down 1i "program " rjust "continues " rjust
159 line dashed down from L2 to L9
160 line dashed down from L4 to L7
161 line dashed up 1i from L3 "service " rjust "daemon " rjust
162 arrow dashed down 1i from L8
163 move right 1i from L3
164 box invis "Machine B"
165 move left 1.2i from L2; move down
166 box invis "Machine A"
171 \&Higher Layers of RPC
174 .IX "highest layer of RPC"
175 .IX RPC "highest layer"
177 Imagine you're writing a program that needs to know
178 how many users are logged into a remote machine.
179 You can do this by calling the RPC library routine
181 as illustrated below:
194 fprintf(stderr, "usage: rnusers hostname\en");
197 if ((num = rnusers(argv[1])) < 0) {
198 fprintf(stderr, "error: rnusers\en");
201 printf("%d users on %s\en", num, argv[1]);
206 RPC library routines such as
208 are in the RPC services library
210 Thus, the program above should be compiled with
213 % cc \fIprogram.c -lrpcsvc\fP
216 like the other RPC library routines, is documented in section 3R
218 .I "System Interface Manual for the Sun Workstation" ,
219 the same section which documents the standard Sun RPC services.
223 manual page for an explanation of the documentation strategy
224 for these services and their RPC protocols.
226 Here are some of the RPC service library routines available to the
229 \fBTable 3-3\fI RPC Service Library Routines\fR
237 rnusers&Return number of users on remote machine
238 rusers&Return information about users on remote machine
239 havedisk&Determine if remote machine has disk
240 rstats&Get performance data from remote kernel
241 rwall&Write to specified remote machines
242 yppasswd&Update user password in Yellow Pages
245 Other RPC services \(em for example
251 \(em are not available to the C programmer as library routines.
253 have RPC program numbers so they can be invoked with
255 which will be discussed in the next section. Most of them also
258 protocol description files. (The
260 protocol compiler radically simplifies the process of developing
261 network applications.
262 See the \fBrpcgen\fI Programming Guide\fR
263 for detailed information about
267 protocol description files).
271 .IX "intermediate layer of RPC"
272 .IX "RPC" "intermediate layer"
274 The simplest interface, which explicitly makes RPC calls, uses the
279 Using this method, the number of remote users can be gotten as follows:
285 #include <rpcsvc/rusers.h>
291 unsigned long nusers;
295 fprintf(stderr, "usage: nusers hostname\en");
298 if (stat = callrpc(argv[1],
299 RUSERSPROG, RUSERSVERS, RUSERSPROC_NUM,
300 xdr_void, 0, xdr_u_long, &nusers) != 0) {
304 printf("%d users on %s\en", nusers, argv[1]);
309 Each RPC procedure is uniquely defined by a program number,
310 version number, and procedure number. The program number
311 specifies a group of related remote procedures, each of
312 which has a different procedure number. Each program also
313 has a version number, so when a minor change is made to a
314 remote service (adding a new procedure, for example), a new
315 program number doesn't have to be assigned. When you want
316 to call a procedure to find the number of remote users, you
317 look up the appropriate program, version and procedure numbers
318 in a manual, just as you look up the name of a memory allocator
319 when you want to allocate memory.
321 The simplest way of making remote procedure calls is with the the RPC
324 It has eight parameters. The first is the name of the remote server
325 machine. The next three parameters are the program, version, and procedure
326 numbers\(emtogether they identify the procedure to be called.
327 The fifth and sixth parameters are an XDR filter and an argument to
328 be encoded and passed to the remote procedure.
329 The final two parameters are a filter for decoding the results
330 returned by the remote procedure and a pointer to the place where
331 the procedure's results are to be stored. Multiple arguments and
332 results are handled by embedding them in structures. If
334 completes successfully, it returns zero; else it returns a nonzero
335 value. The return codes (of type
336 .IX "enum clnt_stat (in RPC programming)" "" "\fIenum clnt_stat\fP (in RPC programming)"
337 cast into an integer) are found in
340 Since data types may be represented differently on different machines,
342 needs both the type of the RPC argument, as well as
343 a pointer to the argument itself (and similarly for the result). For
345 the return value is an
351 as its first return parameter, which says
352 that the result is of type
356 as its second return parameter,
357 which is a pointer to where the long result will be placed. Since
359 takes no argument, the argument parameter of
364 After trying several times to deliver a message, if
366 gets no answer, it returns with an error code.
367 The delivery mechanism is UDP,
368 which stands for User Datagram Protocol.
369 Methods for adjusting the number of retries
370 or for using a different protocol require you to use the lower
371 layer of the RPC library, discussed later in this document.
372 The remote server procedure
373 corresponding to the above might look like this:
382 unsigned long nusers;
386 * Code here to compute the number of users
387 * and place result in variable \fInusers\fP.
390 return((char *)&nusers);
394 It takes one argument, which is a pointer to the input
395 of the remote procedure call (ignored in our example),
396 and it returns a pointer to the result.
397 In the current version of C,
398 character pointers are the generic pointers,
399 so both the input argument and the return value are cast to
402 Normally, a server registers all of the RPC calls it plans
403 to handle, and then goes into an infinite loop waiting to service requests.
404 In this example, there is only a single procedure
405 to register, so the main body of the server would look like this:
412 #include <rpcsvc/rusers.h>
418 registerrpc(RUSERSPROG, RUSERSVERS, RUSERSPROC_NUM,
419 nuser, xdr_void, xdr_u_long);
420 svc_run(); /* \fINever returns\fP */
421 fprintf(stderr, "Error: svc_run returned!\en");
428 routine registers a C procedure as corresponding to a
429 given RPC procedure number. The first three parameters,
434 are the program, version, and procedure numbers
435 of the remote procedure to be registered;
437 is the name of the local procedure that implements the remote
442 are the XDR filters for the remote procedure's arguments and
443 results, respectively. (Multiple arguments or multiple results
444 are passed as structures).
446 Only the UDP transport mechanism can use
448 thus, it is always safe in conjunction with calls generated by
452 Warning: the UDP transport mechanism can only deal with
453 arguments and results less than 8K bytes in length.
456 After registering the local procedure, the server program's
459 the RPC library's remote procedure dispatcher. It is this
460 function that calls the remote procedures in response to RPC
461 call messages. Note that the dispatcher takes care of decoding
462 remote procedure arguments and encoding results, using the XDR
463 filters specified when the remote procedure was registered.
465 \&Assigning Program Numbers
466 .IX "program number assignment"
467 .IX "assigning program numbers"
469 Program numbers are assigned in groups of
471 according to the following chart:
474 0x0 - 0x1fffffff \fRDefined by Sun\fP
475 0x20000000 - 0x3fffffff \fRDefined by user\fP
476 0x40000000 - 0x5fffffff \fRTransient\fP
477 0x60000000 - 0x7fffffff \fRReserved\fP
478 0x80000000 - 0x9fffffff \fRReserved\fP
479 0xa0000000 - 0xbfffffff \fRReserved\fP
480 0xc0000000 - 0xdfffffff \fRReserved\fP
481 0xe0000000 - 0xffffffff \fRReserved\fP
484 Sun Microsystems administers the first group of numbers, which
485 should be identical for all Sun customers. If a customer
486 develops an application that might be of general interest, that
487 application should be given an assigned number in the first
488 range. The second group of numbers is reserved for specific
489 customer applications. This range is intended primarily for
490 debugging new programs. The third group is reserved for
491 applications that generate program numbers dynamically. The
492 final groups are reserved for future use, and should not be
495 To register a protocol specification, send a request by network
503 Mountain View, CA 94043
505 Please include a compilable
507 \*Q.x\*U file describing your protocol.
508 You will be given a unique program number in return.
509 .IX RPC administration
510 .IX administration "of RPC"
512 The RPC program numbers and protocol specifications
513 of standard Sun RPC services can be
514 found in the include files in
515 .I "/usr/include/rpcsvc" .
516 These services, however, constitute only a small subset
517 of those which have been registered. The complete list of
518 registered programs, as of the time when this manual was
521 \fBTable 3-2\fI RPC Registered Programs\fR
526 RPC Number&Program&Description
530 100000&PMAPPROG&portmapper
531 100001&RSTATPROG&remote stats
532 100002&RUSERSPROG&remote users
534 100004&YPPROG&Yellow Pages
535 100005&MOUNTPROG&mount demon
536 100006&DBXPROG&remote dbx
537 100007&YPBINDPROG&yp binder
538 100008&WALLPROG&shutdown msg
539 100009&YPPASSWDPROG&yppasswd server
540 100010ÐERSTATPROGðer stats
541 100011&RQUOTAPROG&disk quotas
542 100012&SPRAYPROG&spray packets
543 100013&IBM3270PROG&3270 mapper
544 100014&IBMRJEPROG&RJE mapper
545 100015&SELNSVCPROG&selection service
546 100016&RDATABASEPROG&remote database access
547 100017&REXECPROG&remote execution
548 100018&ALICEPROG&Alice Office Automation
549 100019&SCHEDPROG&scheduling service
550 100020&LOCKPROG&local lock manager
551 100021&NETLOCKPROG&network lock manager
552 100022&X25PROG&x.25 inr protocol
553 100023&STATMON1PROG&status monitor 1
554 100024&STATMON2PROG&status monitor 2
555 100025&SELNLIBPROG&selection library
556 100026&BOOTPARAMPROG&boot parameters service
557 100027&MAZEPROG&mazewars game
558 100028&YPUPDATEPROG&yp update
559 100029&KEYSERVEPROG&key server
560 100030&SECURECMDPROG&secure login
561 100031&NETFWDIPROG&nfs net forwarder init
562 100032&NETFWDTPROG&nfs net forwarder trans
563 100033&SUNLINKMAP_PROG&sunlink MAP
564 100034&NETMONPROG&network monitor
565 100035&DBASEPROG&lightweight database
566 100036&PWDAUTHPROG&password authorization
567 100037&TFSPROG&translucent file svc
568 100038&NSEPROG&nse server
569 100039&NSE_ACTIVATE_PROG&nse activate daemon
571 150001&PCNFSDPROG&pc passwd authorization
573 200000&PYRAMIDLOCKINGPROG&Pyramid-locking
574 200001&PYRAMIDSYS5&Pyramid-sys5
575 200002&CADDS_IMAGE&CV cadds_image
577 300001&ADT_RFLOCKPROG&ADT file locking
580 \&Passing Arbitrary Data Types
581 .IX "arbitrary data types"
583 In the previous example, the RPC call passes a single
585 RPC can handle arbitrary data structures, regardless of
586 different machines' byte orders or structure layout conventions,
587 by always converting them to a network standard called
588 .I "External Data Representation"
590 sending them over the wire.
591 The process of converting from a particular machine representation
592 to XDR format is called
594 and the reverse process is called
596 The type field parameters of
600 can be a built-in procedure like
602 in the previous example, or a user supplied one.
603 XDR has these built-in type routines:
604 .IX RPC "built-in routines"
607 xdr_int() xdr_u_int() xdr_enum()
608 xdr_long() xdr_u_long() xdr_bool()
609 xdr_short() xdr_u_short() xdr_wrapstring()
610 xdr_char() xdr_u_char()
612 Note that the routine
614 exists, but cannot be used with
618 which only pass two parameters to their XDR routines.
620 has only two parameters, and is thus OK. It calls
623 As an example of a user-defined type routine,
624 if you wanted to send the structure
637 callrpc(hostname, PROGNUM, VERSNUM, PROCNUM,
638 xdr_simple, &simple ...);
648 xdr_simple(xdrsp, simplep)
650 struct simple *simplep;
652 if (!xdr_int(xdrsp, &simplep->a))
654 if (!xdr_short(xdrsp, &simplep->b))
660 An XDR routine returns nonzero (true in the sense of C) if it
661 completes successfully, and zero otherwise.
662 A complete description of XDR is in the
663 .I "XDR Protocol Specification"
664 section of this manual, only few implementation examples are
667 In addition to the built-in primitives,
668 there are also the prefabricated building blocks:
671 xdr_array() xdr_bytes() xdr_reference()
672 xdr_vector() xdr_union() xdr_pointer()
673 xdr_string() xdr_opaque()
675 To send a variable array of integers,
676 you might package them up as a structure like this
684 and make an RPC call such as
687 callrpc(hostname, PROGNUM, VERSNUM, PROCNUM,
688 xdr_varintarr, &arr...);
696 xdr_varintarr(xdrsp, arrp)
698 struct varintarr *arrp;
700 return (xdr_array(xdrsp, &arrp->data, &arrp->arrlnth,
701 MAXLEN, sizeof(int), xdr_int));
704 This routine takes as parameters the XDR handle,
705 a pointer to the array, a pointer to the size of the array,
706 the maximum allowable array size,
707 the size of each array element,
708 and an XDR routine for handling each array element.
711 If the size of the array is known in advance, one can use
713 which serializes fixed-length arrays.
719 xdr_intarr(xdrsp, intarr)
725 return (xdr_vector(xdrsp, intarr, SIZE, sizeof(int),
731 XDR always converts quantities to 4-byte multiples when serializing.
732 Thus, if either of the examples above involved characters
733 instead of integers, each character would occupy 32 bits.
734 That is the reason for the XDR routine
738 except that it packs characters;
740 has four parameters, similar to the first four parameters of
742 For null-terminated strings, there is also the
744 routine, which is the same as
746 without the length parameter.
747 On serializing it gets the string length from
749 and on deserializing it creates a null-terminated string.
751 Here is a final example that calls the previously written
753 as well as the built-in functions
757 which chases pointers:
761 struct finalexample {
763 struct simple *simplep;
766 xdr_finalexample(xdrsp, finalp)
768 struct finalexample *finalp;
771 if (!xdr_string(xdrsp, &finalp->string, MAXSTRLEN))
773 if (!xdr_reference(xdrsp, &finalp->simplep,
774 sizeof(struct simple), xdr_simple);
779 Note that we could as easily call
784 \&Lowest Layer of RPC
785 .IX "lowest layer of RPC"
786 .IX "RPC" "lowest layer"
788 In the examples given so far,
789 RPC takes care of many details automatically for you.
790 In this section, we'll show you how you can change the defaults
791 by using lower layers of the RPC library.
792 It is assumed that you are familiar with sockets
793 and the system calls for dealing with them.
795 There are several occasions when you may need to use lower layers of
796 RPC. First, you may need to use TCP, since the higher layer uses UDP,
797 which restricts RPC calls to 8K bytes of data. Using TCP permits calls
798 to send long streams of data.
799 For an example, see the
801 section below. Second, you may want to allocate and free memory
802 while serializing or deserializing with XDR routines.
803 There is no call at the higher level to let
804 you free memory explicitly.
805 For more explanation, see the
806 .I "Memory Allocation with XDR"
808 Third, you may need to perform authentication
809 on either the client or server side, by supplying
810 credentials or verifying them.
811 See the explanation in the
815 \&More on the Server Side
816 .IX RPC "server side"
820 program shown below does the same thing as the one using
822 above, but is written using a lower layer of the RPC package:
829 #include <rpcsvc/rusers.h>
836 transp = svcudp_create(RPC_ANYSOCK);
838 fprintf(stderr, "can't create an RPC server\en");
841 pmap_unset(RUSERSPROG, RUSERSVERS);
842 if (!svc_register(transp, RUSERSPROG, RUSERSVERS,
843 nuser, IPPROTO_UDP)) {
844 fprintf(stderr, "can't register RUSER service\en");
847 svc_run(); /* \fINever returns\fP */
848 fprintf(stderr, "should never reach this point\en");
852 struct svc_req *rqstp;
855 unsigned long nusers;
857 switch (rqstp->rq_proc) {
859 if (!svc_sendreply(transp, xdr_void, 0))
860 fprintf(stderr, "can't reply to RPC call\en");
865 * Code here to compute the number of users
866 * and assign it to the variable \fInusers\fP
869 if (!svc_sendreply(transp, xdr_u_long, &nusers))
870 fprintf(stderr, "can't reply to RPC call\en");
873 svcerr_noproc(transp);
879 First, the server gets a transport handle, which is used
880 for receiving and replying to RPC messages.
885 If you require a more reliable protocol, call
892 the RPC library creates a socket
893 on which to receive and reply to RPC calls. Otherwise,
895 expects its argument to be a valid socket number.
896 If you specify your own socket, it can be bound or unbound.
897 If it is bound to a port by the user, the port numbers of
901 (the low-level client routine) must match.
903 If the user specifies the
905 argument, the RPC library routines will open sockets.
906 Otherwise they will expect the user to do so. The routines
910 will cause the RPC library routines to
912 their socket if it is not bound already.
914 A service may choose to register its port number with the
915 local portmapper service. This is done is done by specifying
916 a non-zero protocol number in
918 Incidently, a client can discover the server's port number by
919 consulting the portmapper on their server's machine. This can
920 be done automatically by specifying a zero port number in
923 .I clnttcp_create ().
927 the next step is to call
931 server crashed earlier,
932 any previous trace of it is erased before restarting.
937 from the port mapper's tables.
939 Finally, we associate the program number for
943 The final argument to
945 is normally the protocol being used,
946 which, in this case, is
950 there are no XDR routines involved
951 in the registration process.
952 Also, registration is done on the program,
953 rather than procedure, level.
957 must call and dispatch the appropriate XDR routines
958 based on the procedure number.
960 two things are handled by
964 handles automatically.
965 The first is that procedure
967 (currently zero) returns with no results.
968 This can be used as a simple test
969 for detecting if a remote program is running.
970 Second, there is a check for invalid procedure numbers.
973 is called to handle the error.
976 The user service routine serializes the results and returns
977 them to the RPC caller via
979 Its first parameter is the
981 handle, the second is the XDR routine,
982 and the third is a pointer to the data to be returned.
983 Not illustrated above is how a server
984 handles an RPC program that receives data.
985 As an example, we can add a procedure
987 which has an argument
993 depending on whether there are nusers logged on.
994 It would look like this:
998 case RUSERSPROC_BOOL: {
1000 unsigned nuserquery;
1002 if (!svc_getargs(transp, xdr_u_int, &nuserquery) {
1003 svcerr_decode(transp);
1008 * Code to set \fInusers\fP = number of users
1011 if (nuserquery == nusers)
1015 if (!svc_sendreply(transp, xdr_bool, &bool)) {
1016 fprintf(stderr, "can't reply to RPC call\en");
1024 The relevant routine is
1028 handle, the XDR routine,
1029 and a pointer to where the input is to be placed as arguments.
1031 \&Memory Allocation with XDR
1032 .IX "memory allocation with XDR"
1033 .IX XDR "memory allocation"
1035 XDR routines not only do input and output,
1036 they also do memory allocation.
1037 This is why the second parameter of
1039 is a pointer to an array, rather than the array itself.
1044 allocates space for the array and returns a pointer to it,
1045 putting the size of the array in the third argument.
1046 As an example, consider the following XDR routine
1048 which deals with a fixed array of bytes with length
1053 xdr_chararr1(xdrsp, chararr)
1062 return (xdr_bytes(xdrsp, &p, &len, SIZE));
1065 If space has already been allocated in
1067 it can be called from a server like this:
1073 svc_getargs(transp, xdr_chararr1, chararr);
1075 If you want XDR to do the allocation,
1076 you would have to rewrite this routine in the following way:
1080 xdr_chararr2(xdrsp, chararrp)
1087 return (xdr_bytes(xdrsp, charrarrp, &len, SIZE));
1090 Then the RPC call might look like this:
1097 svc_getargs(transp, xdr_chararr2, &arrptr);
1100 * Use the result here
1103 svc_freeargs(transp, xdr_chararr2, &arrptr);
1105 Note that, after being used, the character array can be freed with
1108 will not attempt to free any memory if the variable indicating it
1109 is NULL. For example, in the the routine
1110 .I xdr_finalexample (),
1113 was NULL, then it would not be freed. The same is true for
1114 .I finalp->simplep .
1116 To summarize, each XDR routine is responsible
1117 for serializing, deserializing, and freeing memory.
1118 When an XDR routine is called from
1120 the serializing part is used.
1123 the deserializer is used.
1124 And when called from
1126 the memory deallocator is used. When building simple examples like those
1127 in this section, a user doesn't have to worry
1128 about the three modes.
1130 .I "External Data Representation: Sun Technical Notes"
1131 for examples of more sophisticated XDR routines that determine
1132 which of the three modes they are in and adjust their behavior accordingly.
1136 .IX RPC "calling side"
1140 you have no control over the RPC delivery
1141 mechanism or the socket used to transport the data.
1142 To illustrate the layer of RPC that lets you adjust these
1143 parameters, consider the following code to call the
1151 #include <rpc/rpc.h>
1153 #include <rpcsvc/rusers.h>
1154 #include <sys/socket.h>
1155 #include <sys/time.h>
1163 struct timeval pertry_timeout, total_timeout;
1164 struct sockaddr_in server_addr;
1165 int sock = RPC_ANYSOCK;
1166 register CLIENT *client;
1167 enum clnt_stat clnt_stat;
1168 unsigned long nusers;
1171 fprintf(stderr, "usage: nusers hostname\en");
1174 if ((hp = gethostbyname(argv[1])) == NULL) {
1175 fprintf(stderr, "can't get addr for %s\en",argv[1]);
1178 pertry_timeout.tv_sec = 3;
1179 pertry_timeout.tv_usec = 0;
1180 bcopy(hp->h_addr, (caddr_t)&server_addr.sin_addr,
1182 server_addr.sin_family = AF_INET;
1183 server_addr.sin_port = 0;
1184 if ((client = clntudp_create(&server_addr, RUSERSPROG,
1185 RUSERSVERS, pertry_timeout, &sock)) == NULL) {
1186 clnt_pcreateerror("clntudp_create");
1189 total_timeout.tv_sec = 20;
1190 total_timeout.tv_usec = 0;
1191 clnt_stat = clnt_call(client, RUSERSPROC_NUM, xdr_void,
1192 0, xdr_u_long, &nusers, total_timeout);
1193 if (clnt_stat != RPC_SUCCESS) {
1194 clnt_perror(client, "rpc");
1197 clnt_destroy(client);
1204 The low-level version of
1210 pointer rather than a host name. The parameters to
1214 pointer, the procedure number,
1215 the XDR routine for serializing the argument,
1216 a pointer to the argument,
1217 the XDR routine for deserializing the return value,
1218 a pointer to where the return value will be placed,
1219 and the time in seconds to wait for a reply.
1223 pointer is encoded with the transport mechanism.
1225 uses UDP, thus it calls
1229 pointer. To get TCP (Transmission Control Protocol), you would use
1230 .I clnttcp_create() .
1234 are the server address, the program number, the version number,
1235 a timeout value (between tries), and a pointer to a socket.
1236 The final argument to
1238 is the total time to wait for a response.
1239 Thus, the number of tries is the
1241 timeout divided by the
1248 always deallocates the space associated with the
1250 handle. It closes the socket associated with the
1252 handle, however, only if the RPC library opened it. It the
1253 socket was opened by the user, it stays open. This makes it
1254 possible, in cases where there are multiple client handles
1255 using the same socket, to destroy one handle without closing
1256 the socket that other handles are using.
1258 To make a stream connection, the call to
1260 is replaced with a call to
1261 .I clnttcp_create() .
1264 clnttcp_create(&server_addr, prognum, versnum, &sock,
1265 inputsize, outputsize);
1267 There is no timeout argument; instead, the receive and send buffer
1268 sizes must be specified. When the
1270 call is made, a TCP connection is established.
1271 All RPC calls using that
1273 handle would use this connection.
1274 The server side of an RPC call using TCP has
1277 .I svctcp_create() .
1280 transp = svctcp_create(RPC_ANYSOCK, 0, 0);
1282 The last two arguments to
1284 are send and receive sizes respectively. If `0' is specified for
1285 either of these, the system chooses a reasonable default.
1288 \&Other RPC Features
1289 .IX "RPC" "miscellaneous features"
1290 .IX "miscellaneous RPC features"
1292 This section discusses some other aspects of RPC
1293 that are occasionally useful.
1295 \&Select on the Server Side
1296 .IX RPC select() RPC \fIselect()\fP
1297 .IX select() "" \fIselect()\fP "on the server side"
1299 Suppose a process is processing RPC requests
1300 while performing some other activity.
1301 If the other activity involves periodically updating a data structure,
1302 the process can set an alarm signal before calling
1304 But if the other activity
1305 involves waiting on a a file descriptor, the
1319 int dtbsz = getdtablesize();
1323 switch (select(dtbsz, &readfds, NULL,NULL,NULL)) {
1333 svc_getreqset(&readfds);
1346 All you need to know are the file descriptors
1347 of the socket(s) associated with the programs you are waiting on.
1348 Thus you can have your own
1350 .IX select() "" \fIselect()\fP
1351 that waits on both the RPC socket,
1352 and your own descriptors. Note that
1354 is a bit mask of all the file descriptors that RPC is using for
1355 services. It can change everytime that
1357 RPC library routine is called, because descriptors are constantly
1358 being opened and closed, for example for TCP connections.
1366 is a daemon that converts RPC program numbers
1367 into DARPA protocol port numbers; see the
1369 man page. You can't do broadcast RPC without the portmapper.
1370 Here are the main differences between
1371 broadcast RPC and normal RPC calls:
1373 Normal RPC expects one answer, whereas
1374 broadcast RPC expects many answers
1375 (one or more answer from each responding machine).
1377 Broadcast RPC can only be supported by packet-oriented (connectionless)
1378 transport protocols like UPD/IP.
1380 The implementation of broadcast RPC
1381 treats all unsuccessful responses as garbage by filtering them out.
1382 Thus, if there is a version mismatch between the
1383 broadcaster and a remote service,
1384 the user of broadcast RPC never knows.
1386 All broadcast messages are sent to the portmap port.
1387 Thus, only services that register themselves with their portmapper
1388 are accessible via the broadcast RPC mechanism.
1390 Broadcast requests are limited in size to the MTU (Maximum Transfer
1391 Unit) of the local network. For Ethernet, the MTU is 1500 bytes.
1394 \&Broadcast RPC Synopsis
1395 .IX "broadcast RPC" synopsis
1396 .IX "RPC" "broadcast synopsis"
1400 #include <rpc/pmap_clnt.h>
1402 enum clnt_stat clnt_stat;
1404 clnt_stat = clnt_broadcast(prognum, versnum, procnum,
1405 inproc, in, outproc, out, eachresult)
1406 u_long prognum; /* \fIprogram number\fP */
1407 u_long versnum; /* \fIversion number\fP */
1408 u_long procnum; /* \fIprocedure number\fP */
1409 xdrproc_t inproc; /* \fIxdr routine for args\fP */
1410 caddr_t in; /* \fIpointer to args\fP */
1411 xdrproc_t outproc; /* \fIxdr routine for results\fP */
1412 caddr_t out; /* \fIpointer to results\fP */
1413 bool_t (*eachresult)();/* \fIcall with each result gotten\fP */
1418 is called each time a valid result is obtained.
1419 It returns a boolean that indicates
1420 whether or not the user wants more responses.
1426 done = eachresult(resultsp, raddr)
1428 struct sockaddr_in *raddr; /* \fIAddr of responding machine\fP */
1434 then broadcasting stops and
1436 returns successfully.
1437 Otherwise, the routine waits for another response.
1438 The request is rebroadcast
1439 after a few seconds of waiting.
1440 If no responses come back,
1441 the routine returns with
1448 The RPC architecture is designed so that clients send a call message,
1449 and wait for servers to reply that the call succeeded.
1450 This implies that clients do not compute
1451 while servers are processing a call.
1452 This is inefficient if the client does not want or need
1453 an acknowledgement for every message sent.
1454 It is possible for clients to continue computing
1455 while waiting for a response,
1456 using RPC batch facilities.
1458 RPC messages can be placed in a \*Qpipeline\*U of calls
1459 to a desired server; this is called batching.
1460 Batching assumes that:
1461 1) each RPC call in the pipeline requires no response from the server,
1462 and the server does not send a response message; and
1463 2) the pipeline of calls is transported on a reliable
1464 byte stream transport such as TCP/IP.
1465 Since the server does not respond to every call,
1466 the client can generate new calls in parallel
1467 with the server executing previous calls.
1468 Furthermore, the TCP/IP implementation can buffer up
1469 many call messages, and send them to the server in one
1471 system call. This overlapped execution
1472 greatly decreases the interprocess communication overhead of
1473 the client and server processes,
1474 and the total elapsed time of a series of calls.
1476 Since the batched calls are buffered,
1477 the client should eventually do a nonbatched call
1478 in order to flush the pipeline.
1480 A contrived example of batching follows.
1481 Assume a string rendering service (like a window system)
1482 has two similar calls: one renders a string and returns void results,
1483 while the other renders a string and remains silent.
1484 The service (using the TCP/IP transport) may look like:
1489 #include <rpc/rpc.h>
1490 #include <suntool/windows.h>
1492 void windowdispatch();
1498 transp = svctcp_create(RPC_ANYSOCK, 0, 0);
1499 if (transp == NULL){
1500 fprintf(stderr, "can't create an RPC server\en");
1503 pmap_unset(WINDOWPROG, WINDOWVERS);
1504 if (!svc_register(transp, WINDOWPROG, WINDOWVERS,
1505 windowdispatch, IPPROTO_TCP)) {
1506 fprintf(stderr, "can't register WINDOW service\en");
1509 svc_run(); /* \fINever returns\fP */
1510 fprintf(stderr, "should never reach this point\en");
1514 windowdispatch(rqstp, transp)
1515 struct svc_req *rqstp;
1520 switch (rqstp->rq_proc) {
1522 if (!svc_sendreply(transp, xdr_void, 0))
1523 fprintf(stderr, "can't reply to RPC call\en");
1526 if (!svc_getargs(transp, xdr_wrapstring, &s)) {
1527 fprintf(stderr, "can't decode arguments\en");
1530 * Tell caller he screwed up
1533 svcerr_decode(transp);
1538 * Code here to render the string \fIs\fP
1541 if (!svc_sendreply(transp, xdr_void, NULL))
1542 fprintf(stderr, "can't reply to RPC call\en");
1544 case RENDERSTRING_BATCHED:
1545 if (!svc_getargs(transp, xdr_wrapstring, &s)) {
1546 fprintf(stderr, "can't decode arguments\en");
1549 * We are silent in the face of protocol errors
1556 * Code here to render string s, but send no reply!
1561 svcerr_noproc(transp);
1566 * Now free string allocated while decoding arguments
1569 svc_freeargs(transp, xdr_wrapstring, &s);
1572 Of course the service could have one procedure
1573 that takes the string and a boolean
1574 to indicate whether or not the procedure should respond.
1576 In order for a client to take advantage of batching,
1577 the client must perform RPC calls on a TCP-based transport
1578 and the actual calls must have the following attributes:
1579 1) the result's XDR routine must be zero
1581 and 2) the RPC call's timeout must be zero.
1584 Here is an example of a client that uses batching to render a
1585 bunch of strings; the batching is flushed when the client gets
1586 a null string (EOF):
1592 #include <rpc/rpc.h>
1593 #include <sys/socket.h>
1594 #include <sys/time.h>
1596 #include <suntool/windows.h>
1603 struct timeval pertry_timeout, total_timeout;
1604 struct sockaddr_in server_addr;
1605 int sock = RPC_ANYSOCK;
1606 register CLIENT *client;
1607 enum clnt_stat clnt_stat;
1608 char buf[1000], *s = buf;
1610 if ((client = clnttcp_create(&server_addr,
1611 WINDOWPROG, WINDOWVERS, &sock, 0, 0)) == NULL) {
1612 perror("clnttcp_create");
1615 total_timeout.tv_sec = 0;
1616 total_timeout.tv_usec = 0;
1617 while (scanf("%s", s) != EOF) {
1618 clnt_stat = clnt_call(client, RENDERSTRING_BATCHED,
1619 xdr_wrapstring, &s, NULL, NULL, total_timeout);
1620 if (clnt_stat != RPC_SUCCESS) {
1621 clnt_perror(client, "batched rpc");
1626 /* \fINow flush the pipeline\fP */
1628 total_timeout.tv_sec = 20;
1629 clnt_stat = clnt_call(client, NULLPROC, xdr_void, NULL,
1630 xdr_void, NULL, total_timeout);
1631 if (clnt_stat != RPC_SUCCESS) {
1632 clnt_perror(client, "rpc");
1635 clnt_destroy(client);
1641 Since the server sends no message,
1642 the clients cannot be notified of any of the failures that may occur.
1643 Therefore, clients are on their own when it comes to handling errors.
1645 The above example was completed to render
1646 all of the (2000) lines in the file
1648 The rendering service did nothing but throw the lines away.
1649 The example was run in the following four configurations:
1650 1) machine to itself, regular RPC;
1651 2) machine to itself, batched RPC;
1652 3) machine to another, regular RPC; and
1653 4) machine to another, batched RPC.
1654 The results are as follows:
1663 only requires six seconds.
1664 These timings show the advantage of protocols
1665 that allow for overlapped execution,
1666 though these protocols are often hard to design.
1669 .IX "authentication"
1670 .IX "RPC" "authentication"
1672 In the examples presented so far,
1673 the caller never identified itself to the server,
1674 and the server never required an ID from the caller.
1675 Clearly, some network services, such as a network filesystem,
1676 require stronger security than what has been presented so far.
1678 In reality, every RPC call is authenticated by
1679 the RPC package on the server, and similarly,
1680 the RPC client package generates and sends authentication parameters.
1681 Just as different transports (TCP/IP or UDP/IP)
1682 can be used when creating RPC clients and servers,
1683 different forms of authentication can be associated with RPC clients;
1684 the default authentication type used as a default is type
1687 The authentication subsystem of the RPC package is open ended.
1688 That is, numerous types of authentication are easy to support.
1690 \&UNIX Authentication
1691 .IX "UNIX Authentication"
1692 .IP "\fIThe Client Side\fP"
1694 When a caller creates a new RPC client handle as in:
1697 clnt = clntudp_create(address, prognum, versnum,
1700 the appropriate transport instance defaults
1701 the associate authentication handle to be
1704 clnt->cl_auth = authnone_create();
1706 The RPC client can choose to use
1708 style authentication by setting
1710 after creating the RPC client handle:
1713 clnt->cl_auth = authunix_create_default();
1715 This causes each RPC call associated with
1717 to carry with it the following authentication credentials structure:
1722 * UNIX style credentials.
1725 struct authunix_parms {
1726 u_long aup_time; /* \fIcredentials creation time\fP */
1727 char *aup_machname; /* \fIhost name where client is\fP */
1728 int aup_uid; /* \fIclient's UNIX effective uid\fP */
1729 int aup_gid; /* \fIclient's current group id\fP */
1730 u_int aup_len; /* \fIelement length of aup_gids\fP */
1731 int *aup_gids; /* \fIarray of groups user is in\fP */
1734 These fields are set by
1735 .I authunix_create_default()
1736 by invoking the appropriate system calls.
1737 Since the RPC user created this new style of authentication,
1738 the user is responsible for destroying it with:
1741 auth_destroy(clnt->cl_auth);
1743 This should be done in all cases, to conserve memory.
1745 .IP "\fIThe Server Side\fP"
1747 Service implementors have a harder time dealing with authentication issues
1748 since the RPC package passes the service dispatch routine a request
1749 that has an arbitrary authentication style associated with it.
1750 Consider the fields of a request handle passed to a service dispatch routine:
1755 * An RPC Service request
1759 u_long rq_prog; /* \fIservice program number\fP */
1760 u_long rq_vers; /* \fIservice protocol vers num\fP */
1761 u_long rq_proc; /* \fIdesired procedure number\fP */
1762 struct opaque_auth rq_cred; /* \fIraw credentials from wire\fP */
1763 caddr_t rq_clntcred; /* \fIcredentials (read only)\fP */
1768 is mostly opaque, except for one field of interest:
1769 the style or flavor of authentication credentials:
1774 * Authentication info. Mostly opaque to the programmer.
1777 struct opaque_auth {
1778 enum_t oa_flavor; /* \fIstyle of credentials\fP */
1779 caddr_t oa_base; /* \fIaddress of more auth stuff\fP */
1780 u_int oa_length; /* \fInot to exceed \fIMAX_AUTH_BYTES */
1784 The RPC package guarantees the following
1785 to the service dispatch routine:
1789 is well formed. Thus the service implementor may inspect the request's
1790 .I rq_cred.oa_flavor
1791 to determine which style of authentication the caller used.
1792 The service implementor may also wish to inspect the other fields of
1794 if the style is not one of the styles supported by the RPC package.
1800 or points to a well formed structure
1801 that corresponds to a supported style of authentication credentials.
1804 style is currently supported, so (currently)
1806 could be cast to a pointer to an
1812 the service implementor may wish to inspect the other (opaque) fields of
1814 in case the service knows about a new type of authentication
1815 that the RPC package does not know about.
1817 Our remote users service example can be extended so that
1818 it computes results for all users except UID 16:
1823 nuser(rqstp, transp)
1824 struct svc_req *rqstp;
1827 struct authunix_parms *unix_cred;
1829 unsigned long nusers;
1833 * we don't care about authentication for null proc
1836 if (rqstp->rq_proc == NULLPROC) {
1837 if (!svc_sendreply(transp, xdr_void, 0)) {
1838 fprintf(stderr, "can't reply to RPC call\en");
1848 switch (rqstp->rq_cred.oa_flavor) {
1851 (struct authunix_parms *)rqstp->rq_clntcred;
1852 uid = unix_cred->aup_uid;
1856 svcerr_weakauth(transp);
1859 switch (rqstp->rq_proc) {
1860 case RUSERSPROC_NUM:
1863 * make sure caller is allowed to call this proc
1867 svcerr_systemerr(transp);
1872 * Code here to compute the number of users
1873 * and assign it to the variable \fInusers\fP
1876 if (!svc_sendreply(transp, xdr_u_long, &nusers)) {
1877 fprintf(stderr, "can't reply to RPC call\en");
1882 svcerr_noproc(transp);
1888 A few things should be noted here.
1889 First, it is customary not to check
1890 the authentication parameters associated with the
1892 (procedure number zero).
1893 Second, if the authentication parameter's type is not suitable
1894 for your service, you should call
1895 .I svcerr_weakauth() .
1896 And finally, the service protocol itself should return status
1897 for access denied; in the case of our example, the protocol
1898 does not have such a status, so we call the service primitive
1899 .I svcerr_systemerr()
1902 The last point underscores the relation between
1903 the RPC authentication package and the services;
1906 and not with individual services'
1907 .I "access control" .
1908 The services themselves must implement their own access control policies
1909 and reflect these policies as return statuses in their protocols.
1911 \&DES Authentication
1913 .IX RPC authentication
1915 UNIX authentication is quite easy to defeat. Instead of using
1916 .I authunix_create_default (),
1918 .I authunix_create()
1919 and then modify the RPC authentication handle it returns by filling in
1920 whatever user ID and hostname they wish the server to think they have.
1921 DES authentication is thus recommended for people who want more security
1922 than UNIX authentication offers.
1924 The details of the DES authentication protocol are complicated and
1925 are not explained here.
1927 .I "Remote Procedure Calls: Protocol Specification"
1930 In order for DES authentication to work, the
1932 daemon must be running on both the server and client machines. The
1933 users on these machines need public keys assigned by the network
1934 administrator in the
1936 database. And, they need to have decrypted their secret keys
1937 using their login password. This automatically happens when one
1940 or can be done manually using
1943 .I "Network Services"
1946 explains more how to setup secure networking.
1948 .IP "\fIClient Side\fP"
1950 If a client wishes to use DES authentication, it must set its
1951 authentication handle appropriately. Here is an example:
1954 authdes_create(servername, 60, &server_addr, NULL);
1956 The first argument is the network name or \*Qnetname\*U of the owner of
1957 the server process. Typically, server processes are root processes
1958 and their netname can be derived using the following call:
1960 char servername[MAXNETNAMELEN];
1962 host2netname(servername, rhostname, NULL);
1966 is the hostname of the machine the server process is running on.
1970 to contain this root process's netname. If the
1971 server process was run by a regular user, one could use the call
1973 instead. Here is an example for a server process with the same user
1976 char servername[MAXNETNAMELEN];
1978 user2netname(servername, getuid(), NULL);
1980 The last argument to both of these calls,
1984 is the name of the naming domain where the server is located. The
1986 used here means \*Quse the local domain name.\*U
1988 The second argument to
1990 is a lifetime for the credential. Here it is set to sixty
1991 seconds. What that means is that the credential will expire 60
1992 seconds from now. If some mischievous user tries to reuse the
1993 credential, the server RPC subsystem will recognize that it has
1994 expired and not grant any requests. If the same mischievous user
1995 tries to reuse the credential within the sixty second lifetime,
1996 he will still be rejected because the server RPC subsystem
1997 remembers which credentials it has already seen in the near past,
1998 and will not grant requests to duplicates.
2000 The third argument to
2002 is the address of the host to synchronize with. In order for DES
2003 authentication to work, the server and client must agree upon the
2004 time. Here we pass the address of the server itself, so the
2005 client and server will both be using the same time: the server's
2006 time. The argument can be
2008 which means \*Qdon't bother synchronizing.\*U You should only do this
2009 if you are sure the client and server are already synchronized.
2011 The final argument to
2013 is the address of a DES encryption key to use for encrypting
2014 timestamps and data. If this argument is
2016 as it is in this example, a random key will be chosen. The client
2017 may find out the encryption key being used by consulting the
2019 field of the authentication handle.
2021 .IP "\fIServer Side\fP"
2023 The server side is a lot simpler than the client side. Here is the
2024 previous example rewritten to use
2032 #include <sys/time.h>
2033 #include <rpc/auth_des.h>
2036 nuser(rqstp, transp)
2037 struct svc_req *rqstp;
2040 struct authdes_cred *des_cred;
2047 * we don't care about authentication for null proc
2051 if (rqstp->rq_proc == NULLPROC) {
2052 /* \fIsame as before\fP */
2060 switch (rqstp->rq_cred.oa_flavor) {
2063 (struct authdes_cred *) rqstp->rq_clntcred;
2064 if (! netname2user(des_cred->adc_fullname.name,
2065 &uid, &gid, &gidlen, gidlist))
2067 fprintf(stderr, "unknown user: %s\en",
2068 des_cred->adc_fullname.name);
2069 svcerr_systemerr(transp);
2075 svcerr_weakauth(transp);
2081 * The rest is the same as before
2086 Note the use of the routine
2090 it takes a network ID and converts to a unix ID.
2092 also supplies the group IDs which we don't use in this example,
2093 but which may be useful to other UNIX programs.
2096 .IX inetd "" "using \fIinetd\fP"
2098 An RPC server can be started from
2100 The only difference from the usual code is that the service
2101 creation routine should be called in the following form:
2105 transp = svcudp_create(0); /* \fIFor UDP\fP */
2106 transp = svctcp_create(0,0,0); /* \fIFor listener TCP sockets\fP */
2107 transp = svcfd_create(0,0,0); /* \fIFor connected TCP sockets\fP */
2111 passes a socket as file descriptor 0.
2118 svc_register(transp, PROGNUM, VERSNUM, service, 0);
2120 with the final flag as 0,
2121 since the program would already be registered by
2123 Remember that if you want to exit
2124 from the server process and return control to
2126 you need to explicitly exit, since
2130 The format of entries in
2132 for RPC services is in one of the following two forms:
2136 p_name/version dgram rpc/udp wait/nowait user server args
2137 p_name/version stream rpc/tcp wait/nowait user server args
2141 is the symbolic name of the program as it appears in
2144 is the program implementing the server,
2149 are the program and version numbers of the service.
2150 For more information, see
2153 If the same program handles multiple versions,
2154 then the version number can be a range,
2159 rstatd/1-2 dgram rpc/udp wait root /usr/etc/rpc.rstatd
2167 .IX "RPC" "versions"
2169 By convention, the first version number of program
2173 and the most recent version is
2175 Suppose there is a new version of the
2177 program that returns an
2181 If we name this version
2183 then a server that wants to support both versions
2184 would do a double register.
2188 if (!svc_register(transp, RUSERSPROG, RUSERSVERS_ORIG,
2189 nuser, IPPROTO_TCP)) {
2190 fprintf(stderr, "can't register RUSER service\en");
2193 if (!svc_register(transp, RUSERSPROG, RUSERSVERS_SHORT,
2194 nuser, IPPROTO_TCP)) {
2195 fprintf(stderr, "can't register RUSER service\en");
2199 Both versions can be handled by the same C procedure:
2204 nuser(rqstp, transp)
2205 struct svc_req *rqstp;
2208 unsigned long nusers;
2209 unsigned short nusers2;
2211 switch (rqstp->rq_proc) {
2213 if (!svc_sendreply(transp, xdr_void, 0)) {
2214 fprintf(stderr, "can't reply to RPC call\en");
2218 case RUSERSPROC_NUM:
2221 * Code here to compute the number of users
2222 * and assign it to the variable \fInusers\fP
2226 switch (rqstp->rq_vers) {
2227 case RUSERSVERS_ORIG:
2228 if (!svc_sendreply(transp, xdr_u_long,
2230 fprintf(stderr,"can't reply to RPC call\en");
2233 case RUSERSVERS_SHORT:
2234 if (!svc_sendreply(transp, xdr_u_short,
2236 fprintf(stderr,"can't reply to RPC call\en");
2241 svcerr_noproc(transp);
2252 Here is an example that is essentially
2254 The initiator of the RPC
2256 call takes its standard input and sends it to the server
2258 which prints it on standard output.
2259 The RPC call uses TCP.
2260 This also illustrates an XDR procedure that behaves differently
2261 on serialization than on deserialization.
2268 * on decode, read from wire, write onto fp
2269 * on encode, read from fp, write onto wire
2273 #include <rpc/rpc.h>
2280 char buf[BUFSIZ], *p;
2282 if (xdrs->x_op == XDR_FREE)/* nothing to free */
2285 if (xdrs->x_op == XDR_ENCODE) {
2286 if ((size = fread(buf, sizeof(char), BUFSIZ,
2287 fp)) == 0 && ferror(fp)) {
2288 fprintf(stderr, "can't fread\en");
2293 if (!xdr_bytes(xdrs, &p, &size, BUFSIZ))
2297 if (xdrs->x_op == XDR_DECODE) {
2298 if (fwrite(buf, sizeof(char), size,
2300 fprintf(stderr, "can't fwrite\en");
2314 * The sender routines
2319 #include <rpc/rpc.h>
2320 #include <sys/socket.h>
2321 #include <sys/time.h>
2331 fprintf(stderr, "usage: %s servername\en", argv[0]);
2334 if ((err = callrpctcp(argv[1], RCPPROG, RCPPROC,
2335 RCPVERS, xdr_rcp, stdin, xdr_void, 0) != 0)) {
2337 fprintf(stderr, "can't make RPC call\en");
2343 callrpctcp(host, prognum, procnum, versnum,
2344 inproc, in, outproc, out)
2345 char *host, *in, *out;
2346 xdrproc_t inproc, outproc;
2348 struct sockaddr_in server_addr;
2349 int socket = RPC_ANYSOCK;
2350 enum clnt_stat clnt_stat;
2352 register CLIENT *client;
2353 struct timeval total_timeout;
2355 if ((hp = gethostbyname(host)) == NULL) {
2356 fprintf(stderr, "can't get addr for '%s'\en", host);
2359 bcopy(hp->h_addr, (caddr_t)&server_addr.sin_addr,
2361 server_addr.sin_family = AF_INET;
2362 server_addr.sin_port = 0;
2363 if ((client = clnttcp_create(&server_addr, prognum,
2364 versnum, &socket, BUFSIZ, BUFSIZ)) == NULL) {
2365 perror("rpctcp_create");
2368 total_timeout.tv_sec = 20;
2369 total_timeout.tv_usec = 0;
2370 clnt_stat = clnt_call(client, procnum,
2371 inproc, in, outproc, out, total_timeout);
2372 clnt_destroy(client);
2373 return (int)clnt_stat;
2382 * The receiving routines
2386 #include <rpc/rpc.h>
2390 register SVCXPRT *transp;
2391 int rcp_service(), xdr_rcp();
2393 if ((transp = svctcp_create(RPC_ANYSOCK,
2394 BUFSIZ, BUFSIZ)) == NULL) {
2395 fprintf("svctcp_create: error\en");
2398 pmap_unset(RCPPROG, RCPVERS);
2399 if (!svc_register(transp,
2400 RCPPROG, RCPVERS, rcp_service, IPPROTO_TCP)) {
2401 fprintf(stderr, "svc_register: error\en");
2404 svc_run(); /* \fInever returns\fP */
2405 fprintf(stderr, "svc_run should never return\en");
2408 rcp_service(rqstp, transp)
2409 register struct svc_req *rqstp;
2410 register SVCXPRT *transp;
2412 switch (rqstp->rq_proc) {
2414 if (svc_sendreply(transp, xdr_void, 0) == 0) {
2415 fprintf(stderr, "err: rcp_service");
2420 if (!svc_getargs(transp, xdr_rcp, stdout)) {
2421 svcerr_decode(transp);
2424 if (!svc_sendreply(transp, xdr_void, 0)) {
2425 fprintf(stderr, "can't reply\en");
2430 svcerr_noproc(transp);
2437 \&Callback Procedures
2438 .IX RPC "callback procedures"
2440 Occasionally, it is useful to have a server become a client,
2441 and make an RPC call back to the process which is its client.
2442 An example is remote debugging,
2443 where the client is a window system program,
2444 and the server is a debugger running on the remote machine.
2446 the user clicks a mouse button at the debugging window,
2447 which converts this to a debugger command,
2448 and then makes an RPC call to the server
2449 (where the debugger is actually running),
2450 telling it to execute that command.
2451 However, when the debugger hits a breakpoint, the roles are reversed,
2452 and the debugger wants to make an rpc call to the window program,
2453 so that it can inform the user that a breakpoint has been reached.
2455 In order to do an RPC callback,
2456 you need a program number to make the RPC call on.
2457 Since this will be a dynamically generated program number,
2458 it should be in the transient range,
2459 .I "0x40000000 - 0x5fffffff" .
2462 returns a valid program number in the transient range,
2463 and registers it with the portmapper.
2464 It only talks to the portmapper running on the same machine as the
2466 routine itself. The call to
2468 is a test and set operation,
2469 in that it indivisibly tests whether a program number
2470 has already been registered,
2471 and if it has not, then reserves it. On return, the
2473 argument will contain a socket that can be used
2474 as the argument to an
2484 #include <rpc/rpc.h>
2485 #include <sys/socket.h>
2487 gettransient(proto, vers, sockp)
2488 int proto, vers, *sockp;
2490 static int prognum = 0x40000000;
2491 int s, len, socktype;
2492 struct sockaddr_in addr;
2496 socktype = SOCK_DGRAM;
2499 socktype = SOCK_STREAM;
2502 fprintf(stderr, "unknown protocol type\en");
2505 if (*sockp == RPC_ANYSOCK) {
2506 if ((s = socket(AF_INET, socktype, 0)) < 0) {
2514 addr.sin_addr.s_addr = 0;
2515 addr.sin_family = AF_INET;
2520 * may be already bound, so don't check for error
2523 bind(s, &addr, len);
2524 if (getsockname(s, &addr, &len)< 0) {
2525 perror("getsockname");
2528 while (!pmap_set(prognum++, vers, proto,
2529 ntohs(addr.sin_port))) continue;
2539 is necessary to ensure that the port number in
2540 .I "addr.sin_port" ,
2543 byte order, is passed in
2549 man page for more details on the conversion of network
2550 addresses from network to host byte order.
2553 The following pair of programs illustrate how to use the
2556 The client makes an RPC call to the server,
2557 passing it a transient program number.
2558 Then the client waits around to receive a callback
2559 from the server at that program number.
2560 The server registers the program
2562 so that it can receive the RPC call
2563 informing it of the callback program number.
2564 Then at some random time (on receiving an
2566 signal in this example), it sends a callback RPC call,
2567 using the program number it received earlier.
2577 #include <rpc/rpc.h>
2587 gethostname(hostname, sizeof(hostname));
2589 x = gettransient(IPPROTO_UDP, 1, &s);
2590 fprintf(stderr, "client gets prognum %d\en", x);
2591 if ((xprt = svcudp_create(s)) == NULL) {
2592 fprintf(stderr, "rpc_server: svcudp_create\en");
2596 /* protocol is 0 - gettransient does registering
2599 (void)svc_register(xprt, x, 1, callback, 0);
2600 ans = callrpc(hostname, EXAMPLEPROG, EXAMPLEVERS,
2601 EXAMPLEPROC_CALLBACK, xdr_int, &x, xdr_void, 0);
2602 if ((enum clnt_stat) ans != RPC_SUCCESS) {
2603 fprintf(stderr, "call: ");
2605 fprintf(stderr, "\en");
2608 fprintf(stderr, "Error: svc_run shouldn't return\en");
2611 callback(rqstp, transp)
2612 register struct svc_req *rqstp;
2613 register SVCXPRT *transp;
2615 switch (rqstp->rq_proc) {
2617 if (!svc_sendreply(transp, xdr_void, 0)) {
2618 fprintf(stderr, "err: exampleprog\en");
2623 if (!svc_getargs(transp, xdr_void, 0)) {
2624 svcerr_decode(transp);
2627 fprintf(stderr, "client got callback\en");
2628 if (!svc_sendreply(transp, xdr_void, 0)) {
2629 fprintf(stderr, "err: exampleprog");
2646 #include <rpc/rpc.h>
2647 #include <sys/signal.h>
2652 int pnum; /* \fIprogram number for callback routine\fP */
2656 gethostname(hostname, sizeof(hostname));
2657 registerrpc(EXAMPLEPROG, EXAMPLEVERS,
2658 EXAMPLEPROC_CALLBACK, getnewprog, xdr_int, xdr_void);
2659 fprintf(stderr, "server going into svc_run\en");
2660 signal(SIGALRM, docallback);
2663 fprintf(stderr, "Error: svc_run shouldn't return\en");
2670 pnum = *(int *)pnump;
2678 ans = callrpc(hostname, pnum, 1, 1, xdr_void, 0,
2681 fprintf(stderr, "server: ");
2683 fprintf(stderr, "\en");