grrr...fix reverse chronological order
[dragonfly.git] / lib / libcr / rpc / PSD.doc / rpc.prog.ms
1 .\"
2 .\" Must use -- tbl and pic -- with this one
3 .\"
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 $
6 .\" $DragonFly: src/lib/libcr/rpc/PSD.doc/Attic/rpc.prog.ms,v 1.2 2003/06/17 04:26:45 dillon Exp $
7 .\"
8 .so stubs
9 .de BT
10 .if \\n%=1 .tl ''- % -''
11 ..
12 .nr OF 0
13 .ND
14 .\" prevent excess underlining in nroff
15 .if n .fp 2 R
16 .OH 'Remote Procedure Call Programming Guide''Page %'
17 .EH 'Page %''Remote Procedure Call Programming Guide'
18 .SH
19 \&Remote Procedure Call Programming Guide
20 .nr OF 1
21 .IX "Network Programming" "" "" "" PAGE MAJOR
22 .IX "RPC Programming Guide"
23 .LP
24 This document assumes a working knowledge of network theory.  It is
25 intended for programmers who wish to write network applications using
26 remote procedure calls (explained below), and who want to understand
27 the RPC mechanisms usually hidden by the
28 .I rpcgen(1) 
29 protocol compiler.
30 .I rpcgen 
31 is described in detail in the previous chapter, the
32 .I "\fBrpcgen\fP \fIProgramming Guide\fP".
33 .SH
34 Note:
35 .I
36 .IX rpcgen "" \fIrpcgen\fP
37 Before attempting to write a network application, or to convert an
38 existing non-network application to run over the network, you may want to
39 understand the material in this chapter.  However, for most applications,
40 you can circumvent the need to cope with the details presented here by using
41 .I rpcgen .
42 The
43 .I "Generating XDR Routines"
44 section of that chapter contains the complete source for a working RPC
45 service\(ema remote directory listing service which uses
46 .I rpcgen 
47 to generate XDR routines as well as client and server stubs.
48 .LP
49 .LP
50 What are remote procedure calls?  Simply put, they are the high-level
51 communications paradigm used in the operating system.
52 RPC presumes the existence of
53 low-level networking mechanisms (such as TCP/IP and UDP/IP), and upon them
54 it implements a logical client to server communications system designed
55 specifically for the support of network applications.  With RPC, the client
56 makes a procedure call to send a data packet to the server.  When the
57 packet arrives, the server calls a dispatch routine, performs whatever
58 service is requested, sends back the reply, and the procedure call returns
59 to the client.
60 .NH 0
61 \&Layers of RPC
62 .IX "layers of RPC"
63 .IX "RPC" "layers"
64 .LP
65 The RPC interface can be seen as being divided into three layers.\**
66 .FS
67 For a complete specification of the routines in the remote procedure
68 call Library, see the
69 .I rpc(3N) 
70 manual page.
71 .FE
72 .LP
73 .I "The Highest Layer:"
74 .IX RPC "The Highest Layer"
75 The highest layer is totally transparent to the operating system, 
76 machine and network upon which is is run.  It's probably best to 
77 think of this level as a way of
78 .I using
79 RPC, rather than as
80 a \fIpart of\fP RPC proper.  Programmers who write RPC routines 
81 should (almost) always make this layer available to others by way 
82 of a simple C front end that entirely hides the networking.
83 .LP 
84 To illustrate, at this level a program can simply make a call to
85 .I rnusers (),
86 a C routine which returns the number of users on a remote machine.
87 The user is not explicitly aware of using RPC \(em they simply 
88 call a procedure, just as they would call
89 .I malloc() .
90 .LP
91 .I "The Middle Layer:"
92 .IX RPC "The Middle Layer"
93 The middle layer is really \*QRPC proper.\*U  Here, the user doesn't
94 need to consider details about sockets, the UNIX system, or other low-level 
95 implementation mechanisms.  They simply make remote procedure calls
96 to routines on other machines.  The selling point here is simplicity.  
97 It's this layer that allows RPC to pass the \*Qhello world\*U test \(em
98 simple things should be simple.  The middle-layer routines are used 
99 for most applications.
100 .LP
101 RPC calls are made with the system routines
102 .I registerrpc()
103 .I callrpc()
104 and
105 .I svc_run ().
106 The first two of these are the most fundamental:
107 .I registerrpc() 
108 obtains a unique system-wide procedure-identification number, and
109 .I callrpc() 
110 actually executes a remote procedure call.  At the middle level, a 
111 call to 
112 .I rnusers()
113 is implemented by way of these two routines.
114 .LP
115 The middle layer is unfortunately rarely used in serious programming 
116 due to its inflexibility (simplicity).  It does not allow timeout 
117 specifications or the choice of transport.  It allows no UNIX
118 process control or flexibility in case of errors.  It doesn't support
119 multiple kinds of call authentication.  The programmer rarely needs 
120 all these kinds of control, but one or two of them is often necessary.
121 .LP
122 .I "The Lowest Layer:"
123 .IX RPC "The Lowest Layer"
124 The lowest layer does allow these details to be controlled by the 
125 programmer, and for that reason it is often necessary.  Programs 
126 written at this level are also most efficient, but this is rarely a
127 real issue \(em since RPC clients and servers rarely generate 
128 heavy network loads.
129 .LP
130 Although this document only discusses the interface to C,
131 remote procedure calls can be made from any language.
132 Even though this document discusses RPC
133 when it is used to communicate
134 between processes on different machines,
135 it works just as well for communication
136 between different processes on the same machine.
137 .br
138 .KS
139 .NH 2
140 \&The RPC Paradigm
141 .IX RPC paradigm
142 .LP
143 Here is a diagram of the RPC paradigm:
144 .LP
145 \fBFigure 1-1\fI Network Communication with the Remote Reocedure Call\fR
146 .LP
147 .PS
148 L1: arrow down 1i "client " rjust "program " rjust
149 L2: line right 1.5i "\fIcallrpc\fP" "function"
150 move up 1.5i; line dotted down 6i; move up 4.5i
151 arrow right 1i
152 L3: arrow down 1i "invoke " rjust "service " rjust
153 L4: arrow right 1.5i "call" "service"
154 L5: arrow down 1i " service" ljust " executes" ljust
155 L6: arrow left 1.5i "\fIreturn\fP" "answer"
156 L7: arrow down 1i "request " rjust "completed " rjust
157 L8: line left 1i
158 arrow left 1.5i "\fIreturn\fP" "reply"
159 L9: arrow down 1i "program " rjust "continues " rjust
160 line dashed down from L2 to L9
161 line dashed down from L4 to L7
162 line dashed up 1i from L3 "service " rjust "daemon " rjust
163 arrow dashed down 1i from L8
164 move right 1i from L3
165 box invis "Machine B"
166 move left 1.2i from L2; move down
167 box invis "Machine A"
168 .PE
169 .KE
170 .KS
171 .NH 1
172 \&Higher Layers of RPC
173 .NH 2
174 \&Highest Layer
175 .IX "highest layer of RPC"
176 .IX RPC "highest layer"
177 .LP
178 Imagine you're writing a program that needs to know
179 how many users are logged into a remote machine.
180 You can do this by calling the RPC library routine
181 .I rnusers()
182 as illustrated below:
183 .ie t .DS
184 .el .DS L
185 .ft CW
186 #include <stdio.h>
187
188 main(argc, argv)
189         int argc;
190         char **argv;
191 {
192         int num;
193
194         if (argc != 2) {
195                 fprintf(stderr, "usage: rnusers hostname\en");
196                 exit(1);
197         }
198         if ((num = rnusers(argv[1])) < 0) {
199                 fprintf(stderr, "error: rnusers\en");
200                 exit(-1);
201         }
202         printf("%d users on %s\en", num, argv[1]);
203         exit(0);
204 }
205 .DE
206 .KE
207 RPC library routines such as
208 .I rnusers() 
209 are in the RPC services library
210 .I librpcsvc.a
211 Thus, the program above should be compiled with
212 .DS
213 .ft CW
214 % cc \fIprogram.c -lrpcsvc\fP
215 .DE
216 .I rnusers (),
217 like the other RPC library routines, is documented in section 3R 
218 of the
219 .I "System Interface Manual for the Sun Workstation" ,
220 the same section which documents the standard Sun RPC services.  
221 .IX "RPC Services"
222 See the 
223 .I intro(3R) 
224 manual page for an explanation of the documentation strategy 
225 for these services and their RPC protocols.
226 .LP
227 Here are some of the RPC service library routines available to the 
228 C programmer:
229 .LP
230 \fBTable 3-3\fI RPC Service Library Routines\fR
231 .TS
232 box tab (&) ;
233 cfI cfI
234 lfL l .
235 Routine&Description
236 _
237 .sp .5
238 rnusers&Return number of users on remote machine
239 rusers&Return information about users on remote machine
240 havedisk&Determine if remote machine has disk
241 rstats&Get performance data from remote kernel
242 rwall&Write to specified remote machines
243 yppasswd&Update user password in Yellow Pages
244 .TE
245 .LP
246 Other RPC services \(em for example
247 .I ether()
248 .I mount
249 .I rquota()
250 and
251 .I spray
252 \(em are not available to the C programmer as library routines.
253 They do, however,
254 have RPC program numbers so they can be invoked with
255 .I callrpc()
256 which will be discussed in the next section.  Most of them also 
257 have compilable 
258 .I rpcgen(1) 
259 protocol description files.  (The
260 .I rpcgen
261 protocol compiler radically simplifies the process of developing
262 network applications.  
263 See the \fBrpcgen\fI Programming Guide\fR
264 for detailed information about 
265 .I rpcgen 
266 and 
267 .I rpcgen 
268 protocol description files).
269 .KS
270 .NH 2
271 \&Intermediate Layer
272 .IX "intermediate layer of RPC"
273 .IX "RPC" "intermediate layer"
274 .LP
275 The simplest interface, which explicitly makes RPC calls, uses the 
276 functions
277 .I callrpc()
278 and
279 .I registerrpc()
280 Using this method, the number of remote users can be gotten as follows:
281 .ie t .DS
282 .el .DS L
283 #include <stdio.h>
284 #include <rpc/rpc.h>
285 #include <utmp.h>
286 #include <rpcsvc/rusers.h>
287
288 main(argc, argv)
289         int argc;
290         char **argv;
291 {
292         unsigned long nusers;
293         int stat;
294
295         if (argc != 2) {
296                 fprintf(stderr, "usage: nusers hostname\en");
297                 exit(-1);
298         }
299         if (stat = callrpc(argv[1],
300           RUSERSPROG, RUSERSVERS, RUSERSPROC_NUM,
301           xdr_void, 0, xdr_u_long, &nusers) != 0) {
302                 clnt_perrno(stat);
303                 exit(1);
304         }
305         printf("%d users on %s\en", nusers, argv[1]);
306         exit(0);
307 }
308 .DE
309 .KE
310 Each RPC procedure is uniquely defined by a program number, 
311 version number, and procedure number.  The program number 
312 specifies a group of related remote procedures, each of 
313 which has a different procedure number.  Each program also 
314 has a version number, so when a minor change is made to a 
315 remote service (adding a new procedure, for example), a new 
316 program number doesn't have to be assigned.  When you want 
317 to call a procedure to find the number of remote users, you 
318 look up the appropriate program, version and procedure numbers
319 in a manual, just as you look up the name of a memory allocator 
320 when you want to allocate memory.
321 .LP
322 The simplest way of making remote procedure calls is with the the RPC 
323 library routine
324 .I callrpc()
325 It has eight parameters.  The first is the name of the remote server 
326 machine.  The next three parameters are the program, version, and procedure 
327 numbers\(emtogether they identify the procedure to be called.
328 The fifth and sixth parameters are an XDR filter and an argument to
329 be encoded and passed to the remote procedure.  
330 The final two parameters are a filter for decoding the results 
331 returned by the remote procedure and a pointer to the place where 
332 the procedure's results are to be stored.  Multiple arguments and
333 results are handled by embedding them in structures.  If 
334 .I callrpc() 
335 completes successfully, it returns zero; else it returns a nonzero 
336 value.  The return codes (of type
337 .IX "enum clnt_stat (in RPC programming)" "" "\fIenum clnt_stat\fP (in RPC programming)"
338 cast into an integer) are found in 
339 .I <rpc/clnt.h> .
340 .LP
341 Since data types may be represented differently on different machines,
342 .I callrpc() 
343 needs both the type of the RPC argument, as well as
344 a pointer to the argument itself (and similarly for the result).  For
345 .I RUSERSPROC_NUM ,
346 the return value is an
347 .I "unsigned long"
348 so
349 .I callrpc() 
350 has
351 .I xdr_u_long() 
352 as its first return parameter, which says
353 that the result is of type
354 .I "unsigned long"
355 and
356 .I &nusers 
357 as its second return parameter,
358 which is a pointer to where the long result will be placed.  Since
359 .I RUSERSPROC_NUM 
360 takes no argument, the argument parameter of
361 .I callrpc() 
362 is
363 .I xdr_void ().
364 .LP
365 After trying several times to deliver a message, if
366 .I callrpc() 
367 gets no answer, it returns with an error code.
368 The delivery mechanism is UDP,
369 which stands for User Datagram Protocol.
370 Methods for adjusting the number of retries
371 or for using a different protocol require you to use the lower
372 layer of the RPC library, discussed later in this document.
373 The remote server procedure
374 corresponding to the above might look like this:
375 .ie t .DS
376 .el .DS L
377 .ft CW
378 .ft CW
379 char *
380 nuser(indata)
381         char *indata;
382 {
383         unsigned long nusers;
384
385 .ft I
386         /*
387          * Code here to compute the number of users
388          * and place result in variable \fInusers\fP.
389          */
390 .ft CW
391         return((char *)&nusers);
392 }
393 .DE
394 .LP
395 It takes one argument, which is a pointer to the input
396 of the remote procedure call (ignored in our example),
397 and it returns a pointer to the result.
398 In the current version of C,
399 character pointers are the generic pointers,
400 so both the input argument and the return value are cast to
401 .I "char *" .
402 .LP
403 Normally, a server registers all of the RPC calls it plans
404 to handle, and then goes into an infinite loop waiting to service requests.
405 In this example, there is only a single procedure
406 to register, so the main body of the server would look like this:
407 .ie t .DS
408 .el .DS L
409 .ft CW
410 #include <stdio.h>
411 #include <rpc/rpc.h>
412 #include <utmp.h>
413 #include <rpcsvc/rusers.h>
414
415 char *nuser();
416
417 main()
418 {
419         registerrpc(RUSERSPROG, RUSERSVERS, RUSERSPROC_NUM,
420                 nuser, xdr_void, xdr_u_long);
421         svc_run();              /* \fINever returns\fP */
422         fprintf(stderr, "Error: svc_run returned!\en");
423         exit(1);
424 }
425 .DE
426 .LP
427 The
428 .I registerrpc()
429 routine registers a C procedure as corresponding to a
430 given RPC procedure number.  The first three parameters,
431 .I RUSERPROG ,
432 .I RUSERSVERS ,
433 and
434 .I RUSERSPROC_NUM 
435 are the program, version, and procedure numbers
436 of the remote procedure to be registered;
437 .I nuser() 
438 is the name of the local procedure that implements the remote
439 procedure; and
440 .I xdr_void() 
441 and
442 .I xdr_u_long() 
443 are the XDR filters for the remote procedure's arguments and
444 results, respectively.  (Multiple arguments or multiple results
445 are passed as structures).
446 .LP
447 Only the UDP transport mechanism can use
448 .I registerrpc()
449 thus, it is always safe in conjunction with calls generated by
450 .I callrpc() .
451 .SH
452 .IX "UDP 8K warning"
453 Warning: the UDP transport mechanism can only deal with
454 arguments and results less than 8K bytes in length.
455 .LP
456 .LP
457 After registering the local procedure, the server program's
458 main procedure calls
459 .I svc_run (),
460 the RPC library's remote procedure dispatcher.  It is this 
461 function that calls the remote procedures in response to RPC
462 call messages.  Note that the dispatcher takes care of decoding
463 remote procedure arguments and encoding results, using the XDR
464 filters specified when the remote procedure was registered.
465 .NH 2
466 \&Assigning Program Numbers
467 .IX "program number assignment"
468 .IX "assigning program numbers"
469 .LP
470 Program numbers are assigned in groups of 
471 .I 0x20000000 
472 according to the following chart:
473 .DS
474 .ft CW
475        0x0 - 0x1fffffff \fRDefined by Sun\fP
476 0x20000000 - 0x3fffffff \fRDefined by user\fP
477 0x40000000 - 0x5fffffff \fRTransient\fP
478 0x60000000 - 0x7fffffff \fRReserved\fP
479 0x80000000 - 0x9fffffff \fRReserved\fP
480 0xa0000000 - 0xbfffffff \fRReserved\fP
481 0xc0000000 - 0xdfffffff \fRReserved\fP
482 0xe0000000 - 0xffffffff \fRReserved\fP
483 .ft R
484 .DE
485 Sun Microsystems administers the first group of numbers, which
486 should be identical for all Sun customers.  If a customer
487 develops an application that might be of general interest, that
488 application should be given an assigned number in the first
489 range.  The second group of numbers is reserved for specific
490 customer applications.  This range is intended primarily for
491 debugging new programs.  The third group is reserved for
492 applications that generate program numbers dynamically.  The
493 final groups are reserved for future use, and should not be
494 used.
495 .LP
496 To register a protocol specification, send a request by network 
497 mail to
498 .I rpc@sun
499 or write to:
500 .DS
501 RPC Administrator
502 Sun Microsystems
503 2550 Garcia Ave.
504 Mountain View, CA 94043
505 .DE
506 Please include a compilable 
507 .I rpcgen 
508 \*Q.x\*U file describing your protocol.
509 You will be given a unique program number in return.
510 .IX RPC administration
511 .IX administration "of RPC"
512 .LP
513 The RPC program numbers and protocol specifications 
514 of standard Sun RPC services can be
515 found in the include files in 
516 .I "/usr/include/rpcsvc" .
517 These services, however, constitute only a small subset 
518 of those which have been registered.  The complete list of 
519 registered programs, as of the time when this manual was 
520 printed, is:
521 .LP
522 \fBTable 3-2\fI RPC Registered Programs\fR
523 .TS H
524 box tab (&) ;
525 lfBI lfBI lfBI
526 lfL lfL lfI .
527 RPC Number&Program&Description
528 _
529 .TH
530 .sp .5
531 100000&PMAPPROG&portmapper
532 100001&RSTATPROG&remote stats            
533 100002&RUSERSPROG&remote users            
534 100003&NFSPROG&nfs                     
535 100004&YPPROG&Yellow Pages            
536 100005&MOUNTPROG&mount demon             
537 100006&DBXPROG&remote dbx              
538 100007&YPBINDPROG&yp binder               
539 100008&WALLPROG&shutdown msg            
540 100009&YPPASSWDPROG&yppasswd server         
541 100010&ETHERSTATPROG&ether stats             
542 100011&RQUOTAPROG&disk quotas             
543 100012&SPRAYPROG&spray packets           
544 100013&IBM3270PROG&3270 mapper             
545 100014&IBMRJEPROG&RJE mapper              
546 100015&SELNSVCPROG&selection service       
547 100016&RDATABASEPROG&remote database access  
548 100017&REXECPROG&remote execution        
549 100018&ALICEPROG&Alice Office Automation 
550 100019&SCHEDPROG&scheduling service      
551 100020&LOCKPROG&local lock manager      
552 100021&NETLOCKPROG&network lock manager    
553 100022&X25PROG&x.25 inr protocol       
554 100023&STATMON1PROG&status monitor 1        
555 100024&STATMON2PROG&status monitor 2        
556 100025&SELNLIBPROG&selection library       
557 100026&BOOTPARAMPROG&boot parameters service 
558 100027&MAZEPROG&mazewars game           
559 100028&YPUPDATEPROG&yp update               
560 100029&KEYSERVEPROG&key server              
561 100030&SECURECMDPROG&secure login            
562 100031&NETFWDIPROG&nfs net forwarder init       
563 100032&NETFWDTPROG&nfs net forwarder trans      
564 100033&SUNLINKMAP_PROG&sunlink MAP              
565 100034&NETMONPROG&network monitor               
566 100035&DBASEPROG&lightweight database   
567 100036&PWDAUTHPROG&password authorization       
568 100037&TFSPROG&translucent file svc     
569 100038&NSEPROG&nse server               
570 100039&NSE_ACTIVATE_PROG&nse activate daemon    
571 .sp .2i
572 150001&PCNFSDPROG&pc passwd authorization 
573 .sp .2i
574 200000&PYRAMIDLOCKINGPROG&Pyramid-locking         
575 200001&PYRAMIDSYS5&Pyramid-sys5            
576 200002&CADDS_IMAGE&CV cadds_image               
577 .sp .2i
578 300001&ADT_RFLOCKPROG&ADT file locking  
579 .TE
580 .NH 2
581 \&Passing Arbitrary Data Types
582 .IX "arbitrary data types"
583 .LP
584 In the previous example, the RPC call passes a single
585 .I "unsigned long"
586 RPC can handle arbitrary data structures, regardless of
587 different machines' byte orders or structure layout conventions,
588 by always converting them to a network standard called
589 .I "External Data Representation"
590 (XDR) before
591 sending them over the wire.
592 The process of converting from a particular machine representation
593 to XDR format is called
594 .I serializing ,
595 and the reverse process is called
596 .I deserializing .
597 The type field parameters of
598 .I callrpc() 
599 and
600 .I registerrpc() 
601 can be a built-in procedure like
602 .I xdr_u_long() 
603 in the previous example, or a user supplied one.
604 XDR has these built-in type routines:
605 .IX RPC "built-in routines"
606 .DS
607 .ft CW
608 xdr_int()      xdr_u_int()      xdr_enum()
609 xdr_long()     xdr_u_long()     xdr_bool()
610 xdr_short()    xdr_u_short()    xdr_wrapstring()
611 xdr_char()     xdr_u_char()
612 .DE
613 Note that the routine
614 .I xdr_string() 
615 exists, but cannot be used with 
616 .I callrpc() 
617 and
618 .I registerrpc (),
619 which only pass two parameters to their XDR routines.
620 .I xdr_wrapstring() 
621 has only two parameters, and is thus OK.  It calls 
622 .I xdr_string ().
623 .LP
624 As an example of a user-defined type routine,
625 if you wanted to send the structure
626 .DS
627 .ft CW
628 struct simple {
629         int a;
630         short b;
631 } simple;
632 .DE
633 then you would call
634 .I callrpc() 
635 as
636 .DS
637 .ft CW
638 callrpc(hostname, PROGNUM, VERSNUM, PROCNUM,
639         xdr_simple, &simple ...);
640 .DE
641 where
642 .I xdr_simple() 
643 is written as:
644 .ie t .DS
645 .el .DS L
646 .ft CW
647 #include <rpc/rpc.h>
648
649 xdr_simple(xdrsp, simplep)
650         XDR *xdrsp;
651         struct simple *simplep;
652 {
653         if (!xdr_int(xdrsp, &simplep->a))
654                 return (0);
655         if (!xdr_short(xdrsp, &simplep->b))
656                 return (0);
657         return (1);
658 }
659 .DE
660 .LP
661 An XDR routine returns nonzero (true in the sense of C) if it 
662 completes successfully, and zero otherwise.
663 A complete description of XDR is in the
664 .I "XDR Protocol Specification" 
665 section of this manual, only few implementation examples are 
666 given here.
667 .LP
668 In addition to the built-in primitives,
669 there are also the prefabricated building blocks:
670 .DS
671 .ft CW
672 xdr_array()       xdr_bytes()     xdr_reference()
673 xdr_vector()      xdr_union()     xdr_pointer()
674 xdr_string()      xdr_opaque()
675 .DE
676 To send a variable array of integers,
677 you might package them up as a structure like this
678 .DS
679 .ft CW
680 struct varintarr {
681         int *data;
682         int arrlnth;
683 } arr;
684 .DE
685 and make an RPC call such as
686 .DS
687 .ft CW
688 callrpc(hostname, PROGNUM, VERSNUM, PROCNUM,
689         xdr_varintarr, &arr...);
690 .DE
691 with
692 .I xdr_varintarr() 
693 defined as:
694 .ie t .DS
695 .el .DS L
696 .ft CW
697 xdr_varintarr(xdrsp, arrp)
698         XDR *xdrsp;
699         struct varintarr *arrp;
700 {
701         return (xdr_array(xdrsp, &arrp->data, &arrp->arrlnth, 
702                 MAXLEN, sizeof(int), xdr_int));
703 }
704 .DE
705 This routine takes as parameters the XDR handle,
706 a pointer to the array, a pointer to the size of the array,
707 the maximum allowable array size,
708 the size of each array element,
709 and an XDR routine for handling each array element.
710 .KS
711 .LP
712 If the size of the array is known in advance, one can use
713 .I xdr_vector (),
714 which serializes fixed-length arrays.
715 .ie t .DS
716 .el .DS L
717 .ft CW
718 int intarr[SIZE];
719
720 xdr_intarr(xdrsp, intarr)
721         XDR *xdrsp;
722         int intarr[];
723 {
724         int i;
725
726         return (xdr_vector(xdrsp, intarr, SIZE, sizeof(int),
727                 xdr_int));
728 }
729 .DE
730 .KE
731 .LP
732 XDR always converts quantities to 4-byte multiples when serializing.
733 Thus, if either of the examples above involved characters
734 instead of integers, each character would occupy 32 bits.
735 That is the reason for the XDR routine
736 .I xdr_bytes()
737 which is like
738 .I xdr_array()
739 except that it packs characters;
740 .I xdr_bytes() 
741 has four parameters, similar to the first four parameters of
742 .I xdr_array ().
743 For null-terminated strings, there is also the
744 .I xdr_string()
745 routine, which is the same as
746 .I xdr_bytes() 
747 without the length parameter.
748 On serializing it gets the string length from
749 .I strlen (),
750 and on deserializing it creates a null-terminated string.
751 .LP
752 Here is a final example that calls the previously written
753 .I xdr_simple() 
754 as well as the built-in functions
755 .I xdr_string() 
756 and
757 .I xdr_reference (),
758 which chases pointers:
759 .ie t .DS
760 .el .DS L
761 .ft CW
762 struct finalexample {
763         char *string;
764         struct simple *simplep;
765 } finalexample;
766
767 xdr_finalexample(xdrsp, finalp)
768         XDR *xdrsp;
769         struct finalexample *finalp;
770 {
771
772         if (!xdr_string(xdrsp, &finalp->string, MAXSTRLEN))
773                 return (0);
774         if (!xdr_reference(xdrsp, &finalp->simplep,
775           sizeof(struct simple), xdr_simple);
776                 return (0);
777         return (1);
778 }
779 .DE
780 Note that we could as easily call
781 .I xdr_simple() 
782 here instead of
783 .I xdr_reference ().
784 .NH 1
785 \&Lowest Layer of RPC
786 .IX "lowest layer of RPC"
787 .IX "RPC" "lowest layer"
788 .LP
789 In the examples given so far,
790 RPC takes care of many details automatically for you.
791 In this section, we'll show you how you can change the defaults
792 by using lower layers of the RPC library.
793 It is assumed that you are familiar with sockets
794 and the system calls for dealing with them.
795 .LP
796 There are several occasions when you may need to use lower layers of 
797 RPC.  First, you may need to use TCP, since the higher layer uses UDP, 
798 which restricts RPC calls to 8K bytes of data.  Using TCP permits calls 
799 to send long streams of data.  
800 For an example, see the
801 .I TCP
802 section below.  Second, you may want to allocate and free memory
803 while serializing or deserializing with XDR routines.  
804 There is no call at the higher level to let 
805 you free memory explicitly.  
806 For more explanation, see the
807 .I "Memory Allocation with XDR"
808 section below.  
809 Third, you may need to perform authentication 
810 on either the client or server side, by supplying 
811 credentials or verifying them.
812 See the explanation in the 
813 .I Authentication
814 section below.
815 .NH 2
816 \&More on the Server Side
817 .IX RPC "server side"
818 .LP
819 The server for the
820 .I nusers() 
821 program shown below does the same thing as the one using
822 .I registerrpc() 
823 above, but is written using a lower layer of the RPC package:
824 .ie t .DS
825 .el .DS L
826 .ft CW
827 #include <stdio.h>
828 #include <rpc/rpc.h>
829 #include <utmp.h>
830 #include <rpcsvc/rusers.h>
831
832 main()
833 {
834         SVCXPRT *transp;
835         int nuser();
836
837         transp = svcudp_create(RPC_ANYSOCK);
838         if (transp == NULL){
839                 fprintf(stderr, "can't create an RPC server\en");
840                 exit(1);
841         }
842         pmap_unset(RUSERSPROG, RUSERSVERS);
843         if (!svc_register(transp, RUSERSPROG, RUSERSVERS,
844                           nuser, IPPROTO_UDP)) {
845                 fprintf(stderr, "can't register RUSER service\en");
846                 exit(1);
847         }
848         svc_run();  /* \fINever returns\fP */
849         fprintf(stderr, "should never reach this point\en");
850 }
851
852 nuser(rqstp, transp)
853         struct svc_req *rqstp;
854         SVCXPRT *transp;
855 {
856         unsigned long nusers;
857
858         switch (rqstp->rq_proc) {
859         case NULLPROC:
860                 if (!svc_sendreply(transp, xdr_void, 0))
861                         fprintf(stderr, "can't reply to RPC call\en");
862                 return;
863         case RUSERSPROC_NUM:
864 .ft I
865                 /*
866                  * Code here to compute the number of users
867                  * and assign it to the variable \fInusers\fP
868                  */
869 .ft CW
870                 if (!svc_sendreply(transp, xdr_u_long, &nusers)) 
871                         fprintf(stderr, "can't reply to RPC call\en");
872                 return;
873         default:
874                 svcerr_noproc(transp);
875                 return;
876         }
877 }
878 .DE
879 .LP
880 First, the server gets a transport handle, which is used
881 for receiving and replying to RPC messages.
882 .I registerrpc() 
883 uses
884 .I svcudp_create()
885 to get a UDP handle.
886 If you require a more reliable protocol, call
887 .I svctcp_create()
888 instead.
889 If the argument to
890 .I svcudp_create() 
891 is
892 .I RPC_ANYSOCK
893 the RPC library creates a socket
894 on which to receive and reply to RPC calls.  Otherwise,
895 .I svcudp_create() 
896 expects its argument to be a valid socket number.
897 If you specify your own socket, it can be bound or unbound.
898 If it is bound to a port by the user, the port numbers of
899 .I svcudp_create() 
900 and
901 .I clnttcp_create()
902 (the low-level client routine) must match.
903 .LP
904 If the user specifies the
905 .I RPC_ANYSOCK 
906 argument, the RPC library routines will open sockets.
907 Otherwise they will expect the user to do so.  The routines
908 .I svcudp_create() 
909 and 
910 .I clntudp_create()
911 will cause the RPC library routines to
912 .I bind() 
913 their socket if it is not bound already.
914 .LP
915 A service may choose to register its port number with the
916 local portmapper service.  This is done is done by specifying
917 a non-zero protocol number in
918 .I svc_register ().
919 Incidently, a client can discover the server's port number by 
920 consulting the portmapper on their server's machine.  This can 
921 be done automatically by specifying a zero port number in 
922 .I clntudp_create() 
923 or
924 .I clnttcp_create ().
925 .LP
926 After creating an
927 .I SVCXPRT ,
928 the next step is to call
929 .I pmap_unset()
930 so that if the
931 .I nusers() 
932 server crashed earlier,
933 any previous trace of it is erased before restarting.
934 More precisely,
935 .I pmap_unset() 
936 erases the entry for
937 .I RUSERSPROG
938 from the port mapper's tables.
939 .LP
940 Finally, we associate the program number for
941 .I nusers() 
942 with the procedure
943 .I nuser ().
944 The final argument to
945 .I svc_register() 
946 is normally the protocol being used,
947 which, in this case, is
948 .I IPPROTO_UDP
949 Notice that unlike
950 .I registerrpc (),
951 there are no XDR routines involved
952 in the registration process.
953 Also, registration is done on the program,
954 rather than procedure, level.
955 .LP
956 The user routine
957 .I nuser() 
958 must call and dispatch the appropriate XDR routines
959 based on the procedure number.
960 Note that
961 two things are handled by
962 .I nuser() 
963 that
964 .I registerrpc() 
965 handles automatically.
966 The first is that procedure
967 .I NULLPROC
968 (currently zero) returns with no results.
969 This can be used as a simple test
970 for detecting if a remote program is running.
971 Second, there is a check for invalid procedure numbers.
972 If one is detected,
973 .I svcerr_noproc()
974 is called to handle the error.
975 .KS
976 .LP
977 The user service routine serializes the results and returns
978 them to the RPC caller via
979 .I svc_sendreply()
980 Its first parameter is the
981 .I SVCXPRT
982 handle, the second is the XDR routine,
983 and the third is a pointer to the data to be returned.
984 Not illustrated above is how a server
985 handles an RPC program that receives data.
986 As an example, we can add a procedure
987 .I RUSERSPROC_BOOL
988 which has an argument
989 .I nusers (),
990 and returns
991 .I TRUE 
992 or
993 .I FALSE 
994 depending on whether there are nusers logged on.
995 It would look like this:
996 .ie t .DS
997 .el .DS L
998 .ft CW
999 case RUSERSPROC_BOOL: {
1000         int bool;
1001         unsigned nuserquery;
1002
1003         if (!svc_getargs(transp, xdr_u_int, &nuserquery) {
1004                 svcerr_decode(transp);
1005                 return;
1006         }
1007 .ft I
1008         /*
1009          * Code to set \fInusers\fP = number of users
1010          */
1011 .ft CW
1012         if (nuserquery == nusers)
1013                 bool = TRUE;
1014         else
1015                 bool = FALSE;
1016         if (!svc_sendreply(transp, xdr_bool, &bool)) {
1017                  fprintf(stderr, "can't reply to RPC call\en");
1018                  return (1);
1019         }
1020         return;
1021 }
1022 .DE
1023 .KE
1024 .LP
1025 The relevant routine is
1026 .I svc_getargs()
1027 which takes an
1028 .I SVCXPRT
1029 handle, the XDR routine,
1030 and a pointer to where the input is to be placed as arguments.
1031 .NH 2
1032 \&Memory Allocation with XDR
1033 .IX "memory allocation with XDR"
1034 .IX XDR "memory allocation"
1035 .LP
1036 XDR routines not only do input and output,
1037 they also do memory allocation.
1038 This is why the second parameter of
1039 .I xdr_array()
1040 is a pointer to an array, rather than the array itself.
1041 If it is
1042 .I NULL ,
1043 then
1044 .I xdr_array()
1045 allocates space for the array and returns a pointer to it,
1046 putting the size of the array in the third argument.
1047 As an example, consider the following XDR routine
1048 .I xdr_chararr1()
1049 which deals with a fixed array of bytes with length
1050 .I SIZE .
1051 .ie t .DS
1052 .el .DS L
1053 .ft CW
1054 xdr_chararr1(xdrsp, chararr)
1055         XDR *xdrsp;
1056         char chararr[];
1057 {
1058         char *p;
1059         int len;
1060
1061         p = chararr;
1062         len = SIZE;
1063         return (xdr_bytes(xdrsp, &p, &len, SIZE));
1064 }
1065 .DE
1066 If space has already been allocated in
1067 .I chararr ,
1068 it can be called from a server like this:
1069 .ie t .DS
1070 .el .DS L
1071 .ft CW
1072 char chararr[SIZE];
1073
1074 svc_getargs(transp, xdr_chararr1, chararr);
1075 .DE
1076 If you want XDR to do the allocation,
1077 you would have to rewrite this routine in the following way:
1078 .ie t .DS
1079 .el .DS L
1080 .ft CW
1081 xdr_chararr2(xdrsp, chararrp)
1082         XDR *xdrsp;
1083         char **chararrp;
1084 {
1085         int len;
1086
1087         len = SIZE;
1088         return (xdr_bytes(xdrsp, charrarrp, &len, SIZE));
1089 }
1090 .DE
1091 Then the RPC call might look like this:
1092 .ie t .DS
1093 .el .DS L
1094 .ft CW
1095 char *arrptr;
1096
1097 arrptr = NULL;
1098 svc_getargs(transp, xdr_chararr2, &arrptr);
1099 .ft I
1100 /*
1101  * Use the result here
1102  */
1103 .ft CW
1104 svc_freeargs(transp, xdr_chararr2, &arrptr);
1105 .DE
1106 Note that, after being used, the character array can be freed with
1107 .I svc_freeargs()
1108 .I svc_freeargs() 
1109 will not attempt to free any memory if the variable indicating it 
1110 is NULL.  For example, in the the routine 
1111 .I xdr_finalexample (),
1112 given earlier, if
1113 .I finalp->string 
1114 was NULL, then it would not be freed.  The same is true for 
1115 .I finalp->simplep .
1116 .LP
1117 To summarize, each XDR routine is responsible
1118 for serializing, deserializing, and freeing memory.
1119 When an XDR routine is called from
1120 .I callrpc()
1121 the serializing part is used.
1122 When called from
1123 .I svc_getargs()
1124 the deserializer is used.
1125 And when called from
1126 .I svc_freeargs()
1127 the memory deallocator is used.  When building simple examples like those
1128 in this section, a user doesn't have to worry 
1129 about the three modes.  
1130 See the
1131 .I "External Data Representation: Sun Technical Notes"
1132 for examples of more sophisticated XDR routines that determine 
1133 which of the three modes they are in and adjust their behavior accordingly.
1134 .KS
1135 .NH 2
1136 \&The Calling Side
1137 .IX RPC "calling side"
1138 .LP
1139 When you use
1140 .I callrpc()
1141 you have no control over the RPC delivery
1142 mechanism or the socket used to transport the data.
1143 To illustrate the layer of RPC that lets you adjust these
1144 parameters, consider the following code to call the
1145 .I nusers
1146 service:
1147 .ie t .DS
1148 .el .DS L
1149 .ft CW
1150 .vs 11
1151 #include <stdio.h>
1152 #include <rpc/rpc.h>
1153 #include <utmp.h>
1154 #include <rpcsvc/rusers.h>
1155 #include <sys/socket.h>
1156 #include <sys/time.h>
1157 #include <netdb.h>
1158
1159 main(argc, argv)
1160         int argc;
1161         char **argv;
1162 {
1163         struct hostent *hp;
1164         struct timeval pertry_timeout, total_timeout;
1165         struct sockaddr_in server_addr;
1166         int sock = RPC_ANYSOCK;
1167         register CLIENT *client;
1168         enum clnt_stat clnt_stat;
1169         unsigned long nusers;
1170
1171         if (argc != 2) {
1172                 fprintf(stderr, "usage: nusers hostname\en");
1173                 exit(-1);
1174         }
1175         if ((hp = gethostbyname(argv[1])) == NULL) {
1176                 fprintf(stderr, "can't get addr for %s\en",argv[1]);
1177                 exit(-1);
1178         }
1179         pertry_timeout.tv_sec = 3;
1180         pertry_timeout.tv_usec = 0;
1181         bcopy(hp->h_addr, (caddr_t)&server_addr.sin_addr,
1182                 hp->h_length);
1183         server_addr.sin_family = AF_INET;
1184         server_addr.sin_port =  0;
1185         if ((client = clntudp_create(&server_addr, RUSERSPROG,
1186           RUSERSVERS, pertry_timeout, &sock)) == NULL) {
1187                 clnt_pcreateerror("clntudp_create");
1188                 exit(-1);
1189         }
1190         total_timeout.tv_sec = 20;
1191         total_timeout.tv_usec = 0;
1192         clnt_stat = clnt_call(client, RUSERSPROC_NUM, xdr_void,
1193                 0, xdr_u_long, &nusers, total_timeout);
1194         if (clnt_stat != RPC_SUCCESS) {
1195                 clnt_perror(client, "rpc");
1196                 exit(-1);
1197         }
1198         clnt_destroy(client);
1199         close(sock);
1200         exit(0);
1201 }
1202 .vs
1203 .DE
1204 .KE
1205 The low-level version of
1206 .I callrpc()
1207 is
1208 .I clnt_call()
1209 which takes a
1210 .I CLIENT
1211 pointer rather than a host name.  The parameters to
1212 .I clnt_call() 
1213 are a
1214 .I CLIENT 
1215 pointer, the procedure number,
1216 the XDR routine for serializing the argument,
1217 a pointer to the argument,
1218 the XDR routine for deserializing the return value,
1219 a pointer to where the return value will be placed,
1220 and the time in seconds to wait for a reply.
1221 .LP
1222 The
1223 .I CLIENT 
1224 pointer is encoded with the transport mechanism.
1225 .I callrpc()
1226 uses UDP, thus it calls
1227 .I clntudp_create() 
1228 to get a
1229 .I CLIENT 
1230 pointer.  To get TCP (Transmission Control Protocol), you would use
1231 .I clnttcp_create() .
1232 .LP
1233 The parameters to
1234 .I clntudp_create() 
1235 are the server address, the program number, the version number,
1236 a timeout value (between tries), and a pointer to a socket.
1237 The final argument to
1238 .I clnt_call() 
1239 is the total time to wait for a response.
1240 Thus, the number of tries is the
1241 .I clnt_call() 
1242 timeout divided by the
1243 .I clntudp_create() 
1244 timeout.
1245 .LP
1246 Note that the
1247 .I clnt_destroy()
1248 call
1249 always deallocates the space associated with the
1250 .I CLIENT 
1251 handle.  It closes the socket associated with the
1252 .I CLIENT 
1253 handle, however, only if the RPC library opened it.  It the
1254 socket was opened by the user, it stays open.  This makes it
1255 possible, in cases where there are multiple client handles
1256 using the same socket, to destroy one handle without closing
1257 the socket that other handles are using.
1258 .LP
1259 To make a stream connection, the call to
1260 .I clntudp_create() 
1261 is replaced with a call to
1262 .I clnttcp_create() .
1263 .DS
1264 .ft CW
1265 clnttcp_create(&server_addr, prognum, versnum, &sock,
1266                inputsize, outputsize);
1267 .DE
1268 There is no timeout argument; instead, the receive and send buffer
1269 sizes must be specified.  When the
1270 .I clnttcp_create() 
1271 call is made, a TCP connection is established.
1272 All RPC calls using that
1273 .I CLIENT 
1274 handle would use this connection.
1275 The server side of an RPC call using TCP has
1276 .I svcudp_create()
1277 replaced by
1278 .I svctcp_create() .
1279 .DS
1280 .ft CW
1281 transp = svctcp_create(RPC_ANYSOCK, 0, 0);
1282 .DE
1283 The last two arguments to 
1284 .I svctcp_create() 
1285 are send and receive sizes respectively.  If `0' is specified for 
1286 either of these, the system chooses a reasonable default.
1287 .KS
1288 .NH 1
1289 \&Other RPC Features
1290 .IX "RPC" "miscellaneous features"
1291 .IX "miscellaneous RPC features"
1292 .LP
1293 This section discusses some other aspects of RPC
1294 that are occasionally useful.
1295 .NH 2
1296 \&Select on the Server Side
1297 .IX RPC select() RPC \fIselect()\fP
1298 .IX select() "" \fIselect()\fP "on the server side"
1299 .LP
1300 Suppose a process is processing RPC requests
1301 while performing some other activity.
1302 If the other activity involves periodically updating a data structure,
1303 the process can set an alarm signal before calling
1304 .I svc_run()
1305 But if the other activity
1306 involves waiting on a a file descriptor, the
1307 .I svc_run()
1308 call won't work.
1309 The code for
1310 .I svc_run()
1311 is as follows:
1312 .ie t .DS
1313 .el .DS L
1314 .ft CW
1315 .vs 11
1316 void
1317 svc_run()
1318 {
1319         fd_set readfds;
1320         int dtbsz = getdtablesize();
1321
1322         for (;;) {
1323                 readfds = svc_fds;
1324                 switch (select(dtbsz, &readfds, NULL,NULL,NULL)) {
1325
1326                 case -1:
1327                         if (errno == EINTR)
1328                                 continue;
1329                         perror("select");
1330                         return;
1331                 case 0:
1332                         break;
1333                 default:
1334                         svc_getreqset(&readfds);
1335                 }
1336         }
1337 }
1338 .vs
1339 .DE
1340 .KE
1341 .LP
1342 You can bypass
1343 .I svc_run()
1344 and call
1345 .I svc_getreqset()
1346 yourself.
1347 All you need to know are the file descriptors
1348 of the socket(s) associated with the programs you are waiting on.
1349 Thus you can have your own
1350 .I select() 
1351 .IX select() "" \fIselect()\fP
1352 that waits on both the RPC socket,
1353 and your own descriptors.  Note that
1354 .I svc_fds() 
1355 is a bit mask of all the file descriptors that RPC is using for 
1356 services.  It can change everytime that
1357 .I any
1358 RPC library routine is called, because descriptors are constantly 
1359 being opened and closed, for example for TCP connections.
1360 .NH 2
1361 \&Broadcast RPC
1362 .IX "broadcast RPC"
1363 .IX RPC "broadcast"
1364 .LP
1365 The
1366 .I portmapper
1367 is a daemon that converts RPC program numbers
1368 into DARPA protocol port numbers; see the
1369 .I portmap 
1370 man page.  You can't do broadcast RPC without the portmapper.
1371 Here are the main differences between
1372 broadcast RPC and normal RPC calls:
1373 .IP  1.
1374 Normal RPC expects one answer, whereas
1375 broadcast RPC expects many answers
1376 (one or more answer from each responding machine).
1377 .IP  2.
1378 Broadcast RPC can only be supported by packet-oriented (connectionless)
1379 transport protocols like UPD/IP.
1380 .IP  3.
1381 The implementation of broadcast RPC
1382 treats all unsuccessful responses as garbage by filtering them out.
1383 Thus, if there is a version mismatch between the
1384 broadcaster and a remote service,
1385 the user of broadcast RPC never knows.
1386 .IP  4.
1387 All broadcast messages are sent to the portmap port.
1388 Thus, only services that register themselves with their portmapper
1389 are accessible via the broadcast RPC mechanism.
1390 .IP  5.
1391 Broadcast requests are limited in size to the MTU (Maximum Transfer
1392 Unit) of the local network.  For Ethernet, the MTU is 1500 bytes.
1393 .KS
1394 .NH 3
1395 \&Broadcast RPC Synopsis
1396 .IX "broadcast RPC" synopsis
1397 .IX "RPC" "broadcast synopsis"
1398 .ie t .DS
1399 .el .DS L
1400 .ft CW
1401 #include <rpc/pmap_clnt.h>
1402         . . .
1403 enum clnt_stat  clnt_stat;
1404         . . .
1405 clnt_stat = clnt_broadcast(prognum, versnum, procnum,
1406   inproc, in, outproc, out, eachresult)
1407         u_long    prognum;        /* \fIprogram number\fP */
1408         u_long    versnum;        /* \fIversion number\fP */
1409         u_long    procnum;        /* \fIprocedure number\fP */
1410         xdrproc_t inproc;         /* \fIxdr routine for args\fP */
1411         caddr_t   in;             /* \fIpointer to args\fP */
1412         xdrproc_t outproc;        /* \fIxdr routine for results\fP */
1413         caddr_t   out;            /* \fIpointer to results\fP */
1414         bool_t    (*eachresult)();/* \fIcall with each result gotten\fP */
1415 .DE
1416 .KE
1417 The procedure
1418 .I eachresult()
1419 is called each time a valid result is obtained.
1420 It returns a boolean that indicates
1421 whether or not the user wants more responses.
1422 .ie t .DS
1423 .el .DS L
1424 .ft CW
1425 bool_t done;
1426         . . . 
1427 done = eachresult(resultsp, raddr)
1428         caddr_t resultsp;
1429         struct sockaddr_in *raddr; /* \fIAddr of responding machine\fP */
1430 .DE
1431 If
1432 .I done
1433 is
1434 .I TRUE ,
1435 then broadcasting stops and
1436 .I clnt_broadcast()
1437 returns successfully.
1438 Otherwise, the routine waits for another response.
1439 The request is rebroadcast
1440 after a few seconds of waiting.
1441 If no responses come back,
1442 the routine returns with
1443 .I RPC_TIMEDOUT .
1444 .NH 2
1445 \&Batching
1446 .IX "batching"
1447 .IX RPC "batching"
1448 .LP
1449 The RPC architecture is designed so that clients send a call message,
1450 and wait for servers to reply that the call succeeded.
1451 This implies that clients do not compute
1452 while servers are processing a call.
1453 This is inefficient if the client does not want or need
1454 an acknowledgement for every message sent.
1455 It is possible for clients to continue computing
1456 while waiting for a response,
1457 using RPC batch facilities.
1458 .LP
1459 RPC messages can be placed in a \*Qpipeline\*U of calls
1460 to a desired server; this is called batching.
1461 Batching assumes that:
1462 1) each RPC call in the pipeline requires no response from the server,
1463 and the server does not send a response message; and
1464 2) the pipeline of calls is transported on a reliable
1465 byte stream transport such as TCP/IP.
1466 Since the server does not respond to every call,
1467 the client can generate new calls in parallel
1468 with the server executing previous calls.
1469 Furthermore, the TCP/IP implementation can buffer up
1470 many call messages, and send them to the server in one
1471 .I write()
1472 system call.  This overlapped execution
1473 greatly decreases the interprocess communication overhead of
1474 the client and server processes,
1475 and the total elapsed time of a series of calls.
1476 .LP
1477 Since the batched calls are buffered,
1478 the client should eventually do a nonbatched call
1479 in order to flush the pipeline.
1480 .LP
1481 A contrived example of batching follows.
1482 Assume a string rendering service (like a window system)
1483 has two similar calls: one renders a string and returns void results,
1484 while the other renders a string and remains silent.
1485 The service (using the TCP/IP transport) may look like:
1486 .ie t .DS
1487 .el .DS L
1488 .ft CW
1489 #include <stdio.h>
1490 #include <rpc/rpc.h>
1491 #include <suntool/windows.h>
1492
1493 void windowdispatch();
1494
1495 main()
1496 {
1497         SVCXPRT *transp;
1498
1499         transp = svctcp_create(RPC_ANYSOCK, 0, 0);
1500         if (transp == NULL){
1501                 fprintf(stderr, "can't create an RPC server\en");
1502                 exit(1);
1503         }
1504         pmap_unset(WINDOWPROG, WINDOWVERS);
1505         if (!svc_register(transp, WINDOWPROG, WINDOWVERS,
1506           windowdispatch, IPPROTO_TCP)) {
1507                 fprintf(stderr, "can't register WINDOW service\en");
1508                 exit(1);
1509         }
1510         svc_run();  /* \fINever returns\fP */
1511         fprintf(stderr, "should never reach this point\en");
1512 }
1513
1514 void
1515 windowdispatch(rqstp, transp)
1516         struct svc_req *rqstp;
1517         SVCXPRT *transp;
1518 {
1519         char *s = NULL;
1520
1521         switch (rqstp->rq_proc) {
1522         case NULLPROC:
1523                 if (!svc_sendreply(transp, xdr_void, 0)) 
1524                         fprintf(stderr, "can't reply to RPC call\en");
1525                 return;
1526         case RENDERSTRING:
1527                 if (!svc_getargs(transp, xdr_wrapstring, &s)) {
1528                         fprintf(stderr, "can't decode arguments\en");
1529 .ft I
1530                         /*
1531                          * Tell caller he screwed up
1532                          */
1533 .ft CW
1534                         svcerr_decode(transp);
1535                         break;
1536                 }
1537 .ft I
1538                 /*
1539                  * Code here to render the string \fIs\fP
1540                  */
1541 .ft CW
1542                 if (!svc_sendreply(transp, xdr_void, NULL)) 
1543                         fprintf(stderr, "can't reply to RPC call\en");
1544                 break;
1545         case RENDERSTRING_BATCHED:
1546                 if (!svc_getargs(transp, xdr_wrapstring, &s)) {
1547                         fprintf(stderr, "can't decode arguments\en");
1548 .ft I
1549                         /*
1550                          * We are silent in the face of protocol errors
1551                          */
1552 .ft CW
1553                         break;
1554                 }
1555 .ft I
1556                 /*
1557                  * Code here to render string s, but send no reply!
1558                  */
1559 .ft CW
1560                 break;
1561         default:
1562                 svcerr_noproc(transp);
1563                 return;
1564         }
1565 .ft I
1566         /*
1567          * Now free string allocated while decoding arguments
1568          */
1569 .ft CW
1570         svc_freeargs(transp, xdr_wrapstring, &s);
1571 }
1572 .DE
1573 Of course the service could have one procedure
1574 that takes the string and a boolean
1575 to indicate whether or not the procedure should respond.
1576 .LP
1577 In order for a client to take advantage of batching,
1578 the client must perform RPC calls on a TCP-based transport
1579 and the actual calls must have the following attributes:
1580 1) the result's XDR routine must be zero
1581 .I NULL ),
1582 and 2) the RPC call's timeout must be zero.
1583 .KS
1584 .LP
1585 Here is an example of a client that uses batching to render a
1586 bunch of strings; the batching is flushed when the client gets
1587 a null string (EOF):
1588 .ie t .DS
1589 .el .DS L
1590 .ft CW
1591 .vs 11
1592 #include <stdio.h>
1593 #include <rpc/rpc.h>
1594 #include <sys/socket.h>
1595 #include <sys/time.h>
1596 #include <netdb.h>
1597 #include <suntool/windows.h>
1598
1599 main(argc, argv)
1600         int argc;
1601         char **argv;
1602 {
1603         struct hostent *hp;
1604         struct timeval pertry_timeout, total_timeout;
1605         struct sockaddr_in server_addr;
1606         int sock = RPC_ANYSOCK;
1607         register CLIENT *client;
1608         enum clnt_stat clnt_stat;
1609         char buf[1000], *s = buf;
1610
1611         if ((client = clnttcp_create(&server_addr,
1612           WINDOWPROG, WINDOWVERS, &sock, 0, 0)) == NULL) {
1613                 perror("clnttcp_create");
1614                 exit(-1);
1615         }
1616         total_timeout.tv_sec = 0;
1617         total_timeout.tv_usec = 0;
1618         while (scanf("%s", s) != EOF) {
1619                 clnt_stat = clnt_call(client, RENDERSTRING_BATCHED,
1620                         xdr_wrapstring, &s, NULL, NULL, total_timeout);
1621                 if (clnt_stat != RPC_SUCCESS) {
1622                         clnt_perror(client, "batched rpc");
1623                         exit(-1);
1624                 }
1625         }
1626
1627         /* \fINow flush the pipeline\fP */
1628
1629         total_timeout.tv_sec = 20;
1630         clnt_stat = clnt_call(client, NULLPROC, xdr_void, NULL,
1631                 xdr_void, NULL, total_timeout);
1632         if (clnt_stat != RPC_SUCCESS) {
1633                 clnt_perror(client, "rpc");
1634                 exit(-1);
1635         }
1636         clnt_destroy(client);
1637         exit(0);
1638 }
1639 .vs
1640 .DE
1641 .KE
1642 Since the server sends no message,
1643 the clients cannot be notified of any of the failures that may occur.
1644 Therefore, clients are on their own when it comes to handling errors.
1645 .LP
1646 The above example was completed to render
1647 all of the (2000) lines in the file
1648 .I /etc/termcap .
1649 The rendering service did nothing but throw the lines away.
1650 The example was run in the following four configurations:
1651 1) machine to itself, regular RPC;
1652 2) machine to itself, batched RPC;
1653 3) machine to another, regular RPC; and
1654 4) machine to another, batched RPC.
1655 The results are as follows:
1656 1) 50 seconds;
1657 2) 16 seconds;
1658 3) 52 seconds;
1659 4) 10 seconds.
1660 Running
1661 .I fscanf()
1662 on
1663 .I /etc/termcap
1664 only requires six seconds.
1665 These timings show the advantage of protocols
1666 that allow for overlapped execution,
1667 though these protocols are often hard to design.
1668 .NH 2
1669 \&Authentication
1670 .IX "authentication"
1671 .IX "RPC" "authentication"
1672 .LP
1673 In the examples presented so far,
1674 the caller never identified itself to the server,
1675 and the server never required an ID from the caller.
1676 Clearly, some network services, such as a network filesystem,
1677 require stronger security than what has been presented so far.
1678 .LP
1679 In reality, every RPC call is authenticated by
1680 the RPC package on the server, and similarly,
1681 the RPC client package generates and sends authentication parameters.
1682 Just as different transports (TCP/IP or UDP/IP)
1683 can be used when creating RPC clients and servers,
1684 different forms of authentication can be associated with RPC clients;
1685 the default authentication type used as a default is type
1686 .I none .
1687 .LP
1688 The authentication subsystem of the RPC package is open ended.
1689 That is, numerous types of authentication are easy to support.
1690 .NH 3
1691 \&UNIX Authentication
1692 .IX "UNIX Authentication"
1693 .IP "\fIThe Client Side\fP"
1694 .LP
1695 When a caller creates a new RPC client handle as in:
1696 .DS
1697 .ft CW
1698 clnt = clntudp_create(address, prognum, versnum,
1699                       wait, sockp)
1700 .DE
1701 the appropriate transport instance defaults
1702 the associate authentication handle to be
1703 .DS
1704 .ft CW
1705 clnt->cl_auth = authnone_create();
1706 .DE
1707 The RPC client can choose to use
1708 .I UNIX
1709 style authentication by setting
1710 .I clnt\->cl_auth
1711 after creating the RPC client handle:
1712 .DS
1713 .ft CW
1714 clnt->cl_auth = authunix_create_default();
1715 .DE
1716 This causes each RPC call associated with
1717 .I clnt
1718 to carry with it the following authentication credentials structure:
1719 .ie t .DS
1720 .el .DS L
1721 .ft I
1722 /*
1723  * UNIX style credentials.
1724  */
1725 .ft CW
1726 struct authunix_parms {
1727     u_long  aup_time;       /* \fIcredentials creation time\fP */
1728     char    *aup_machname;  /* \fIhost name where client is\fP */
1729     int     aup_uid;        /* \fIclient's UNIX effective uid\fP */
1730     int     aup_gid;        /* \fIclient's current group id\fP */
1731     u_int   aup_len;        /* \fIelement length of aup_gids\fP */
1732     int     *aup_gids;      /* \fIarray of groups user is in\fP */
1733 };
1734 .DE
1735 These fields are set by
1736 .I authunix_create_default()
1737 by invoking the appropriate system calls.
1738 Since the RPC user created this new style of authentication,
1739 the user is responsible for destroying it with:
1740 .DS
1741 .ft CW
1742 auth_destroy(clnt->cl_auth);
1743 .DE
1744 This should be done in all cases, to conserve memory.
1745 .sp
1746 .IP "\fIThe Server Side\fP"
1747 .LP
1748 Service implementors have a harder time dealing with authentication issues
1749 since the RPC package passes the service dispatch routine a request
1750 that has an arbitrary authentication style associated with it.
1751 Consider the fields of a request handle passed to a service dispatch routine:
1752 .ie t .DS
1753 .el .DS L
1754 .ft I
1755 /*
1756  * An RPC Service request
1757  */
1758 .ft CW
1759 struct svc_req {
1760     u_long    rq_prog;          /* \fIservice program number\fP */
1761     u_long    rq_vers;          /* \fIservice protocol vers num\fP */
1762     u_long    rq_proc;          /* \fIdesired procedure number\fP */
1763     struct opaque_auth rq_cred; /* \fIraw credentials from wire\fP */
1764     caddr_t   rq_clntcred;  /* \fIcredentials (read only)\fP */
1765 };
1766 .DE
1767 The
1768 .I rq_cred
1769 is mostly opaque, except for one field of interest:
1770 the style or flavor of authentication credentials:
1771 .ie t .DS
1772 .el .DS L
1773 .ft I
1774 /*
1775  * Authentication info.  Mostly opaque to the programmer.
1776  */
1777 .ft CW
1778 struct opaque_auth {
1779     enum_t  oa_flavor;  /* \fIstyle of credentials\fP */
1780     caddr_t oa_base;    /* \fIaddress of more auth stuff\fP */
1781     u_int   oa_length;  /* \fInot to exceed \fIMAX_AUTH_BYTES */
1782 };
1783 .DE
1784 .IX RPC guarantees
1785 The RPC package guarantees the following
1786 to the service dispatch routine:
1787 .IP  1.
1788 That the request's
1789 .I rq_cred
1790 is well formed.  Thus the service implementor may inspect the request's
1791 .I rq_cred.oa_flavor
1792 to determine which style of authentication the caller used.
1793 The service implementor may also wish to inspect the other fields of
1794 .I rq_cred
1795 if the style is not one of the styles supported by the RPC package.
1796 .IP  2.
1797 That the request's
1798 .I rq_clntcred
1799 field is either
1800 .I NULL 
1801 or points to a well formed structure
1802 that corresponds to a supported style of authentication credentials.
1803 Remember that only
1804 .I unix
1805 style is currently supported, so (currently)
1806 .I rq_clntcred
1807 could be cast to a pointer to an
1808 .I authunix_parms
1809 structure.  If
1810 .I rq_clntcred
1811 is
1812 .I NULL ,
1813 the service implementor may wish to inspect the other (opaque) fields of
1814 .I rq_cred
1815 in case the service knows about a new type of authentication
1816 that the RPC package does not know about.
1817 .LP
1818 Our remote users service example can be extended so that
1819 it computes results for all users except UID 16:
1820 .ie t .DS
1821 .el .DS L
1822 .ft CW
1823 .vs 11
1824 nuser(rqstp, transp)
1825         struct svc_req *rqstp;
1826         SVCXPRT *transp;
1827 {
1828         struct authunix_parms *unix_cred;
1829         int uid;
1830         unsigned long nusers;
1831
1832 .ft I
1833         /*
1834          * we don't care about authentication for null proc
1835          */
1836 .ft CW
1837         if (rqstp->rq_proc == NULLPROC) {
1838                 if (!svc_sendreply(transp, xdr_void, 0)) {
1839                         fprintf(stderr, "can't reply to RPC call\en");
1840                         return (1);
1841                  }
1842                  return;
1843         }
1844 .ft I
1845         /*
1846          * now get the uid
1847          */
1848 .ft CW
1849         switch (rqstp->rq_cred.oa_flavor) {
1850         case AUTH_UNIX:
1851                 unix_cred = 
1852                         (struct authunix_parms *)rqstp->rq_clntcred;
1853                 uid = unix_cred->aup_uid;
1854                 break;
1855         case AUTH_NULL:
1856         default:
1857                 svcerr_weakauth(transp);
1858                 return;
1859         }
1860         switch (rqstp->rq_proc) {
1861         case RUSERSPROC_NUM:
1862 .ft I
1863                 /*
1864                  * make sure caller is allowed to call this proc
1865                  */
1866 .ft CW
1867                 if (uid == 16) {
1868                         svcerr_systemerr(transp);
1869                         return;
1870                 }
1871 .ft I
1872                 /*
1873                  * Code here to compute the number of users
1874                  * and assign it to the variable \fInusers\fP
1875                  */
1876 .ft CW
1877                 if (!svc_sendreply(transp, xdr_u_long, &nusers)) {
1878                         fprintf(stderr, "can't reply to RPC call\en");
1879                         return (1);
1880                 }
1881                 return;
1882         default:
1883                 svcerr_noproc(transp);
1884                 return;
1885         }
1886 }
1887 .vs
1888 .DE
1889 A few things should be noted here.
1890 First, it is customary not to check
1891 the authentication parameters associated with the
1892 .I NULLPROC
1893 (procedure number zero).
1894 Second, if the authentication parameter's type is not suitable
1895 for your service, you should call
1896 .I svcerr_weakauth() .
1897 And finally, the service protocol itself should return status
1898 for access denied; in the case of our example, the protocol
1899 does not have such a status, so we call the service primitive
1900 .I svcerr_systemerr()
1901 instead.
1902 .LP
1903 The last point underscores the relation between
1904 the RPC authentication package and the services;
1905 RPC deals only with 
1906 .I authentication 
1907 and not with individual services' 
1908 .I "access control" .
1909 The services themselves must implement their own access control policies
1910 and reflect these policies as return statuses in their protocols.
1911 .NH 2
1912 \&DES Authentication
1913 .IX RPC DES
1914 .IX RPC authentication
1915 .LP
1916 UNIX authentication is quite easy to defeat.  Instead of using
1917 .I authunix_create_default (),
1918 one can call
1919 .I authunix_create() 
1920 and then modify the RPC authentication handle it returns by filling in
1921 whatever user ID and hostname they wish the server to think they have.
1922 DES authentication is thus recommended for people who want more security
1923 than UNIX authentication offers.
1924 .LP
1925 The details of the DES authentication protocol are complicated and
1926 are not explained here.  
1927 See
1928 .I "Remote Procedure Calls: Protocol Specification"
1929 for the details.
1930 .LP
1931 In  order for  DES authentication   to  work, the
1932 .I keyserv(8c) 
1933 daemon must be running  on both  the  server  and client machines.  The
1934 users on  these machines  need  public  keys  assigned by  the network
1935 administrator in  the
1936 .I publickey(5) 
1937 database.  And,  they  need to have decrypted  their  secret keys
1938 using  their  login   password.  This automatically happens when one
1939 logs in using
1940 .I login(1) ,
1941 or can be done manually using
1942 .I keylogin(1) .
1943 The
1944 .I "Network Services"
1945 chapter
1946 .\" XXX
1947 explains more how to setup secure networking.
1948 .sp
1949 .IP "\fIClient Side\fP"
1950 .LP
1951 If a client wishes to use DES authentication, it must set its
1952 authentication handle appropriately.  Here is an example:
1953 .DS
1954 cl->cl_auth =
1955         authdes_create(servername, 60, &server_addr, NULL);
1956 .DE
1957 The first argument is the network name or \*Qnetname\*U of the owner of
1958 the server process.  Typically, server processes are root processes
1959 and their netname can be derived using the following call:
1960 .DS
1961 char servername[MAXNETNAMELEN];
1962
1963 host2netname(servername, rhostname, NULL);
1964 .DE
1965 Here,
1966 .I rhostname
1967 is the hostname of the machine the server process is running on.
1968 .I host2netname() 
1969 fills in
1970 .I servername
1971 to contain this root process's netname.  If the
1972 server process was run by a regular user, one could use the call
1973 .I user2netname() 
1974 instead.  Here is an example for a server process with the same user
1975 ID as the client:
1976 .DS
1977 char servername[MAXNETNAMELEN];
1978
1979 user2netname(servername, getuid(), NULL);
1980 .DE
1981 The last argument to both of these calls,
1982 .I user2netname() 
1983 and
1984 .I host2netname (),
1985 is the name of the naming domain where the server is located.  The
1986 .I NULL 
1987 used here means \*Quse the local domain name.\*U
1988 .LP
1989 The second argument to
1990 .I authdes_create() 
1991 is a lifetime for the credential.  Here it is set to sixty
1992 seconds.  What that means is that the credential will expire 60
1993 seconds from now.  If some mischievous user tries to reuse the
1994 credential, the server RPC subsystem will recognize that it has
1995 expired and not grant any requests.  If the same mischievous user
1996 tries to reuse the credential within the sixty second lifetime,
1997 he will still be rejected because the server RPC subsystem
1998 remembers which credentials it has already seen in the near past,
1999 and will not grant requests to duplicates.
2000 .LP
2001 The third argument to
2002 .I authdes_create() 
2003 is the address of the host to synchronize with.  In order for DES
2004 authentication to work, the server and client must agree upon the
2005 time.  Here we pass the address of the server itself, so the
2006 client and server will both be using the same time: the server's
2007 time.  The argument can be
2008 .I NULL ,
2009 which means \*Qdon't bother synchronizing.\*U You should only do this
2010 if you are sure the client and server are already synchronized.
2011 .LP
2012 The final argument to
2013 .I authdes_create() 
2014 is the address of a DES encryption key to use for encrypting
2015 timestamps and data.  If this argument is
2016 .I NULL ,
2017 as it is in this example, a random key will be chosen.  The client
2018 may find out the encryption key being used by consulting the
2019 .I ah_key 
2020 field of the authentication handle.
2021 .sp
2022 .IP "\fIServer Side\fP"
2023 .LP
2024 The server side is a lot simpler than the client side.  Here is the
2025 previous example rewritten to use
2026 .I AUTH_DES
2027 instead of
2028 .I AUTH_UNIX :
2029 .ie t .DS
2030 .el .DS L
2031 .ft CW
2032 .vs 11
2033 #include <sys/time.h>
2034 #include <rpc/auth_des.h>
2035         . . .
2036         . . .
2037 nuser(rqstp, transp)
2038         struct svc_req *rqstp;
2039         SVCXPRT *transp;
2040 {
2041         struct authdes_cred *des_cred;
2042         int uid;
2043         int gid;
2044         int gidlen;
2045         int gidlist[10];
2046 .ft I
2047         /*
2048          * we don't care about authentication for null proc
2049          */
2050 .ft CW
2051
2052         if (rqstp->rq_proc == NULLPROC) { 
2053                 /* \fIsame as before\fP */
2054         }
2055
2056 .ft I
2057         /*
2058          * now get the uid
2059          */
2060 .ft CW
2061         switch (rqstp->rq_cred.oa_flavor) {
2062         case AUTH_DES:
2063                 des_cred =
2064                         (struct authdes_cred *) rqstp->rq_clntcred;
2065                 if (! netname2user(des_cred->adc_fullname.name,
2066                         &uid, &gid, &gidlen, gidlist))
2067                 {
2068                         fprintf(stderr, "unknown user: %s\en",
2069                                 des_cred->adc_fullname.name);
2070                         svcerr_systemerr(transp);
2071                         return;
2072                 }
2073                 break;
2074         case AUTH_NULL:
2075         default:
2076                 svcerr_weakauth(transp);
2077                 return;
2078         }
2079
2080 .ft I
2081         /*
2082          * The rest is the same as before
2083          */     
2084 .ft CW
2085 .vs
2086 .DE
2087 Note the use of the routine
2088 .I netname2user (),
2089 the inverse of
2090 .I user2netname ():
2091 it takes a network ID and converts to a unix ID.
2092 .I netname2user () 
2093 also supplies the group IDs which we don't use in this example,
2094 but which may be useful to other UNIX programs.
2095 .NH 2
2096 \&Using Inetd
2097 .IX inetd "" "using \fIinetd\fP"
2098 .LP
2099 An RPC server can be started from
2100 .I inetd
2101 The only difference from the usual code is that the service
2102 creation routine should be called in the following form:
2103 .ie t .DS
2104 .el .DS L
2105 .ft CW
2106 transp = svcudp_create(0);     /* \fIFor UDP\fP */
2107 transp = svctcp_create(0,0,0); /* \fIFor listener TCP sockets\fP */
2108 transp = svcfd_create(0,0,0);  /* \fIFor connected TCP sockets\fP */
2109 .DE
2110 since
2111 .I inet
2112 passes a socket as file descriptor 0.
2113 Also,
2114 .I svc_register()
2115 should be called as
2116 .ie t .DS
2117 .el .DS L
2118 .ft CW
2119 svc_register(transp, PROGNUM, VERSNUM, service, 0);
2120 .DE
2121 with the final flag as 0,
2122 since the program would already be registered by
2123 .I inetd
2124 Remember that if you want to exit
2125 from the server process and return control to
2126 .I inet
2127 you need to explicitly exit, since
2128 .I svc_run()
2129 never returns.
2130 .LP
2131 The format of entries in 
2132 .I /etc/inetd.conf 
2133 for RPC services is in one of the following two forms:
2134 .ie t .DS
2135 .el .DS L
2136 .ft CW
2137 p_name/version dgram  rpc/udp wait/nowait user server args
2138 p_name/version stream rpc/tcp wait/nowait user server args
2139 .DE
2140 where
2141 .I p_name
2142 is the symbolic name of the program as it appears in
2143 .I rpc(5) ,
2144 .I server
2145 is the program implementing the server,
2146 and
2147 .I program
2148 and
2149 .I version
2150 are the program and version numbers of the service.
2151 For more information, see
2152 .I inetd.conf(5) .
2153 .LP
2154 If the same program handles multiple versions,
2155 then the version number can be a range,
2156 as in this example:
2157 .ie t .DS
2158 .el .DS L
2159 .ft CW
2160 rstatd/1-2 dgram rpc/udp wait root /usr/etc/rpc.rstatd
2161 .DE
2162 .NH 1
2163 \&More Examples
2164 .sp 1
2165 .NH 2
2166 \&Versions
2167 .IX "versions"
2168 .IX "RPC" "versions"
2169 .LP
2170 By convention, the first version number of program
2171 .I PROG
2172 is
2173 .I PROGVERS_ORIG
2174 and the most recent version is
2175 .I PROGVERS
2176 Suppose there is a new version of the
2177 .I user
2178 program that returns an
2179 .I "unsigned short"
2180 rather than a
2181 .I long .
2182 If we name this version
2183 .I RUSERSVERS_SHORT
2184 then a server that wants to support both versions
2185 would do a double register.
2186 .ie t .DS
2187 .el .DS L
2188 .ft CW
2189 if (!svc_register(transp, RUSERSPROG, RUSERSVERS_ORIG,
2190   nuser, IPPROTO_TCP)) {
2191         fprintf(stderr, "can't register RUSER service\en");
2192         exit(1);
2193 }
2194 if (!svc_register(transp, RUSERSPROG, RUSERSVERS_SHORT,
2195   nuser, IPPROTO_TCP)) {
2196         fprintf(stderr, "can't register RUSER service\en");
2197         exit(1);
2198 }
2199 .DE
2200 Both versions can be handled by the same C procedure:
2201 .ie t .DS
2202 .el .DS L
2203 .ft CW
2204 .vs 11
2205 nuser(rqstp, transp)
2206         struct svc_req *rqstp;
2207         SVCXPRT *transp;
2208 {
2209         unsigned long nusers;
2210         unsigned short nusers2;
2211
2212         switch (rqstp->rq_proc) {
2213         case NULLPROC:
2214                 if (!svc_sendreply(transp, xdr_void, 0)) {
2215                         fprintf(stderr, "can't reply to RPC call\en");
2216             return (1);
2217                 }
2218                 return;
2219         case RUSERSPROC_NUM:
2220 .ft I
2221                 /*
2222          * Code here to compute the number of users
2223          * and assign it to the variable \fInusers\fP
2224                  */
2225 .ft CW
2226                 nusers2 = nusers;
2227                 switch (rqstp->rq_vers) {
2228                 case RUSERSVERS_ORIG:
2229             if (!svc_sendreply(transp, xdr_u_long, 
2230                     &nusers)) {
2231                 fprintf(stderr,"can't reply to RPC call\en");
2232                         }
2233                         break;
2234                 case RUSERSVERS_SHORT:
2235             if (!svc_sendreply(transp, xdr_u_short, 
2236                     &nusers2)) {
2237                 fprintf(stderr,"can't reply to RPC call\en");
2238                         }
2239                         break;
2240                 }
2241         default:
2242                 svcerr_noproc(transp);
2243                 return;
2244         }
2245 }
2246 .vs
2247 .DE
2248 .KS
2249 .NH 2
2250 \&TCP
2251 .IX "TCP"
2252 .LP
2253 Here is an example that is essentially
2254 .I rcp.
2255 The initiator of the RPC
2256 .I snd
2257 call takes its standard input and sends it to the server
2258 .I rcv
2259 which prints it on standard output.
2260 The RPC call uses TCP.
2261 This also illustrates an XDR procedure that behaves differently
2262 on serialization than on deserialization.
2263 .ie t .DS
2264 .el .DS L
2265 .vs 11
2266 .ft I
2267 /*
2268  * The xdr routine:
2269  *              on decode, read from wire, write onto fp
2270  *              on encode, read from fp, write onto wire
2271  */
2272 .ft CW
2273 #include <stdio.h>
2274 #include <rpc/rpc.h>
2275
2276 xdr_rcp(xdrs, fp)
2277         XDR *xdrs;
2278         FILE *fp;
2279 {
2280         unsigned long size;
2281         char buf[BUFSIZ], *p;
2282
2283         if (xdrs->x_op == XDR_FREE)/* nothing to free */
2284                 return 1;
2285         while (1) {
2286                 if (xdrs->x_op == XDR_ENCODE) {
2287                         if ((size = fread(buf, sizeof(char), BUFSIZ,
2288                           fp)) == 0 && ferror(fp)) {
2289                                 fprintf(stderr, "can't fread\en");
2290                                 return (1);
2291                         }
2292                 }
2293                 p = buf;
2294                 if (!xdr_bytes(xdrs, &p, &size, BUFSIZ))
2295                         return 0;
2296                 if (size == 0)
2297                         return 1;
2298                 if (xdrs->x_op == XDR_DECODE) {
2299                         if (fwrite(buf, sizeof(char), size,
2300                           fp) != size) {
2301                                 fprintf(stderr, "can't fwrite\en");
2302                                 return (1);
2303                         }
2304                 }
2305         }
2306 }
2307 .vs
2308 .DE
2309 .KE
2310 .ie t .DS
2311 .el .DS L
2312 .vs 11
2313 .ft I
2314 /*
2315  * The sender routines
2316  */
2317 .ft CW
2318 #include <stdio.h>
2319 #include <netdb.h>
2320 #include <rpc/rpc.h>
2321 #include <sys/socket.h>
2322 #include <sys/time.h>
2323
2324 main(argc, argv)
2325         int argc;
2326         char **argv;
2327 {
2328         int xdr_rcp();
2329         int err;
2330
2331         if (argc < 2) {
2332                 fprintf(stderr, "usage: %s servername\en", argv[0]);
2333                 exit(-1);
2334         }
2335         if ((err = callrpctcp(argv[1], RCPPROG, RCPPROC,
2336           RCPVERS, xdr_rcp, stdin, xdr_void, 0) != 0)) {
2337                 clnt_perrno(err);
2338                 fprintf(stderr, "can't make RPC call\en");
2339                 exit(1);
2340         }
2341         exit(0);
2342 }
2343
2344 callrpctcp(host, prognum, procnum, versnum,
2345            inproc, in, outproc, out)
2346         char *host, *in, *out;
2347         xdrproc_t inproc, outproc;
2348 {
2349         struct sockaddr_in server_addr;
2350         int socket = RPC_ANYSOCK;
2351         enum clnt_stat clnt_stat;
2352         struct hostent *hp;
2353         register CLIENT *client;
2354         struct timeval total_timeout;
2355
2356         if ((hp = gethostbyname(host)) == NULL) {
2357                 fprintf(stderr, "can't get addr for '%s'\en", host);
2358                 return (-1);
2359         }
2360         bcopy(hp->h_addr, (caddr_t)&server_addr.sin_addr,
2361                 hp->h_length);
2362         server_addr.sin_family = AF_INET;
2363         server_addr.sin_port =  0;
2364         if ((client = clnttcp_create(&server_addr, prognum,
2365           versnum, &socket, BUFSIZ, BUFSIZ)) == NULL) {
2366                 perror("rpctcp_create");
2367                 return (-1);
2368         }
2369         total_timeout.tv_sec = 20;
2370         total_timeout.tv_usec = 0;
2371         clnt_stat = clnt_call(client, procnum,
2372                 inproc, in, outproc, out, total_timeout);
2373         clnt_destroy(client);
2374         return (int)clnt_stat;
2375 }
2376 .vs
2377 .DE
2378 .ie t .DS
2379 .el .DS L
2380 .vs 11
2381 .ft I
2382 /*
2383  * The receiving routines
2384  */
2385 .ft CW
2386 #include <stdio.h>
2387 #include <rpc/rpc.h>
2388
2389 main()
2390 {
2391         register SVCXPRT *transp;
2392      int rcp_service(), xdr_rcp(); 
2393
2394         if ((transp = svctcp_create(RPC_ANYSOCK,
2395           BUFSIZ, BUFSIZ)) == NULL) {
2396                 fprintf("svctcp_create: error\en");
2397                 exit(1);
2398         }
2399         pmap_unset(RCPPROG, RCPVERS);
2400         if (!svc_register(transp,
2401           RCPPROG, RCPVERS, rcp_service, IPPROTO_TCP)) {
2402                 fprintf(stderr, "svc_register: error\en");
2403                 exit(1);
2404         }
2405         svc_run();  /* \fInever returns\fP */
2406         fprintf(stderr, "svc_run should never return\en");
2407 }
2408
2409 rcp_service(rqstp, transp)
2410         register struct svc_req *rqstp;
2411         register SVCXPRT *transp;
2412 {
2413         switch (rqstp->rq_proc) {
2414         case NULLPROC:
2415                 if (svc_sendreply(transp, xdr_void, 0) == 0) {
2416                         fprintf(stderr, "err: rcp_service");
2417                         return (1);
2418                 }
2419                 return;
2420         case RCPPROC_FP:
2421                 if (!svc_getargs(transp, xdr_rcp, stdout)) {
2422                         svcerr_decode(transp);
2423                         return;
2424                 }
2425                 if (!svc_sendreply(transp, xdr_void, 0)) {
2426                         fprintf(stderr, "can't reply\en");
2427                         return;
2428                 }
2429                 return (0);
2430         default:
2431                 svcerr_noproc(transp);
2432                 return;
2433         }
2434 }
2435 .vs
2436 .DE
2437 .NH 2
2438 \&Callback Procedures
2439 .IX RPC "callback procedures"
2440 .LP
2441 Occasionally, it is useful to have a server become a client,
2442 and make an RPC call back to the process which is its client.
2443 An example is remote debugging,
2444 where the client is a window system program,
2445 and the server is a debugger running on the remote machine.
2446 Most of the time,
2447 the user clicks a mouse button at the debugging window,
2448 which converts this to a debugger command,
2449 and then makes an RPC call to the server
2450 (where the debugger is actually running),
2451 telling it to execute that command.
2452 However, when the debugger hits a breakpoint, the roles are reversed,
2453 and the debugger wants to make an rpc call to the window program,
2454 so that it can inform the user that a breakpoint has been reached.
2455 .LP
2456 In order to do an RPC callback,
2457 you need a program number to make the RPC call on.
2458 Since this will be a dynamically generated program number,
2459 it should be in the transient range,
2460 .I "0x40000000 - 0x5fffffff" .
2461 The routine
2462 .I gettransient()
2463 returns a valid program number in the transient range,
2464 and registers it with the portmapper.
2465 It only talks to the portmapper running on the same machine as the
2466 .I gettransient()
2467 routine itself.  The call to
2468 .I pmap_set()
2469 is a test and set operation,
2470 in that it indivisibly tests whether a program number
2471 has already been registered,
2472 and if it has not, then reserves it.  On return, the
2473 .I sockp
2474 argument will contain a socket that can be used
2475 as the argument to an
2476 .I svcudp_create()
2477 or
2478 .I svctcp_create()
2479 call.
2480 .ie t .DS
2481 .el .DS L
2482 .ft CW
2483 .vs 11
2484 #include <stdio.h>
2485 #include <rpc/rpc.h>
2486 #include <sys/socket.h>
2487
2488 gettransient(proto, vers, sockp)
2489         int proto, vers, *sockp;
2490 {
2491         static int prognum = 0x40000000;
2492         int s, len, socktype;
2493         struct sockaddr_in addr;
2494
2495         switch(proto) {
2496                 case IPPROTO_UDP:
2497                         socktype = SOCK_DGRAM;
2498                         break;
2499                 case IPPROTO_TCP:
2500                         socktype = SOCK_STREAM;
2501                         break;
2502                 default:
2503                         fprintf(stderr, "unknown protocol type\en");
2504                         return 0;
2505         }
2506         if (*sockp == RPC_ANYSOCK) {
2507                 if ((s = socket(AF_INET, socktype, 0)) < 0) {
2508                         perror("socket");
2509                         return (0);
2510                 }
2511                 *sockp = s;
2512         }
2513         else
2514                 s = *sockp;
2515         addr.sin_addr.s_addr = 0;
2516         addr.sin_family = AF_INET;
2517         addr.sin_port = 0;
2518         len = sizeof(addr);
2519 .ft I
2520         /*
2521          * may be already bound, so don't check for error
2522          */
2523 .ft CW
2524         bind(s, &addr, len);
2525         if (getsockname(s, &addr, &len)< 0) {
2526                 perror("getsockname");
2527                 return (0);
2528         }
2529         while (!pmap_set(prognum++, vers, proto, 
2530                 ntohs(addr.sin_port))) continue;
2531         return (prognum-1);
2532 }
2533 .vs
2534 .DE
2535 .SH
2536 Note:
2537 .I
2538 The call to
2539 .I ntohs() 
2540 is necessary to ensure that the port number in
2541 .I "addr.sin_port" ,
2542 which is in 
2543 .I network 
2544 byte order, is passed in 
2545 .I host
2546 byte order (as
2547 .I pmap_set() 
2548 expects).  See the
2549 .I byteorder(3N) 
2550 man page for more details on the conversion of network
2551 addresses from network to host byte order.
2552 .KS
2553 .LP
2554 The following pair of programs illustrate how to use the
2555 .I gettransient()
2556 routine.
2557 The client makes an RPC call to the server,
2558 passing it a transient program number.
2559 Then the client waits around to receive a callback
2560 from the server at that program number.
2561 The server registers the program
2562 .I EXAMPLEPROG
2563 so that it can receive the RPC call
2564 informing it of the callback program number.
2565 Then at some random time (on receiving an
2566 .I ALRM
2567 signal in this example), it sends a callback RPC call,
2568 using the program number it received earlier.
2569 .ie t .DS
2570 .el .DS L
2571 .vs 11
2572 .ft I
2573 /*
2574  * client
2575  */
2576 .ft CW
2577 #include <stdio.h>
2578 #include <rpc/rpc.h>
2579
2580 int callback();
2581 char hostname[256];
2582
2583 main()
2584 {
2585         int x, ans, s;
2586         SVCXPRT *xprt;
2587
2588         gethostname(hostname, sizeof(hostname));
2589         s = RPC_ANYSOCK;
2590         x = gettransient(IPPROTO_UDP, 1, &s);
2591         fprintf(stderr, "client gets prognum %d\en", x);
2592         if ((xprt = svcudp_create(s)) == NULL) {
2593           fprintf(stderr, "rpc_server: svcudp_create\en");
2594                 exit(1);
2595         }
2596 .ft I
2597         /* protocol is 0 - gettransient does registering
2598          */
2599 .ft CW
2600         (void)svc_register(xprt, x, 1, callback, 0);
2601         ans = callrpc(hostname, EXAMPLEPROG, EXAMPLEVERS,
2602                 EXAMPLEPROC_CALLBACK, xdr_int, &x, xdr_void, 0);
2603         if ((enum clnt_stat) ans != RPC_SUCCESS) {
2604                 fprintf(stderr, "call: ");
2605                 clnt_perrno(ans);
2606                 fprintf(stderr, "\en");
2607         }
2608         svc_run();
2609         fprintf(stderr, "Error: svc_run shouldn't return\en");
2610 }
2611
2612 callback(rqstp, transp)
2613         register struct svc_req *rqstp;
2614         register SVCXPRT *transp;
2615 {
2616         switch (rqstp->rq_proc) {
2617                 case 0:
2618                         if (!svc_sendreply(transp, xdr_void, 0)) {
2619                                 fprintf(stderr, "err: exampleprog\en");
2620                                 return (1);
2621                         }
2622                         return (0);
2623                 case 1:
2624                         if (!svc_getargs(transp, xdr_void, 0)) {
2625                                 svcerr_decode(transp);
2626                                 return (1);
2627                         }
2628                         fprintf(stderr, "client got callback\en");
2629                         if (!svc_sendreply(transp, xdr_void, 0)) {
2630                                 fprintf(stderr, "err: exampleprog");
2631                                 return (1);
2632                         }
2633         }
2634 }
2635 .vs
2636 .DE
2637 .KE
2638 .ie t .DS
2639 .el .DS L
2640 .vs 11
2641 .ft I
2642 /*
2643  * server
2644  */
2645 .ft CW
2646 #include <stdio.h>
2647 #include <rpc/rpc.h>
2648 #include <sys/signal.h>
2649
2650 char *getnewprog();
2651 char hostname[256];
2652 int docallback();
2653 int pnum;               /* \fIprogram number for callback routine\fP */
2654
2655 main()
2656 {
2657         gethostname(hostname, sizeof(hostname));
2658         registerrpc(EXAMPLEPROG, EXAMPLEVERS,
2659           EXAMPLEPROC_CALLBACK, getnewprog, xdr_int, xdr_void);
2660         fprintf(stderr, "server going into svc_run\en");
2661         signal(SIGALRM, docallback);
2662         alarm(10);
2663         svc_run();
2664         fprintf(stderr, "Error: svc_run shouldn't return\en");
2665 }
2666
2667 char *
2668 getnewprog(pnump)
2669         char *pnump;
2670 {
2671         pnum = *(int *)pnump;
2672         return NULL;
2673 }
2674
2675 docallback()
2676 {
2677         int ans;
2678
2679         ans = callrpc(hostname, pnum, 1, 1, xdr_void, 0,
2680                 xdr_void, 0);
2681         if (ans != 0) {
2682                 fprintf(stderr, "server: ");
2683                 clnt_perrno(ans);
2684                 fprintf(stderr, "\en");
2685         }
2686 }
2687 .vs
2688 .DE