linux rpc
DESCRIPTION
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) - PowerPoint PPT PresentationTRANSCRIPT
Linux RPC
Comer Chapter 21(RPCgen Concept)
RFC 1057 – RPC Spec.UNIX Network Programming - Stevens
1
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.
2
Client / Server Between SystemsOne Solution:
• eXternal Data 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).
3
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
4
XDR Data Conversion
• Objective:– Gather all parameter data into a buffer in XDR
format
• Procedure:– Create a buffer (xdrmem_create)
5
XDR Data Conversion
• Objective:– Gather all parameter data into a buffer in XDR
format
• Procedure:– Create a buffer (xdrmem_create)
6
#include <rpc/xdr.h>#define BUFSIZE 4000
...XDR * xdrs;char buf[BUFSIZE];xdrmen_create(xdrs, buf, BUFSIZE, XDR_ENCODE);
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 ( );
7
XDR Data Conversion
– Add data items in order to the buffer (after converting to XDR format)
8
int myInt;...myInt = 260;xdr_int(xdrs, &myInt);
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
9
RPC Programming Process
• Dividing the program into local and remote procedures.
10
Proc A
Client Stub
Server Stub
Proc B
RPC
RPC Dispatching(Procedure Location)
11
Proc A1
Client Stub
Server Stub
Proc B1
Proc A2
Client StubProc B2
Server Stub
Dispatcher
RPC
RPC
RPC Interface Specification
12
Proc A
Client comm
Server Iface
Proc B
Server Comm
Client Iface
RPC
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
13
RPC Process Flow
14
Q.x rpcgen
Q_clnt.cpp
Q.h
Q_xdr.cpp
Q_svc.cpp
Clientapplication
Clientinterface
Serverinterface
Remoteprocedures
Server
Clientcompile
compile
RPC General Build Procedure
15
Develop Interface
Develop Client Develop Server
Developing the Interface
16
MyApp.x
RPCgen
MyApp_clnt.cClient Stub
MyApp_svc.cServer Stub
MyApp.h
MyApp_xdr.c
Developing the Server
17
MyApp.x
RPCgen
MyApp_svc.cServer Stub
MyApp.hMySrvr.c MyApp_xdr.c
C Compiler
Linker
MySrvr.exe
Developing the Client
18
MyApp.x
RPCgen
MyApp_clnt.cClient Stub
MyApp.hMyClnt.c
C Compiler
Linker
MyClnt.exe
MyApp_xdr.c
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.
19
Start Portmap
Portmap is included in all Linux distributions as a standard server.
Under Red Hat / Fedora Open services applet , select portmap and startFrom command line (as root)
/sbin/service portmap start
Other distributions should be similar
20
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.
21
Register the Server Program
svc_register(port#, SERV#, VER#, serv_func, proto#);
port#: port on which the service is activeSERV#: unique number for the serviceVER#: version for this particular serviceserv_func: name by which this function is calledproto#: IPPROTO_UDP or IPPROTO_TCP
22
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
23
How the Client Establishes a Connection
clnt_create(server, SERV#, VER#, proto#);
remote procedure call...
Clnt_destroy(CLIENT);
24
Example #1
• Temperature Server (Fahrenheit to Centigrade)– Parameters passed as integers– TCP / IP port connection
• Source files:– temp.x– Tclient.c– tempServer.c
25
temp.x
program TEMPSERV {version TEMPVERS {
int TempConv(int) = 1; //procedure number} = 1; //version number
} = 77; //program number
26
TClient.c#include <stdio.h>, <stdlib.h>, <string.h>#include <rpc/rpc.h>#include "temp.h"#define YES 0#define NO 1
void main (int argc, char *argv[]){
int tempconvert(int temp, char *srvr);int temperature, nuTemp;int loopFlag;char srvr[25];CLIENT * cl;
27
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);
28
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;
}
29
tempServer.c
#include <stdlib.h>, <unistd.h>, <stdio.h>#include <rpc/rpc.h>, "temp.h"
static int count;static int nuTemp;
int *tempconv_1_svc (int *val, struct svc_req * rqst)
{int oldTemp;oldTemp = *val;
30
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);
}
31
Files created with rpcgen
• Input:– temp.x
• Output– temp.h– temp_xdr.c (NULL file)– temp_clnt.c– temp_svc.c
32
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 *, struct svc_req *);
extern int tempserv_1_freeresult (SVCXPRT *, xdrproc_t, caddr_t);
#ifdef __cplusplus}
#endif
#endif /* !_TEMP_H_RPCGEN */
33
temp_xdr.c
#include <rpc/rpc.h>
#include "temp.h"
34
temp_clnt.c#include <memory.h> /* for memset */#include "temp.h“/* Default timeout can be changed using
clnt_control() */
static struct timeval TIMEOUT = { 25, 0 };
int *tempconv_1(int *argp, CLIENT *clnt){static int clnt_res;memset((char *)&clnt_res, 0, sizeof(clnt_res));
35
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);}
36
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
37
temp_svc.c (cont)static void tempserv_1(struct svc_req *rqstp, register SVCXPRT *transp){
union {
int tempconv_1_arg;
} argument;
char *result;
xdrproc_t _xdr_argument, _xdr_result;
char *(*local)(char *, struct svc_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 *, struct svc_req *)) tempconv_1_svc;break;
default:
svcerr_noproc (transp);
return; } 38
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;
}
39
temp_svc.c (cont)int main (int argc, 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);
}
40
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 */}
41
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>
42
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>
43
Summary
• Linux RPC Implementation models SUN ONCRPC functionality
• RPC specific programming limited to linking original applications code with rpcgen interface code.
44