SCTP Discussions

Text archives Help


[SCTP-Discussion] Another Update on API definition (sctp.h)


Chronological Thread 
  • From: Andreas Jungmaier <ajung AT exp-math.uni-essen.de>
  • To: discussion AT sctp.de, Schruefer Wolfgang <Wolfgang.Schruefer AT icn.siemens.de>
  • Subject: [SCTP-Discussion] Another Update on API definition (sctp.h)
  • Date: Thu Mar 1 14:43:02 2001
  • List-id: SCTP Discussions <discussion.sctp.de>
  • Organization: University of Essen, Germany

Hi all,

I put my comments to Wolfgangs mail inline. Please
find attached yet another (and the current) version of our API
description (i.e. the file "sctp.h") :
You will note (among others) that I added the function
int sctp_sendUdpData(int sfd, unsigned char* buf, int length,
unsigned char destination[], unsigned short dest_port);

so that data can now be returned to an ULP via UDP. The implementation
now compiles again, and I need to add a few more details (1-2 days),
rewrite the API documentation to reflect the most recent changes
and check a few bug-reports (another 3-4 days), so that we might
have a release some time next week, if all goes well.

Thanks again for all the comments,

Regards, Andreas

> > > 1) Error Codes
> > > These are not very good supported yet.
> > > There should be sctp specific errorcodes (via #define or typedef enum),
> At the moment, I've seen mostly the values -1, 0 and 1 to be returned.
> So at the moment it would be enough to define e.g
> /* specific error return values will be added in the future */
> #define SCTP_SUCCESS 0
> #define SCTP_UNSPECIFIED_ERROR -1
> #define SCTP_SPECIFIC_FUNCTION_ERROR 1
>
> These values are not wrong and there should be no big effort to
> implememement it. And in the future this list can be extended according the
> implementation ...

Okay, now I see what you mean. And I think that is indeed a nice idea.
I will add these, although it will take some time to really put that into
the implementation.

> > > 2) Memory Management
> > >
> > > Goals:
> > > - no memory copy at the interfaces to ULP and IP (already implemented)
> > > - clear memory assignement to one specific layer.
> > > - usage of different memory pools might be necessary e.g. for
> > > protection mechanisms, cache behaviour, interprocess communication ...
> >
> > > Therefore I would divide the memory in 3 parts:
> > > I) ulp_memory used by SCTP and ULP
> > > II) network_memory used by SCTP and IP-layer
> > > III) internal_memory
> [Schruefer Wolfgang]
> OK, I think this ideas are for a later step.
> My intention is not an internal performance-improvement.
> The idea is, that the memory, which is allocated by ULP will be
> released
> again by ULP. (Here we have ULPs that handle data in memory buffers, which
> are not allowed to be freed by SCTP ). Therefore a callbackfunction to
> return the datapointer (probably with context...) is necessary. And the
> same for the IP-adaption-layer (I was told, in the SOLARIS kernal is a
> zero-copy IP-interface).

Ah , I see -- we should probably discuss that when I come to Munich,
where we plan to do a one or two-day workshop on SCTP, our implementation
and some tools, and future developments. That will probably be end of March.


