Sei sulla pagina 1di 36

Week 7: A case study:

Design and Implementation of


TFTP

Module 6 and Chapter 12 of UNP1e


Objectives
• how network protocols are defined by finite state
machines
• how to implement network finite state machine
• how to make the overall modular design for
network applications
• how to design
– network support modules,
– user interface modules and
– file system modules
Interactive applications
• Interactive programs are constantly interacting
with the outside through communication to
provide services and they normally run as long as
the services are need.
• The centre is an infinite loop with the loop body to
receive the communication events and act on them
according to a protocol.
for (; ; ) {
receive an event;
process the event with corresponding action;
}
Interactive Network application vs. FSM
• When no event occurs, the program blocks on the
receiving statement until the next event occurs.
• The action to process an event depends on the event
itself and the current state of the application.
• There can be many states in which the application
can be used. A state is defined by the value of a
collection of variables of the program and used to
represent a certain history of the execution.
• Interactive network applications can be best
described through an abstract machine model called
Finite State Machine (FSM).
Finite States Machines
• What is a FSM
– A FSM is a 6-tuple: FSM =<S, E, A, f, g, q0>
• where S, E and A are the finite sets of states, events and
actions, respectively, and q0 is the initial state of the FSM,
• f: S × E -> S is the transfer function to determine the
next state given an event in E and the current state,
• g: S × E -> A is the output function which defines the action
to take given an event in E and the current state.
• FSM representations
– A FSM can be defined by a state diagram or
– A FSM can be defined by a set of tables for the
transfer function f and output function g.
FSM state diagram
S = {A, B, C}, q0 = A, E ={e1, e2} and A = {a1, a2, a3}
q0

A e1 e2 A
S
e1/a2 e2/a1
A B,a2 C,a1
B C,a3 A,a2 e2/a2 e1/a1
C A,a1 B,a3
e1/a3
B C
f(s,e),g(s,e)
e2/a3
Network Application protocols
• One of the key steps to develop a network application is to
identify three sets E, S, and A.
– The event set E includes all events from both the user and network
• Typical network events are receiving a certain type of packet from a
socket
• user event arise when the user of the program(most client program) acts
on the user interface.
– The actions set A usually includes
• sending some types of packet to a socket
• issuing system calls on the file system
• delivering outputs to the user interface.
– The state set S should include all states which may last non-zero times,
• usually representing conditions after certain network packets or user
command are received.
Developing network applications
• Application specification defined in the form RFC includes
function f and g, which are the core of the FSM of a
program.
– A network application normally requires two different programs
for the client and server, each of which is a FSM.
– Two FSMs define the formal protocol of the application.
• The first step is to translate the application specification
into a network protocol in the form of two FSMs for the
client and server.
– identify the content of each element in the 6-tuple <S, E, A,
f, g, q0> of each FSM.
TFTP protocol
• TFTP is a simplified version of File Transfer Protocol
(FTP).
– It takes away many features of FTP such as directory
listing and authentication from FTP, but concentrates on
the file transfer only.
• The file transfer is implemented using UDP, it is a
complicated process, because
– we have to ensure the every byte of the file to be delivered
to the destination
– a separate formal protocol in the form of FSMs for each
client and server.
– both the client and the server can be the sender and
receiver.
Design to implement TFTP
• User Interface design:- This is used by the client to interact
with user. User command put or get starts a file transfer.
• File Transfer design:- This component requires two FSMs for
the client and the server as the formal protocol. It concentrates on the
network packets between the server and the receiver for the file
transfer. The events considered are only the receiving of the network
packets.
• File system module design:- This component is responsible
for accessing the file systems of the sender and receiver. The sender
and receiver have to read and write corresponding files, respectively.
These operations are part of the actions in the FSMs
• Network Module design:- This is to hide the details of the
network operations and provides a higher-level interface to the FSMs
for the actions which needs network interactions.
Overall design for TFTP

user interface File transfer Protocol

FSM FSM
user client server

FS interface FS interface
network
interface

File system Network File system


Network packet design
• To identify the event sets of the FSMs, we need to design
the format of the possible network packets between the
client and the server. The following five formats are
necessary.
opcode string EOS string EOS
read request (RRQ) 01 filename 0 mode 0
2 bytes n bytes 1 byte n bytes 1 byte
opcode string EOS string EOS
write request (WRQ) 02 filename 0 mode 0
2 bytes n bytes 1 byte n bytes 1 byte
opcode
data 03 block# data
2 bytes 2 bytes n bytes
opcode
acknowledgment
(ACK)
04 block#
2 bytes 2 bytes
opcode string EOS
error 05 errcode errstring 0
2 bytes 2 bytes n bytes 1 byte
FSM for the server
• The initial state of the server is STANDBY. Its
event set E includes the receiving of the five types
of packets from the client.

