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