Internet2
Site Index | Internet2 Searchlight |
Membership | Communities | Services | Projects | Tools | Events | Newsroom | About
 | Home

APPLICATIONS
>FAQ
>Apps 201
>Publications
>Presentations
>Archive
Initiatives
>Internet2 Commons
>Health Sciences
>Arts & Humanities
>Science & Engineering
ACTIVITIES
>Demos
>Loaner Equipment
>Internet2 Days

Contact us
>via email or call   734.913.4250
>Join Our Mailing List
>Apps Webmaster

Adding an Application

Go back to the Pioneer Overview section.


Adding a new application to Pioneer requires 2 simple steps:

  1. Send your code and contact information to sushila@umich.edu. Your code should be written in a C library, or possibly a C++ library that can interface with C code.
  2. Make sure the code has an interface as specified below.


Your Code/Contact Information
New applications that have a simple client server format (without multiple levels of intermediaries) can be added fairly easily to Pioneer. Currently, I must add some of this information to the Pioneer code, to accept your application as a valid one. Once an authentication framework (which is a parallel project) is in place, we hope to automate this process. In order to incorporate your application into this framework, the following requirements must be met:

  1. Send me a contact person's Full Name, Institution, and email id.
  2. Make sure there is an interface to the code that conforms to the format described in the next section.
  3. Send me a time period (in seconds) after which this program must be killed (as an anti hanging precaution). Admin programs may run forever. (at your own peril, any complaints from unhappy campus folks will be redirected to you).
Expected Code Format
There are 4 pieces necessary to add a new module to pioneer:
  1. A CGI script that will be the front end through which the application is accessed.
  2. A "C" style header file that lists the functions that are necessary for pioneer to work.
  3. A library of routines that contain these functions.
  4. Some documentation on an explanation of the results.

Two types of applications are allowed. One is for the average user, and the other is for admins only. The programs that may be run by all MUST run for a limited, finite amount of time, and must NOT abuse/affect the network significantly. (e.g. flood the network). The admin programs have no constraints at the moment. They are restricted to people with passwords, and the assumption is such people are responsible.


(Alpha version) Code Idiosyncracies
Currently, Pioneer expects that the user programs are of two types. One is the case where a program only runs at one end - e.g. Traceroute, or ping. The other is when they run on two machines, a client end and a server end. In this case, Pioneer expects two SEPERATE libraries to be submitted, each with its default set of parameters (unless they are identical). So for example, "iperf -u -s" and "iperf -c <host> -u" are considered two seperate modules. The assumption is that the average person will use applications with a fixed set of default parameters, and anyone who wants more than that should have admin privileges. This will probably change in the future to be one lib per program. All of the communication between the various servers and modules are SSL encrypted, and new applications must follow that approach in the CGI scripts (clearly seen in the sample code).


Code Format

Header
The header file must contain pointers to functions that do the following:

*(fn_debug)();       /* Something that sets debugging to on or off for this module */
*(fn_get_typestr)(); /* application name e.g. "ping" used to make choices in code */
*(fn_get_logstr)();  /* application name used in logs, e.g. "PING", "IPERFS", "IPERFC" */
*(fn_main)();        /* function to call when a request is made to run this application */
*(fn_parse)();       /* function that parses the output and returns a result string in HTML format */

Library
The calls listed above must be available as a library, and must pass the following parameters:

fn_debug (int flag);
  where: flag = 0 for no debug, 1 for debug

fn_get_typestr ();
  returns: a "char *" with a string that is EXACTLY as it is entered in LDAP

fn_get_logstr ();
  returns: a "char *" with a string that is used in the log files to identify activity in this module

fn_main (client_t *myclient, char *fullcmd, char *cmd_name, int *flag);
  where: myclient is a data structure as defined below that is used to pass parameters gathered on the web page.
  returns: fullcmd (the full path for the command name  e.g. /usr/bin/ping)
  returns: cmd_name (the command name used, should be the same as "fn_get_typestr")
  returns: flag which is 0 if no output is generated, and 1 if a result is generated. E.g. in the case of iperf that we incorporated, results are gathered from the server output, and the client output is discarded.