standby

RRQ/Data(1) WRQ/Ack(0)

Data_Sent Ack_Sent

ACK(n)/Data(n+1) Data(n)/AcK(n)
FSM for the client
• State INIT is a state of the user interface, does not
belong to the state set of FSM client.

INIT
(R)/RRQ (W)/WRQ

RRQ_Sent WRQ_Sent
ERR/RQERR
Data(1)/ACK(1) ACK(0)/DATA(1)
EXIT
Ack_Sent
Data_Sent

Data(n)/ACK(n) ACK(n)/DATA(n+1)

• (R) and (W) are not part of the event set of the FSM. They
are merely the user interface operations to trigger the FSM
to send RRQ and WRQ to the server.
Reliability in UDP implementation
• Using UDP to implement TFTP could result in the
data lose. To add reliability to the transmission,
the technology of time-out and retransmission
need to be used.
– a time-out is setup when a data packet Data(k) or an
acknowledgement ACK(j) is sent
– if the corresponding ACK(k) or Data(j+1) is not
received within the time-out, the same Data(k) or
ACK(j) is retransmitted.
• The time-out and retransmission can be handled at
the code level, they need not to appear in the FSM.
Sorcerer’s apprentice syndrome
• if ACK(n) is received after DATA(n) is retransmitted
due to the time-out, there will be double DATA(k)
for all k>=n+1 and double ACK(j) for all j>=n+1
even though there are not time-outs. This problem is
called Sorcerer’s apprentice syndrome
• The problem with this is double traffic generated if
we follow strictly the mechanism of timeout and
retransmission.
• A simple fix of the problem is to disable sending
Data(n+1) after receiving ACK(n) if this ACK(n) is a
duplicated one.
Sorcerer’s apprentice syndrome
send DATA(n)
receive DATA(n)
(timeout) send ACK(n)
retransmit DATA(n)
receive ACK(n)
send DATA(n+1) receive DATA(n) (dup)
send ACK(n) (dup)
receive ACK(n) (dup)
receive DATA(n+1)
send DATA(n+1) (dup)
send ACK(n+1)
receive ACK(n+1)
send DATA(n+2) receive DATA(n+1) (dup)
send ACK(n+1) (dup)

receive ACK(n+1) (dup) receive DATA(n+2) (dup)


send DATA(n+2) (dup) send ACK(n+2) (dup)
Basic techniques for implementing FSM
• Construct a table of function pointers, fsm_ptr, with
– the rows representing the states of the FSM and
– the columns representing the events of the FSM.
– ie. a 2D array of function pointers
• To start the FSM, enter a infinite loop as follows:
for (; ;) {
event = receive the input event;
call function(*fsm_ptr[state][event])(ags…);
}

• The function called for the action should


– call some functions to complete the action
– change variable state to reflect the transition to the next state.
• For the undefined pairs of state-event, a special function can
be used to indicate the invalidness of reaching this point.
FSM: Infinite Loop engine
• The code dealing with time-out and
retransmission have been taken.
int fsm_loop(int opcode)
{ op_sent = opcode;
for (;;) {
if ((nbytes = net_recv(recvbuf, MAXBUFF)) < 0 ) {
net_send(sendbuff, sendlen);
continue;
}
op_recv = ldshort(recvbuff);
if ((*fsm_ptr[op_sent][op_recv])(recvbuff+2,nbytes-2) < 0) {
}
}
}
FSM: Functions for actions and State
Transitions
• All of them have two arguments:
– a char * pointer to the receiver buffer just past the
opcode
– an int variable for the number of bytes of the
remaining data in the buffer.
Function used by invoked when
recv_ACK() client and server an ACK(n) received in valid state

recv_DATA() client and server a DATA(n) received in valid state

recv_RQERR() client only a ERROR for RRQ or WRQ is received

recv_RRQ() server only a RRQ received in state STANDBY

recv_WRQ() server only a WRQ received in state STANDBY


FSM: Functions for actions and State
Transitions
• When the client receives the read or write request
from the user also need to send RRQ or WRQ
packets to the server.
Function used by invoked when
send_ACK() recv_DATA() send ACK to the DATA received

send_DATA() recv_ACK() send next DATA after receiving ACK

send_RQ() the User send RRQ or WRQ to the server


