System Requirements
The following software versions are required to run concast.
Compiling & Installing the CSPds
As mentioned earlier, the CSP has been implemented in 2 flavors SCSPd (or sender CSPd) and RCSPd (or receiver CSPd). RCSPd and SCSPd need to run with superuser privileges since they communicate using raw sockets. SCSPd must run on all nodes supporting one or more concast senders. The RCSPd must be run on all nodes supporting a MERGEd or a concast receiver. A typical concast scenario could appear as follows:
The figure shows a simple concast setup consisting of 4 nodes. The user(s) need to start the RCSPd and the SCSPd first. Starting a receiver or sender processes without the presence of the daemon processes will result in errors. A MERGEd for a flow is spawned by the RCSPd when the flow is successfully created/joined on that node. Note, CSP only operates on the control path, and not on the data path. Senders and receivers communicate with the RCSPd/SCSPd on certain occasions. For e.g., when the sender is first started, it informs the SCSPd of its intention to join a concast group. Similarly, when the receiver is first started, it needs to provide details of the mergespec and the concast flow that is being created, to the RCSPd. Application interaction with the CSP is restricted to these occasional events. Our CSP implementation includes a set of libraries that allow the sender and receiver to encode several parameters that are required to establish a concast flow. The section on libraries describes these parameters in detail.
Both senders and receivers need to use the libraries libcspdinterface.a and libmergespec.a. If CSPds are compiled ok, these libraries can be found in Concast_v2/lib. Therefore, the sender and receiver must be compiled by a command that looks something like:
gcc sendOrRecvProgram.c -o executable -LsomeDirectory/Concast_v2/lib -lcspdinterface -lmergespec -IsomeDirectory/Concast_v2/include
The following are the list of calls that are meant to be used by the concast receiver and concast sender. The actual usage shall be explained in some detail in the examples below. Use this list as a reference while implementing the concast sender or receiver.
The following functions can be found in Concast_v2/include/cspd.interface.h.
int ccast_receiver (int sock /*IN*/, u_int raddr /*IN*/, u_int gaddr /*IN*/, u_short port /*IN*/, char *mf_ptr /*IN*/ , int mf_len /*IN*/ );/*
int ccast_sender (int sock /*IN*/, u_int raddr /*IN*/, u_int gaddr /*IN*/);/*
The following functions are implemented by the mspec class ( which can be found in Concast_v2/include/mspec.hh). Mspec class is the structure that completely defines a mergespec. Getting acquainted with the mspec class could prove very useful while writing a new mergespec:
int add_fname (int fileNameLen /*IN*/ , char *fileName /*IN*/);/*
int set_url (int urlLen /*IN*/ , char *url /*IN*/ );/*
int create_mspec_java_http (char **v_mspec /*OUT*/);/*
How to Write the Receiver
The receiver program needs to include the following header files:
#include <linux/concast.h>
#include <cspd.interface.h>
#include <filedet.hh>
#include <mspec.hh>
The first header file specifies data structures shared with the kernel. While installing the kernel source, make sure that the concast.h file is installed properly. The last 3 header files are to be found in Concast_v2/include (assuming that the CSPds are compiled ok).
When the receiver is first started, it must provide the local RCSPd with the mergespec. For a http-based mergespec, the receiver may do the following.
{
mspec myMergeSpec;
//this is the mergespec structure is defined in
<mspec.hh>
const char* classFileName= "concast.apps.sum.Sum";
myMergeSpec.add_fname(strlen(classFileName),classFileName);
const char* classFileName= "concast.apps.sum.SumMergeState";
myMergeSpec.add_fname(strlen(classFileName),classFileName);
//specify the class files that together constitute
the mergespec. Sum.class and
//SumMergeState.class form a part of the concast.apps.sum
package.
//In this case, there are two class files. There
could be several more depending upon the
//specific task performed by the mergespec.
const char* url= "http://peculiar-r.netlab.uky.edu/~swami/McastTest/Java/"
myMergeSpec.set_url(strlen(url),url)
//set the url to the location where the class files
can be found.
char* mergeSpecStrPtr=NULL;
int myMergeSpecStrLen;
myMergeSpecStrLen= myMergeSpec.create_mspec_java_http(mergeSpecStrPtr);
//creates a string representation of the mergespec
that is understood by everyone.
//this function allocates mergeSpecStrPtr
int ccastRecvSock=socket(AF_INET,SOCK_DGRAM,IPPROTO_UDP);
ccast_receiver(ccastRecvSock,bindAddr,groupID,bindPort,
mergeSpecStr, mergeSpecLen);
//bindAddr and bindPort are local address &
port respectively in network order.
//groupID is an integer that uniquely identifies
a concast flow (similar to a multicast group
//address)
//deallocate mergeSpecStrPtr
}
//the receiver can now receive concast packets through the socket ccastRecvSock
using
//the traditional recvfrom() call.
How to Write the Sender
The sender program needs to include the following header files:
#include <linux/concast.h>
#include <cspd.interface.h>
Both of these header files have been described in the receiver section.
When the sender is first started, it must join the concast flow (similar
to a multicast receiver joining a multicast group). A typical concast sender
would do the following.
{
int ccastSendSock=socket(AF_INET,SOCK_DGRAM,IPPROTO_UDP);
ccast_sender(ccastSendSock, (u_int)(toAddr.sin_addr.s_addr)
, groupID);
//toAddr is the receiver address in network order.
//groupID is an integer that uniquely identifies
a concast flow. The receiver would need to
//create a flow with this groupID.
}
//the sender is now ready to receive concast packets through socket
ccastSendSock using
//traditional sendto() call.
Please direct bug reports to {swami,amit,leon,mullins}@netlab.uky.edu