The data structures for client_t, and the associated web parameters are:

typedef struct web_request {
  int                     type                 /* iperf/litton etc. */
  int                     err                  /* Error if any, 0 otherwise */
  char                    host[50];            /* Host to return response */
  int                  port;                   /* Port to send resp to */
  char                 src[100];               /* Source parameter for cmd */
  char                 dst[100];               /* Dest parameter for cmd */
  char                 req_host[100];          /* Cakebox that made request */
  void                 *params;                /* program specific params */
  char                 *resp_str;              /* Response data string */
} web_request_t;

typedef struct client {
  char                  name[50];               /* Name of this client */
  int                   index;                  /* This client's index */
  int                   valid;                  /* 1/0 if its in use/not */
  int                   socket;                 /* fd */
  int                   die;                    /* 0/1 checked to see if
                                                   thread should exit */
  int                   response_ready;         /* 0/1 checked if a web
                                                   request completed */
  int                   thr_type;               /* whether this is client
                                                   or server */
  pthread_t             thread_id;              /* for cancellation */
  int                   type;                   /* for iperf/litton etc. */
  web_request_t         *webreq;                /* Web based req/resp */
  void                  *params;                /* Parameters based on type */
  pthread_mutex_t       waitlock;               /* for dowait cond */
  pthread_cond_t        dowait;                 /* for starting a new req */
  pthread_mutex_t       modlock;                /* for modifying struct */
  pthread_mutex_t       sleeplock;              /* for dowait cond */
  pthread_cond_t        sleepcond;              /* for sleep */
} client_t;

fn_parse (char * cmd, char *output, int len);
  where: cmd is the name to be used in output or error strings, to identify where its coming from output  is the raw output generated by the command as a result value. len is the number of bytes of output.
  returns: a "char *" result string that is in HTML format, and sent to the web page where the CGI request was submitted.

CGI Script
This is the front end for the application. It should be based on the scripts presented in the example section. Primarily, the source and dest menus will have to come from a central location where all Cakeboxes have registered as being alive. In the future, we will make an LDAP interface available for the program to access directly.

In the short term, send me the script, and I'll make sure the menus for Src and Dst are appropriately filled (or cut and paste from the sample code).

Also note that the message format from the CGI script to the Pioneer central server is:

sprintf "%d %d %d %d %s %s %s %s %s", app_code, msglen, $baseport, hostnamelen, get_webhost(), $src, $dst, $h_name, $params;

  where: app_code is the application code number, which I assign. msglen is ignored for the moment. baseport is the port to which results should returned (as a HTML string). hostnamelen is the length of the web server host. get_webhost() returns the central pioneer server name. src is the source endpoint for the application. dst is the destination endpoint for the application. h_name is the name of the host from which the web request was made to run the application. params is a string that contains any additional parameters specific to the application.


Sample Code
Here are two examples for code that we have already incorporated. The first is "ping" (which runs on only one machine), and the other is "Iperf" (which runs on two machines). The version presented for Iperf is the admin version, which allows all parameters to be set. You will notice that ping runs in a default setting (incorporated in the code) and runs for a max of 20 seconds. Also notice that the CGI script for Iiperf sends two seperate requests (i.e. messages) to the central Pioneer server: one to spawn the Iperf server, and one to spawn the Iperf client.

ping
Average user: CGI code , library code , header file .

Iperf
Admin version: CGI code , server library code , server header file , client library code , client header file .

© 1996 - 2008 Internet2 - All rights reserved | Terms of Use | Privacy | Contact Us
1000 Oakbrook Drive, Suite 300, Ann Arbor MI 48104 | Phone: +1-734-913-4250