Interface
User interface design
• main program of client
• commands dispatch
• command format and parser
• command processing
Commands dispatch
• The argument of docmd() is a character string for
the command to execute.
– docmd() uses it to search a command dispatch table in
array commands[]
typedef struct Cmds {
char *cmd_name,
int (*cmd_func)();
} Cmds;
Cmds commands[] = {
“?”, cmd_help,
“ascii”, cmd_ascii,
…………. ….
“connect”, cmd_connect,
…………. ….
“verbose”, cmd_verbose
}
Commands processing
• The 13 command processing functions cmd_xxx().
– The most interesting ones are cmd_get() and cmd_put() for
file transfer between the client and server.
void cmd_get(){
if (gettpken(remfname) == NULL)
err_cmd(“”);

do_get(remfname, locfname);
}
void do_get() {
if ( file_open() == NULL) {
}
if (net_open(hostname, TFTP_SERVICE, port) < 0)
return;
t_start();
send_QR(OP_RPQ, remfname, modetype);
fsm_loop(OP_RRQ);
t_stop();
net_close();
file_close();
}
Network support design
• Since the client and the server is not symmetric, we need
two sets of network operations functions for them
• For the client
Function Purpose
net_open() create a socket to communicate with the server
net_close() close the communication socket
net_send() send a network packet to the server
net_recv() receive a network packet from the server
• For the server
Function Purpose
net_initi() initialize the network connection for the server
net_open() receive the first packet from a client and fork a child
net_close() close the communication socket
net_send() send a network packet to the client
net_recv() receive a network packet from the client
File system module design
• This module would include many file system
functions at a level higher than the file system
calls.
• These functions themselves are implemented by
using the file systems call such as read() and write
in Unix OS.
• The file system module is system-dependent, the
rest of application is system-independent.
– This makes the port of the same application from one
OS to another easy.
Four functions for file system module

They are used by both the client and server.

Functions purpose
File_open() Open a local file for reading
and writing
File_close() Close an opened file
File_read() Read data from file into buffer

File_write Write data from buffer to file


Reliability design
• UDP implementation must use the
technique of timeout and retransmission to
ensure the reliability required.
• The client and server expect to receive the
SIGALRM signal generated by the timeout.
• The Jacobson/Karel model for timeout and
retransmission will be used (details can be
found in Module 8).
Reliability module design
• In the beginning of each iteration of for(;;)
loop, statements
Signal(SIGALRM, func_timeout);
Tout_flag = 0;
Alarm(rtt_start(&rttinfo));
• Set the SIGALRM signal handler to be
func_timeout() which set tout_flag, reset
tout_flag and set the timeout clock with
timeout value returned by rtt_start().
Jacobsob/Karel model
• rtt_xxx() functions for timeout and
retransmission.
Rtt_init() Initialize the values in argument rttinfo

Rtt_newpack() Initialize retransmit counter to 0

Rtt_start() Calculate and return the timeout value

Rtt_stop() Calculate RTT and update the values in


rttinfo
Rtt_timeout() Increment retransmit counter, return -1 if it
exceeds limit
UDP Implementation
• The TFTP program consists of
– a client program
– a server program
• The files for UPD version
Filename Client Server Notes
cmd.c yes only client processes user commands
cmdgetput.c yes only client processes user commands
cmdsubr.c yes only client processes user commands
file.c yes yes client and server file I/O
fsm.c yes yes finite state machine to drive system
initvars.c yes yes initialize all global variables
maincli.c yes client main program
mainserv.c yes server main program
netudp.c yes yes client and server network I/O - UDP
sendrecv.c yes yes client and server TFTP functions
netudp.c file
• This file defines five functions that are used
by both client and server
function Notes
net_init initialize a network connection (server only)
net_open open a network connection
net_close close a network connection
net_send send a packet
net_recv receive a packet

• By using these functions in the TFTP


functions, we can easily replace them with
functions that use another protocol.
maincli.c file
void main(int argc, char **argv)
{
while () {
for () {
// process options
// turn on some flags
}
do {
// open each given files
// mainloop: process a given file
}
} // read more
}
Starting the TFTP server
• The TFTP server can be started either by
– inetd superserver or
– independently.
• The server is started by inetd
– When started by the inetd daemon, the wait mode is
specified.
– Once the TFTP server has read the datagram from the
client on its well-known port, we want the TFTP server
to fork with the parent existing.
– This allows the inetd daemon to start another read on
the server’s well-known port to process the next request
from some other client.
TFTP server invoked by inetd
select on the well-known port recvfrom on socket Create new socket
when a datagram arrives Spwan child process bind any local address
invoke TFTP server then exit process client’s request
inetd fork TFTP fork TFTP
daemon exec server(parent) server(child)

initial send to well-known port 1st response from server

TFTP
client
Starting the TFTP server
• The server is started independently of the inetd,
– The server must provide the concurrency.
– The TFTP parent must start another recvfrom after a
child process is spawned
recvfrom on well-known socket
Blocks until client request arrives Create new socket
Spwan child process, Initiate another bind any local address
recvfrom on well-known socket process client’s request

TFTP fork TFTP


server(parent) server(child)

initial send to well-known port 1st response from server

TFTP
client

Potrebbero piacerti anche