CS716
Advanced Computer Networks
By Dr. Amir Qayyum
1
Lecture No. 33
2
Remote Procedure Call
Outline
Protocol Stack
3
Remote Procedure Call (RPC)
• Central premise: apply the familiar to the unfamiliar
– Programmers understand procedure calls
– Programmers do not understand clientserver interactions
• Idea
– Translate some calls into server request messages
– Wait for reply, return reply value
– Transparent to programmer!
• Transport protocol matching needs of applications
involved in a request/reply message exchange
4
RPC Timeline
Client
Server
Reque
s
Blocked
t
Blocked
Computing
Reply
Blocked
5
Remote Procedure Call (RPC)
• More than just a protocol: popular mechanism for
structuring distributed systems
• More complicated than local procedure calls
– Complex network between calling and called process
– Different architecture and data representation formats
• Complete RPC mechanism has two components
– Dealing with undesirable properties of network
– Packaging arguments into messages and viceversa (stub
compiler)
6
Remote Procedure Call Semantics
write_check (CASE, 13500, “tuition payment”);
• Your machine looks up the bank server
• Asks the server about the checking service
• Receives port number for checking service
• Packages up arguments with type write_check
• Tags package (message) with your identification
• Sends request to checking service on bank server
(potentially as several UDP packets)
• Waits for a reply
7
Remote Procedure Call Semantics
write_check (CASE, 13500, “tuition payment”);
• Bank’s checking service receives request from your home
machine (possibly reassembling UDP packets)
• Verifies your identity (possibly via RPC to an authority)
• Identifies request as a write_check request
• Unpackages arguments, possibly converting data to
another format
• Calls write_check handler function with arguments
8
Remote Procedure Call Semantics
write_check (CASE, 13500, “tuition payment”);
• At bank’s checking service, RPC layer receives return
value from handler function
• Packages up arguments with type write_check_reply
• Tags package (message) with your bank’s identification
and unique ID for previous request
• Sends reply to your machine (potentially as several UDP
packets)
9
Remote Procedure Call Semantics
write_check (CASE, 13500, “tuition payment”);
• Your machine receives reply from bank
(possibly reassembling UDP packets)
• Verifies bank’s identity (possibly via RPC to an
authority)
• Identifies reply as a write_check_reply
• Finds corresponding request
• Unpackages return value, possibly converting data to
another format
• Returns value to caller
10
RPC Components
• Protocol Stack
– BLAST: fragments and reassembles large messages
– CHAN: synchronizes request and reply messages
– SELECT: dispatches request to the correct process
• Stubs
Caller
(client)
Arguments
Callee
(server)
Return
value
Arguments
Client
stub
Request
Reply
Request
Reply
RPC
protocol
RPC
protocol
Return
value
Server
stub
11
Bulk Transfer (BLAST)
• Unlike AAL and IP, tries to
recover from lost fragments
• Strategy
Sender
– Selective retransmission
– AKA partial acknowledgements
• Sender:
– After sending all fragments, set timer
DONE
– If receive SRR, send missing
fragments and reset DONE
– If timer DONE expires, free
fragments
Receiver
Frag
men
t1
Frag
men
t2
Frag
men
t3
Frag
men
t4
Frag
men
t5
Frag
men
t6
SRR
Frag
men
t3
Frag
men
t5
SRR
12
BLAST: Receiver Details
• When 1st fragment arrives, set timer LAST_FRAG
• When all fragments present, reassemble and pass up
• Four exceptional conditions:
– If last fragment arrives but message not complete
• Send SRR and set timer RETRY
– If timer LAST_FRAG expires
• Send SRR and set timer RETRY
– If timer RETRY expires for first or second time
• Send SRR and set timer RETRY
– If timer RETRY expires a third time
• Give up and free partial message
13
BLAST Header Format
•
•
•
•
0
16
MID must protect against wrap around
ProtNum
TYPE = DATA or SRR
MID
Length
NumFrags indicates number of fragments
NumFrags
Type
FragMask distinguishes among fragments
FragMask
– If Type=DATA, identifies this fragment
– If Type=SRR, identifies missing fragments
Data
14
31
Request / Reply (CHAN)
• Guarantees message delivery
• Synchronizes client with server
• Supports atmostonce semantics
Simple case Implicit Acks
Client
Server
Req
ue
Client
st
Req
ue
Server
st 1
y1
Re p l
Req
uest
2
y2
Re p l
ACK
y
Repl
…
ACK
15
CHAN Details
• Lost message (request, reply, or ACK)
– Set RETRANSMIT timer
– Use message id (MID) field to distinguish
• Slow (long running) server
– Client periodically sends “are you alive” probe, or
– Server periodically sends “I’m alive” notice
• Want to support multiple outstanding calls
– Use channel id (CID) field to distinguish
• Machines crash and reboot
– Use boot id (BID) field to distinguish
16
CHAN Header Format
typedef struct {
u_short Type;
u_short CID;
int
MID;
int
BID;
int
Length;
int
ProtNum;
} ChanHdr;
/*
/*
/*
/*
/*
/*
typedef struct {
u_char
type;
u_char
status;
int
retries;
int
timeout;
XkReturn ret_val;
Msg
*request;
Msg
*reply;
Semaphore reply_sem;
int
mid;
int
bid;
} ChanState;
REQ, REP, ACK, PROBE */
unique channel id */
unique message id */
unique boot id */
length of message */
high-level protocol */
/*
/*
/*
/*
/*
/*
/*
/*
/*
/*
CLIENT or SERVER */
BUSY or IDLE */
number of retries */
timeout value */
return value */
request message */
reply message */
client semaphore */
message id */
boot id */
17
Synchronous vs Asynchronous
Protocols
• Asynchronous interface
xPush(Sessn s, Msg *msg)
xPop(Sessn s, Msg *msg, void *hdr)
xDemux(Protl hlp, Sessn s, Msg *msg)
• Synchronous interface
xCall(Sessn s, Msg *req, Msg *rep)
xCallPop(Sessn s, Msg *req, Msg *rep, void *hdr)
xCallDemux(Protl hlp, Sessn s, Msg *req, Msg *rep)
• CHAN is a hybrid protocol
– Synchronous from above: xCall
– Asynchronous from below: xPop/xDemux
18
CHAN (cont)
chanCall(Sessn
ChanState
ChanHdr
char
self, Msg *msg, Msg *rmsg){
*state = (ChanState *)self->state;
*hdr;
*buf;
/* ensure only one transaction per channel */
if ((state->status != IDLE))
return XK_FAILURE;
state->status = BUSY;
/* save copy of req msg and ptr to rep msg*/
msgConstructCopy(&state->request, msg);
state->reply = rmsg;
/* fill out header fields */
hdr = state->hdr_template;
hdr->Length = msgLen(msg);
if (state->mid == MAX_MID)
state->mid = 0;
hdr->MID = ++state->mid;
19
CHAN (cont)
/* attach header to msg and send it */
buf = msgPush(msg, HDR_LEN);
chan_hdr_store(hdr, buf, HDR_LEN);
xPush(xGetDown(self, 0), msg);
/* schedule first timeout event */
state->retries = 1;
state->event = evSchedule(retransmit, self, state->timeout);
/* wait for the reply msg */
semWait(&state->reply_sem);
/* clean up state and return */
flush_msg(state->request);
state->status = IDLE;
return state->ret_val;
}
20
CHAN (cont)
retransmit(Event ev, int *arg){
Sessn
s = (Sessn)arg;
ChanState
*state = (ChanState *)s->state;
Msg
tmp;
/* see if event was cancelled */
if ( evIsCancelled(ev) ) return;
/* unblock client if we've retried 4 times */
if (++state->retries > 4) {
state->ret_val = XK_FAILURE;
semSignal(state->rep_sem);
return;
}
/* retransmit request message */
msgConstructCopy(&tmp, &state->request);
xPush(xGetDown(s, 0), &tmp);
}
/* reschedule event with exponential backoff */
evDetach(state->event);
state->timeout = 2*state->timeout;
state->event = evSchedule(retransmit, s,
state->timeout);
21
CHAN (cont)
chanPop(Sessn self, Sessn lls, Msg *msg, void *inHdr)
{
/* see if this is a CLIENT or SERVER session */
if (self->state->type == SERVER)
return(chanServerPop(self, lls, msg, inHdr));
else
return(chanClientPop(self, lls, msg, inHdr));
}
22
CHAN (cont)
chanClientPop(Sessn self, Sessn lls, Msg *msg, void *inHdr)
{
ChanState
*state = (ChanState *)self->state;
ChanHdr
*hdr = (ChanHdr *)inHdr;
/* verify correctness of msg header */
if (!clnt_msg_ok(state, hdr))
return XK_FAILURE;
/* cancel retransmit timeout event */
evCancel(state->event);
/* if ACK, then schedule PROBE and exit*/
if (hdr->Type == ACK)
{
state->event = evSchedule(probe, s, PROBE);
return XK_SUCCESS;
}
}
/* save reply and signal client */
msgAssign(state->reply, msg);
state->ret_val = XK_SUCCESS;
semSignal(&state->reply_sem);
return XK_SUCCESS;
23
Dispatcher (SELECT)
• Dispatch to appropriate
procedure
• Synchronous counterpart
to UDP
• Address Space for
Procedures
– Flat: unique id for each
possible procedure
– Hierarchical: program +
procedure number
Client
Server
Caller
Callee
xCall
SELECT
xCallDemux
SELECT
xCall
CHAN
xPush
xCallDemux
CHAN
xDemux
xPush
xDemux
24
Client side
Example Code
static XkReturn
selectCall(Sessn self, Msg *req, Msg *rep)
{
SelectState *state=(SelectState *)self->state;
char
*buf;
buf = msgPush(req, HLEN);
select_hdr_store(state->hdr, buf, HLEN);
return xCall(xGetDown(self, 0), req, rep);
}
Server side
static XkReturn
selectCallPop(Sessn s, Sessn lls, Msg *req, Msg *rep, void
*inHdr)
{
return xCallDemux(xGetUp(s), s, req, rep);
}
25