----------------------------------------------------------------------------
E-mail is insecure. It may be read by other people, modified in the
course of transmission, or even faked (see http://www.stopcarnivore.org) !
To protect your E-mail, use encryption programs, such as PGP or GPG,
which can be obtained for free from http://www.gnupg.org !!!!
----------------------------------------------------------------------------
Andreas Jungmaier, Dipl.-Ing.
University of Essen email:
ajung AT exp-math.uni-essen.de
Computer Networking Technology Group Tel. : +49 (0201) 183-7636
----------------------------------------------------------------------------
PGP Public Key and Fingerprint: see http://www.exp-math.uni-essen.de/~ajung
----------------------------------------------------------------------------
/*
 *  $Id: sctp.h,v 1.10 2001/03/01 10:53:11 ajung Exp $
 *
 * SCTP implementation according to RFC 2960.
 * Copyright (C) 2000 by Siemens AG, Munich, Germany.
 *
 * Realized in co-operation between Siemens AG
 * and University of Essen, Institute of Computer Networking Technology.
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 *
 * There are two mailinglists available at www.sctp.de which should be used for
 * any discussion related to this implementation.
 *
 * Contact: discussion AT sctp.de
 *          Michael.Tuexen AT icn.siemens.de
 *          ajung AT exp-math.uni-essen.de
 *
 * Purpose: This header-file defines the API to the SCTP library, and contains
 * 			all functions and structures the library offers to an application.
 *          Further comments on these functions can be found in the implemen-
 *          tation of this interface in the files distribution.c, adaptation.c
 *          and in the accompanying manual (see subdirectory manual)
 * 
 *  function prefix: sctp_         
 */

#ifndef SCTP_H
#define SCTP_H

 
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif


/* the maximum length of an IP address string (IPv4 or IPv6, NULL terminated) */
/* see RFC 1884 (mixed IPv6/Ipv4 addresses)   */
#define SCTP_MAX_IP_LEN           46        /* ==  INET6_ADDRSTRLEN      */
                                
/* reasonable sized SACK, SCTP and IP header + one data chunk should be less than MTU */
/* this is for ethernet..... ;-) */
#define SCTP_MAXIMUM_DATA_LENGTH     1400
/******************** Defines *********************************************************************/
/* the possible 7 states of an association */
#define SCTP_CLOSED                     0
#define SCTP_COOKIE_WAIT                1
#define SCTP_COOKIE_ECHOED              2
#define SCTP_ESTABLISHED                3
#define SCTP_SHUTDOWN_PENDING           4
#define SCTP_SHUTDOWN_RECEIVED          5
#define SCTP_SHUTDOWN_SENT              6
#define SCTP_SHUTDOWNACK_SENT           7

/* Pathstatus, used with networkstatus primitives */
#define SCTP_PATH_OK                    0
#define SCTP_PATH_UNREACHABLE           1

/* for use in  sctp_changeHeartBeat */
#define SCTP_HEARTBEAT_ON               1
#define SCTP_HEARTBEAT_OFF              0

#define SCTP_UNORDERED_DELIVERY         1
#define SCTP_ORDERED_DELIVERY           0

/* boolean, 0==normal bundling, 1==do not bundle message */
#define SCTP_BUNDLING_ENABLED           0
#define SCTP_BUNDLING_DISABLED          1

/* these are also for sctp_send() */
#define SCTP_USE_PRIMARY                -1
#define SCTP_INFINITE_LIFETIME          0


/* Here are some error codes that are returned by some functions         */
/* this list may be enhanced or become more extensive in future releases */
#define SCTP_SUCCESS                    0
#define SCTP_UNSPECIFIED_ERROR          -1
#define SCTP_SPECIFIC_FUNCTION_ERROR    1

/******************** Structure Definitions *******************************************************/

/**
   This struct containes the pointers to ULP callback functions.
   Each SCTP-instance can have its own set of callback functions.
   The callback functions of each SCTP-instance can be found by
   first reading the datastruct of an association from the list of 
   associations. The datastruct of the association contains the name
   of the SCTP instance to which it belongs. With the name of the SCTP-
   instance its datastruct can be read from the list of SCTP-instances.
*/
struct SCTP_ulpCallbacks
{
    /* @{ */
    /**
     * indicates that new data arrived from peer (chapter 10.2.A).
     *  @param 1 associationID
     *  @param 2 streamID
     *  @param 3 length of data
     *  @param 4 protocol ID
     *  @param 5 unordered flag (TRUE==1==unordered, FALSE==0==normal, numbered chunk)
     *  @param 6 pointer to ULP data
     */
    void (*sctp_dataArriveNotif) (unsigned int, unsigned int, unsigned int, unsigned int, unsigned int,   void*);
    /**
     * indicates a send failure (chapter 10.2.B).
     *  @param 1 associationID
     *  @param 2 pointer to data not sent
     *  @param 3 dataLength
     *  @param 4 pointer to context from sendChunk
     *  @param 5 pointer to ULP data
     */
    void (*sctp_sendFailureNotif) (unsigned int, unsigned char *, unsigned int, unsigned int *, void*);
    /**
     * indicates a change of network status (chapter 10.2.C).
     *  @param 1 associationID
     *  @param 2 destinationAddresses
     *  @param 3 newState
     *  @param 4 pointer to ULP data
     */
    void (*sctp_networkStatusChangeNotif) (unsigned int, short, unsigned short, void*);
    /**
     * indicates that a association is established (chapter 10.2.D).
     *  @param 1 associationID
     *  @param 2 status, type of event
     *  @param 3 number of destination addresses
     *  @param 4 number input streamns
     *  @param 5 number output streams
     *  @param 6 pointer to ULP data, usually NULL
     *  @return the callback is to return a pointer, that will be transparently returned with every callback
     */
    void* (*sctp_communicationUpNotif) (unsigned int, unsigned short,
                                   int, unsigned short, unsigned short, void*);
    /**
     * indicates that communication was lost to peer (chapter 10.2.E).
     *  @param 1 associationID
     *  @param 2 status, type of event
     *  @param 3 pointer to ULP data
     */
    void (*sctp_communicationLostNotif) (unsigned int, unsigned short, void*);
    /**
     * indicates that communication had an error. (chapter 10.2.F)
     * Currently not implemented !?
     *  @param 1 associationID
     *  @param 2 status, type of error
     *  @param 3 pointer to ULP data
     */
    void (*sctp_communicationErrorNotif) (unsigned int, unsigned short, void*);
    /**
     * indicates that a RESTART has occurred. (chapter 10.2.G)
     *  @param 1 associationID
     *  @param 2 pointer to ULP data
     */
    void (*sctp_restartNotif) (unsigned int, void*);
    /**
     * indicates that a SHUTDOWN has been COMPLETED. (chapter 10.2.H)
     *  @param 1 associationID
     *  @param 2 pointer to ULP data
     */
    void (*sctp_shutdownCompleteNotif) (unsigned int, void*);
    /* @} */
};



typedef
/**
 * This struct contains some parameters that may be set or
 * got with the sctp_getInstanceParams()/sctp_setInstanceParams()
 * functions. So these may also be specified/retrieved for
 * servers, before an association is established !
 */
struct SCTP_Instance_Params {
    /* @{ */
    /*
     * the initial round trip timeout */
    unsigned int RTO_initial;
    /** the lifetime of a cookie */
    unsigned int validCookieLife;
    /** maximum retransmissions per association */
    unsigned int assocMaxRetransmits;
    /** maximum retransmissions per path */
    unsigned int pathMaxRetransmits;
    /** maximum initial retransmissions */
    unsigned int maxInitRetransmits;
    /** from recvcontrol : my receiver window */
    unsigned int my_rwnd;
    /** recvcontrol: delay for delayed ACK in msecs */
    unsigned int delay;
    /** per instance: for the IP type of service field. */
    unsigned char ip_tos;
    /** currently unused, will limit the number of chunks queued in the send queue later */
    unsigned int max_sendQueue;
    /** currently unused, may limit the number of chunks queued in the receive queue later.
     *  Is this really needed ? The protocol limits the receive queue with
     *  window advertisement of arwnd==0  */
    unsigned int max_recvQueue;
    /* @} */
} SCTP_InstanceParams;


typedef
/**
 *  This struct contains the data to be returned to the ULP with the
 *  sctp_getAssocStatus() function primitive. 
 */
struct SCTP_Association_Status
{
    /* @{ */
    /**   */
    unsigned short association_state;
    /**   */
    unsigned short number_of_addresses;
    /**   */
    unsigned char  primaryDestinationAddress[SCTP_MAX_IP_LEN];
    /**   */
    unsigned short outstreams;
    /**   */
    unsigned short instreams;
    /**   */
    unsigned short primaryAddressIndex;
    /**   */
    unsigned int   currentReceiverWindowSize;
    /**   */
    unsigned int   outstanding_bytes;
    /**   */
    unsigned int   noOfChunksInSendQueue;
    /**   */
    unsigned int   noOfChunksInRetransmissionQueue;
    /**   */
    unsigned int   noOfChunksInReceptionQueue;
    /** the initial round trip timeout */
    unsigned int   RTO_initial;
    /** the lifetime of a cookie */
    unsigned int   validCookieLife;
    /** maximum retransmissions per association */
    unsigned int   assocMaxRetransmits;
    /** maximum retransmissions per path */
    unsigned int   pathMaxRetransmits;
    /** maximum initial retransmissions */
    unsigned int   maxInitRetransmits;
    /** from recvcontrol : my receiver window */
    unsigned int my_rwnd;
    /** recvcontrol: delay for delayed ACK in msecs */
    unsigned int delay;
    /* @} */
} SCTP_AssociationStatus;


typedef
/**
 * this struct contains path specific parameters, so these
 * values can only be retrieved/set, when the association
 * already exists !
 */
struct SCTP_Path_Status
{
    /* @{ */
    /**   */
    unsigned char address_string[SCTP_MAX_IP_LEN];
    /**  SCTP_PATH_ACTIVE  0, SCTP_PATH_INACTIVE   1    */
    short path_state; 
    /** smoothed round trip time in msecs */
    unsigned int srtt;
    /** current rto value in msecs */
    unsigned int rto;
    /** round trip time variation, in msecs */
    unsigned int rttvar;
    /** defines the rate at which heartbeats are sent */
    unsigned int heartbeatIntervall;
    /**  congestion window size (flowcontrol) */
    unsigned int cwnd;
    /**  congestion window size 2 (flowcontrol) */
    unsigned int cwnd2;
    /**  Partial Bytes Acked (flowcontrol) */
    unsigned int partial_bytes_acked;
    /**  Slow Start Threshold (flowcontrol) */
    unsigned int ssthresh;
    /**  from flow control */
    unsigned int outstanding_bytes_per_address;
    /**  Current MTU (flowcontrol) */
    unsigned int mtu;
    /** per path ? per instance ? for the IP type of service field. */
    unsigned char ip_tos;
    /* @} */
}SCTP_PathStatus;


/******************** Function Definitions ********************************************************/

unsigned short sctp_registerInstance(unsigned short localPort,
                                     unsigned short noOfInStreams,
                                     unsigned short noOfOutStreams,
                                     unsigned int   noOfLocalAddresses,
                                     unsigned char  localAddressList[][SCTP_MAX_IP_LEN],
                                     struct SCTP_ulpCallbacks ULPcallbackFunctions);

int sctp_unregisterInstance(unsigned short instance_name);




unsigned int sctp_associate(unsigned short SCTP_InstanceName,
                            unsigned short noOfOutStreams,
                            unsigned char  destinationAddress[],
                            unsigned short destinationPort,
                            void* ulp_data);


int sctp_shutdown(unsigned int associationID);

int sctp_abort(unsigned int associationID);



int sctp_send(unsigned int associationID, 
		      unsigned short streamID,
              unsigned char *buffer, 
			  unsigned int length, 
			  unsigned int protocolId,
              short path_id,  /* -1 for primary path, else address index to be taken */
              unsigned int context,
              unsigned int lifetime, /* optional (zero -> infinite) */
              int unorderedDelivery, /* use constants SCTP_ORDERED_DELIVERY, 
										SCTP_UNORDERED_DELIVERY */
              int dontBundle);       /* use constants SCTP_BUNDLING_ENABLED, 
										SCTP_BUNDLING_DISABLED */


unsigned short sctp_receive(unsigned int   associationID,
                            unsigned short streamID,
                            unsigned char  *buffer,
                            unsigned int   *length);


short sctp_setPrimary(unsigned int associationID, short path_id);
short sctp_getPrimary(unsigned int associationID);

unsigned int sctp_getSrttReport(unsigned int associationID, short path_id);


/*----------------------------------------------------------------------------------------------*/
/*  These are the new function for getting/setting parameters per instance, association or path */
/*----------------------------------------------------------------------------------------------*/
int sctp_setInstanceParams(unsigned short SCTP_InstanceName, SCTP_InstanceParams* params);

int sctp_getInstanceParams(unsigned short SCTP_InstanceName, SCTP_InstanceParams* params);


int sctp_getAssocStatus(unsigned int associationID, SCTP_AssociationStatus* status);

int sctp_setAssocStatus(unsigned int associationID, SCTP_AssociationStatus* new_status);

int sctp_getPathStatus(unsigned int associationID, short path_id, SCTP_PathStatus* status);
int sctp_setPathStatus(unsigned int associationID, short path_id, SCTP_PathStatus *new_status);
/*----------------------------------------------------------------------------------------------*/
/* 
 * These _could_ be build up from the above functions, but for the sake of a
 * complete API according to RFC 2960, section 10, we have the following
 * three functions  here, explicitly 
 */

int sctp_changeHeartBeat(unsigned int associationID,
                         short path_id, int heartbeatON, unsigned int timeIntervall);


int sctp_requestHeartbeat(unsigned int associationID, short path_id);

int sctp_setFailureThreshold(unsigned int associationID,
                             short path_id,
                             unsigned short pathMaxRetransmissions);

/*----------------------------------------------------------------------------------------------*/

int sctp_receiveUnsent(unsigned int associationID, unsigned char *buffer, unsigned int *length,
                        unsigned short *streamID, unsigned short *streamSN,unsigned int* protocolId);

int sctp_receiveUnacked(unsigned int associationID, unsigned char *buffer, unsigned int *length,
                        unsigned short *streamID, unsigned short *streamSN,unsigned int* protocolId);


int sctp_deleteAssociation(unsigned int associationID);


/* Defines the callback function that is called when new data have been received
   (Events POLLIN||POLLPRI )
   Params: 1. socketdescriptor of the socket where the datagramm has been received
           2. pointer to the datagramm data
           3. length of datagramm data
           4. source Address  (as string, may be IPv4 or IPv6 address string, in numerical format)
           5. source port number for UDP sockets, 0 for STDIN file descriptor, 0 for SCTP raw sockets
*/
typedef void (*sctp_socketCallback) (int, unsigned char *, int, unsigned char[] , unsigned short);

/**
 * this function is supposed to open and bind a UDP socket listening on a port
 * to incoming udp pakets on a local interface (a local union sockunion address)
 * @param  me   local address string (IPv4 or IPv6, numerical format), if it receives UDP data
 *              it will trigger callback
 * @param  my_port  port to receive data on (will bind that port !)
 * @param  scf  callback funtion that is called when data has arrived
 * @return new UDP socket file descriptor, or -1 if error ocurred
 */
int sctp_registerUdpCallback(unsigned char me[],
                             unsigned short my_port,
                             sctp_socketCallback scf);


int sctp_sendUdpData(int sfd, unsigned char* buf, int length,
                     unsigned char destination[], unsigned short dest_port);

/**
 * this function is supposed to register a callback function for catching
 * input from the Unix STDIN file descriptor. We expect this to be useful
 * in test programs mainly, so it is provided here for convenience.
 * @param  scf  callback funtion that is called (when return is hit)
 * @return 0, or -1 if error ocurred
 */
int sctp_registerStdinCallback(sctp_socketCallback scf);


/* Defines the callback function that is called when an timer expires.
   Params: 1. ID of timer
           2. pointer to param1
           3. pointer to param2
              param1 and param2 are transparent data from the caller of start_timer,
              that are returned to it when the timer expires.
*/
typedef void (*sctp_timerCallback) (unsigned int, void *, void *);


/**
 *      This function adds a callback that is to be called some time from now. It realizes
 *      the timer (in an ordered list).
 *      @param      milliseconds  action is to be started in milliseconds ms from now
 *      @param      timer_cb      pointer to a function to be executed, when timer expires
 *      @param      param1        pointer to be returned to the caller when timer expires
 *      @param      param2        pointer to be returned to the caller when timer expires
 *      @return     returns an id value, that can be used to cancel a timer
 *      @author     ajung
 */
unsigned int sctp_startTimer(unsigned int milliseconds,
                        sctp_timerCallback timer_cb, void *param1, void *param2);


/**
 *      This function stops a previously started timer.
 *      @param      tid        timer-id of timer to be removed
 *      @return     returns 0 on success, 1 if tid not in the list, -1 on error
 *      @author     ajung
 */
int sctp_stopTimer(unsigned int tid);

/**
 *      Restarts a timer currently running
 *      @param      timer_id   the value returned by set_timer for a certain timer
 *      @param      milliseconds  action is to be started in milliseconds ms from now
 *      @return     new timer id , zero when there is an error (i.e. no timer)
 *      @author     ajung
 */
unsigned int sctp_restartTimer(unsigned int timer_id, unsigned int milliseconds);

/**
 * helper function that returns a 32Bit-value representing current time in msecs
 * Beware, this counter wraps about once per 20 days. Keep that in mind when
 * calculating time differences !
 */
unsigned int sctp_getTime(void);

int sctp_getEvents(void);

int sctp_eventLoop(void);

#endif



Archive powered by MHonArc 2.6.19+.

Top of page