1 / 44

Linux RPC

Linux RPC. Comer Chapter 21 (RPCgen Concept) RFC 1057 – RPC Spec. UNIX Network Programming - Stevens. Sockets API Limitations. Must explicitly account for differences in systems Byte order (big-endian / little-endian) Limited to sending characters (without tricking the system)

dean-holt
Télécharger la présentation

Linux RPC

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Linux RPC Comer Chapter 21 (RPCgen Concept) RFC 1057 – RPC Spec. UNIX Network Programming - Stevens

  2. Sockets API Limitations • Must explicitly account for differences in systems • Byte order (big-endian / little-endian) • Limited to sending characters (without tricking the system) • requires source and destination to implicitly understand the data transformation.

  3. Client / Server Between SystemsOne Solution: • eXternalData Representation (XDR) • Developed by Sun Microsystems • A standard for representing data over the network. • Includes a set of library routines for converting data between local format and XDR format (either direction).

  4. XDR Data Types • int 32 bits • unsigned int 32 bits • bool 32 bits • enum arbitrary • hyper 64 bits • unsigned hyper 64 bits • float 32 bits • double 64 bits • opaque arbitrary • String arbitrary • fixed array arbitrary • counted array arbitrary • structure arbitrary • discriminated union arbitrary. • void 0 • symbolic constant arbitrary • optional data arbitrary

  5. XDR Data Conversion • Objective: • Gather all parameter data into a buffer in XDR format • Procedure: • Create a buffer (xdrmem_create)

  6. XDR Data Conversion • Objective: • Gather all parameter data into a buffer in XDR format • Procedure: • Create a buffer (xdrmem_create) #include <rpc/xdr.h> #define BUFSIZE 4000 ... XDR * xdrs; char buf[BUFSIZE]; xdrmen_create(xdrs, buf, BUFSIZE, XDR_ENCODE);

  7. XDR Data Conversion Routines xdr_bool (xdrs, ptrBool); xdr_bytes (xdrs,str,strSize,maxsize); xdr_char (xdrs, ptrChar); xdr_double(xdrs, prtDouble); xdr_enum(xdrs, ptrInt); xdr_float(xdrs, ptrFloat); xdr_int (xdrs, ptrInt); xdr_long (xdrs, ptrLong); xdr_opaque (xdrs, ptrChar, count); xdr_pointer (xdrs, ptrObj, pbjSize, xdrObj); xdrs_short (xdrs, ptrShort); xdrs_u_char (xdrs, ptrUchar); xdrs_u_int (xdrs, ptrUint); xdrs_u_long (xdrs, ptrUlong); xdrs_u_short (xdrs, ptrUshort); xdr_union (xdrs, ptrDiscrim, ptrUnion, choiceFcn, default); xdr_vector (xdrs, ptrArray, size, elemSize, elemProc); xdr_void ( );

  8. XDR Data Conversion • Add data items in order to the buffer (after converting to XDR format) intmyInt; ... myInt = 260; xdr_int(xdrs, &myInt);

  9. RPC Programming MechanismsONC (Open Network Computing) • XDR library routines for data conversion • XDR library routines for complex data structures • RPC run-time library routines • Program generator tool

  10. RPC Programming Process • Dividing the program into local and remote procedures. RPC Proc A Server Stub Client Stub Proc B

  11. RPC Dispatching(Procedure Location) RPC Proc A2 Dispatcher Proc A1 RPC Server Stub Server Stub Client Stub Client Stub Proc B1 Proc B2

  12. RPC Interface Specification Proc A Server Comm RPC Client Iface Server Iface Client comm Proc B

  13. RPCgen Input and Output • Input • Q.x Interface specification file • Output • Q.h Declarations header file • Q_xdr.cpp XDR procedure calls used to marshal arguments • Q_clnt.cpp Client-side communications stub • Q_svc.cpp Server-side communications stub

  14. RPC Process Flow Client application Client interface Q_clnt.cpp compile Client Q.h rpcgen Q.x Q_xdr.cpp compile Server Q_svc.cpp Remote procedures Server interface

  15. RPC General Build Procedure Develop Interface Develop Client Develop Server

  16. Developing the Interface MyApp.x RPCgen MyApp_clnt.c Client Stub MyApp.h MyApp_svc.c Server Stub MyApp_xdr.c

  17. Developing the Server MyApp.x RPCgen MySrvr.c MyApp_xdr.c MyApp.h C Compiler MyApp_svc.c Server Stub Linker MySrvr.exe

  18. Developing the Client MyApp.x RPCgen MyClnt.c MyApp_xdr.c MyApp.h C Compiler MyApp_clnt.c Client Stub Linker MyClnt.exe

  19. How the Server Prepares for a Connection • (Be certain that Portmap is running) • Create UDP service • Register UDP service with Portmap • Create TCP service • Register TCP service with Portmap • Run service... • Uses select( ) to monitor ports.

  20. Start Portmap Portmap is included in all Linux distributions as a standard server. Under Red Hat / Fedora Open services applet , select portmap and start From command line (as root) /sbin/service portmap start Other distributions should be similar

  21. Server concurrency mode RPC servers can be created in either single threaded or multi-threaded mode. Servers automatically create and (when done) destroy a thread for each incoming connection.

  22. Register the Server Program svc_register(port#, SERV#, VER#, serv_func, proto#); port#: port on which the service is active SERV#: unique number for the service VER#: version for this particular service serv_func: name by which this function is called proto#: IPPROTO_UDP or IPPROTO_TCP

  23. How the Client Establishes a Connection • Make a Remote Procedure Call • Find the Server Host Computer • Find Server Process Port # (through Portmap) • Create a (connection) to the Server Process

  24. How the Client Establishes a Connection clnt_create(server, SERV#, VER#, proto#); remote procedure call... Clnt_destroy(CLIENT);

  25. Example #1 • Temperature Server (Fahrenheit to Centigrade) • Parameters passed as integers • TCP / IP port connection • Source files: • temp.x • Tclient.c • tempServer.c

  26. temp.x program TEMPSERV { version TEMPVERS { intTempConv(int) = 1; //procedure number } = 1; //version number } = 77; //program number

  27. TClient.c #include <stdio.h>, <stdlib.h>, <string.h> #include <rpc/rpc.h> #include "temp.h" #define YES 0 #define NO 1 void main (intargc, char *argv[]) { inttempconvert(int temp, char *srvr); int temperature, nuTemp; intloopFlag; char srvr[25]; CLIENT * cl;

  28. TClient.c (cont) strcpy (srvr, argv[1]); cl = clnt_create(srvr, TEMPSERV, TEMPVERS, "tcp"); loopFlag = YES; while(loopFlag == YES) { printf("Enter temperature in Faherenheit (-999 to quit)"); scanf ("%d", &temperature); ans = tempconv_1(&temperature, cl);

  29. TClient.c (cont) if (ans != NULL) nuTemp = * ans; if (temperature == -999 || temperature == -9999) { loopFlag = NO; printf ("Goodbye...\n"); continue; } printf("That’s %2d in centigrade\n", nuTemp); } clnt_destroy(cl); return 0; }

  30. tempServer.c #include <stdlib.h>, <unistd.h>, <stdio.h> #include <rpc/rpc.h>, "temp.h" static int count; static intnuTemp; int *tempconv_1_svc (int *val, structsvc_req * rqst) { intoldTemp; oldTemp = *val;

  31. tempServer.c if (oldTemp == -9999) { printf("We're shutting down...\n"); exit (0); } printf("We got a temperature of %d, ", oldTemp); count++; nuTemp = (int)((5*(oldTemp -32))/ 9.0); printf("and we returned a value of %d\n", nuTemp); sleep(1); return (&nuTemp); }

  32. Files created with rpcgen • Input: • temp.x • Output • temp.h • temp_xdr.c (NULL file) • temp_clnt.c • temp_svc.c

  33. temp.h #include <rpc/rpc.h> #ifdef __cplusplus extern "C" { #endif #define TEMPSERV 77 #define TEMPVERS 1 #if defined(__STDC__) || defined(__cplusplus) #define TempConv 1 extern int * tempconv_1(int *, CLIENT *); extern int * tempconv_1_svc(int *, structsvc_req *); extern int tempserv_1_freeresult (SVCXPRT *, xdrproc_t, caddr_t); #ifdef __cplusplus} #endif #endif /* !_TEMP_H_RPCGEN */

  34. temp_xdr.c #include <rpc/rpc.h> #include "temp.h"

  35. temp_clnt.c #include <memory.h> /* for memset */ #include "temp.h“ /* Default timeout can be changed using clnt_control() */ static structtimeval TIMEOUT = { 25, 0 }; int *tempconv_1(int *argp, CLIENT *clnt){ static intclnt_res; memset((char *)&clnt_res, 0, sizeof(clnt_res));

  36. temp_clnt.c (cont) if (clnt_call (clnt, TempConv, (xdrproc_t) xdr_int, (caddr_t) argp, (xdrproc_t) xdr_int, (caddr_t) &clnt_res, TIMEOUT) != RPC_SUCCESS) { return (NULL); } return (&clnt_res);}

  37. temp_svc.c #include "temp.h“ #include <stdio.h> #include <stdlib.h> #include <rpc/pmap_clnt.h> #include <string.h> #include <memory.h> #include <sys/socket.h> #include <netinet/in.h> #ifndef SIG_PF #define SIG_PF void(*)(int) #endif

  38. temp_svc.c (cont) static void tempserv_1(structsvc_req *rqstp, register SVCXPRT *transp){ union { int tempconv_1_arg; } argument; char *result; xdrproc_t _xdr_argument, _xdr_result; char *(*local)(char *, structsvc_req *); switch (rqstp->rq_proc) { case NULLPROC: (void) svc_sendreply (transp, (xdrproc_t) xdr_void, (char *)NULL); return; case TempConv: _xdr_argument = (xdrproc_t) xdr_int; _xdr_result = (xdrproc_t) xdr_int; local = (char *(*)(char *, structsvc_req *)) tempconv_1_svc; break; default: svcerr_noproc (transp); return; }

  39. temp_svc.c (cont) memset ((char *)&argument, 0, sizeof (argument)); if (!svc_getargs (transp, (xdrproc_t) _xdr_argument, (caddr_t) &argument)) { svcerr_decode (transp); return; } result = (*local)((char *)&argument, rqstp); if (result != NULL && !svc_sendreply(transp, (xdrproc_t) _xdr_result, result)) { svcerr_systemerr (transp); } if (!svc_freeargs (transp, (xdrproc_t) _xdr_argument, (caddr_t) &argument)) { fprintf (stderr, "%s", "unable to free arguments"); exit (1); } return; }

  40. temp_svc.c (cont) int main (intargc, char **argv){ register SVCXPRT *transp; pmap_unset (TEMPSERV, TEMPVERS); transp = svcudp_create(RPC_ANYSOCK); if (transp == NULL) { fprintf (stderr, "%s", "can’t create udp service."); exit(1); } if (!svc_register(transp, TEMPSERV, TEMPVERS, tempserv_1, IPPROTO_UDP)) { fprintf (stderr, "%s", "unable to register (TEMPSERV, TEMPVERS, udp)."); exit(1); }

  41. temp_svc.c (cont) transp = svctcp_create(RPC_ANYSOCK, 0, 0); if (transp == NULL) { fprintf (stderr, "%s", "cannot create tcp service."); exit(1); } if (!svc_register(transp, TEMPSERV, TEMPVERS, tempserv_1, IPPROTO_TCP)) { fprintf (stderr, "%s", "unable to register (TEMPSERV, TEMPVERS, tcp)."); exit(1); } svc_run (); fprintf (stderr, "%s", "svc_run returned"); exit (1); /* NOTREACHED */}

  42. Sample Client Output D:\data\RPC\onrpc_temp\client\Debug>client localhost Enter the temperature in Faherenheit (-999 to quit)32 That would be 0 in centigrade Enter the temperature in Faherenheit (-999 to quit)100 That would be 37 in centigrade Enter the temperature in Faherenheit (-999 to quit)212 That would be 100 in centigrade Enter the temperature in Faherenheit (-999 to quit)-9999 Goodbye... D:\data\RPC\onrpc_temp\client\Debug>

  43. Sample Server Output D:\data\RPC\examples\onrpc_temp\server\Debug>server We got a temperature of 32, and we returned a value of 0 We got a temperature of 100, and we returned a value of 37 We got a temperature of 212, and we returned a value of 100 We're shutting down... D:\data\RPC\examples\onrpc_temp\server\Debug>

  44. Summary • Linux RPC Implementation models SUN ONCRPC functionality • RPC specific programming limited to linking original applications code with rpcgen interface code.

More Related