- From: Michael Tüxen <Michael.Tuexen AT micmac.franken.de>
- To: <discussion AT sctp.de>
- Cc: Andreas Jungmaier <ajung AT exp-math.uni-essen.de>
- Subject: [SCTP-Discussion] API, second version
- Date: Tue Feb 27 21:13:02 2001
- List-id: SCTP Discussions <discussion.sctp.de>
Dear all,
please find attached the second version of the API for the 1.0 release of
the sctp
implementation. We have included most of the comments. Thanks to
erveryone supporting
us!
I have some comments in sctp.h which suggests or documents some changes.
These are mainly for Andreas (so Andreas, please read them and accept or
discard them) but should also be interesting for others.
Please send us also comments on this second version!
Happy SCTPing
Michael
--
e-mail:
Michael.Tuexen AT micmac.franken.de/*
* $Id: discard_server.c,v 1.2 2001/02/15 17:45:07 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 http://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
*
* discard_server.c - main program module
*
* This is a 'minimal' implementation of a server. It discards all packets
* it is receiving. Only a verbose mode is supported.
*/
#include "sctp.h"
#include
#include
#define DISCARD_PORT 9
#define MAXIMUM_NUMBER_OF_LOCAL_ADDRESSES 10
#define MAXIMUM_PAYLOAD_LENGTH 1500
#define MAXIMUM_NUMBER_OF_IN_STREAMS 17
#define MAXIMUM_NUMBER_OF_OUT_STREAMS 1
static unsigned char localAddressList[MAXIMUM_NUMBER_OF_LOCAL_ADDRESSES][MAX_IP_LEN];
static unsigned short noOfLocalAddresses = 0;
static int verbose = 0;
static int vverbose = 0;
void getArgs(int argc, char **argv)
{
int c;
extern char *optarg;
extern int optind;
while ((c = getopt(argc, argv, "s:vV")) != -1)
{
switch (c) {
case 's':
if ((noOfLocalAddresses < MAXIMUM_NUMBER_OF_LOCAL_ADDRESSES) &&
(strlen(optarg) < MAX_IP_LEN )) {
strcpy(localAddressList[noOfLocalAddresses], optarg);
noOfLocalAddresses++;
};
break;
case 'v':
verbose = 1;
break;
case 'V':
verbose = 1;
vverbose = 1;
break;
}
}
}
void dataArriveNotif(unsigned int assoc_id, unsigned int stream_id, unsigned int len,
unsigned int protoID, unsigned int unordered, void* dummy)
{
unsigned char chunk[MAXIMUM_PAYLOAD_LENGTH];
unsigned int length;
if (vverbose) {
fprintf(stdout, "%-8u: Data arrived (%u bytes on stream %u, %s)\n",
assoc_id, len, stream_id, (unordered==SCTP_ORDERED_DELIVERY)?"ordered":"unordered");
fflush(stdout);
};
/* read and discard it */
length = MAXIMUM_PAYLOAD_LENGTH;
sctp_receive(assoc_id, stream_id, chunk, &length);
}
void sentFailureNotif(unsigned int assoc_id,
unsigned char *unsent_data, unsigned int data_len, unsigned int *context, void* dummy)
{
if (verbose) {
fprintf(stdout, "%-8u: Sent failure\n", assoc_id);
fflush(stdout);
}
}
void networkStatusChangeNotif(unsigned int assoc_id, short dest_add, unsigned short new_state, void* dummy)
{
if (verbose) {
fprintf(stdout, "%-8u: Network status change: path %u is now %s\n",
assoc_id, dest_add, ((new_state == SCTP_PATH_OK) ? "ACTIVE" : "INACTIVE"));
fflush(stdout);
}
}
void* communicationUpNotif(unsigned int assoc_id, unsigned short status,
int noOfDestinations,
unsigned short noOfInStreams, unsigned short noOfOutStreams, void* dummy)
{
if (verbose) {
fprintf(stdout, "%-8u: Communication up (%u paths)\n", assoc_id, noOfDestinations);
fflush(stdout);
}
/* use no upper layer identifier */
return NULL;
}
void communicationLostNotif(unsigned int assoc_id, unsigned short status, void* dummy)
{
if (verbose) {
fprintf(stdout, "%-8u: Communication lost (status %u)\n", assoc_id, status);
fflush(stdout);
};
/* delete the association */
sctp_delete_association(assoc_id);
}
void communicationErrorNotif(unsigned int assoc_id, unsigned short status, void* dummy)
{
if (verbose) {
fprintf(stdout, "%-8u: Communication error (status %u)\n", assoc_id, status);
fflush(stdout);
}
}
void restartNotif(unsigned int assoc_id, void* dummy)
{
if (verbose) {
fprintf(stdout, "%-8u: Restart\n", assoc_id);
fflush(stdout);
}
}
void shutdownCompleteNotif(unsigned int assoc_id, void* dummy)
{
if (verbose) {
fprintf(stdout, "%-8u: Shutdown complete\n", assoc_id);
fflush(stdout);
}
}
int main(int argc, char **argv)
{
unsigned short sctp_instance;
struct ULPcallback discard_ulp;
/* initialize the discard_ulp variable */
discard_ulp.dataArriveNotif = &dataArriveNotif;
discard_ulp.sentFailureNotif = &sentFailureNotif;
discard_ulp.networkStatusChangeNotif = &networkStatusChangeNotif;
discard_ulp.communicationUpNotif = &communicationUpNotif;
discard_ulp.communicationLostNotif = &communicationLostNotif;
discard_ulp.communicationErrorNotif = &communicationErrorNotif;
discard_ulp.RestartNotif = &restartNotif;
discard_ulp.ShutdownCompleteNotif = &shutdownCompleteNotif;
/* handle all command line options */
getArgs(argc, argv);
/* set up the "server" */
sctp_instance = sctp_registerSCTP_instance(DISCARD_PORT,
MAXIMUM_NUMBER_OF_IN_STREAMS,
MAXIMUM_NUMBER_OF_OUT_STREAMS,
noOfLocalAddresses, localAddressList,
discard_ulp);
/* run the event handler forever */
while (sctp_event_loop() >= 0);
/* this will never be reached */
return 0;
}
/*
* $Id: echo_server.c,v 1.2 2001/02/15 17:45:07 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 http://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
*
* discard_server.c - main program module
*
*/
#include "sctp.h"
#include
#include
#define ECHO_PORT 7
#define MAXIMUM_NUMBER_OF_LOCAL_ADDRESSES 10
#define MAXIMUM_NUMBER_OF_ASSOCIATIONS 5
#define MAXIMUM_PAYLOAD_LENGTH 1500
#define MAXIMUM_NUMBER_OF_IN_STREAMS 17
#define MAXIMUM_NUMBER_OF_OUT_STREAMS 17
#define NO_CONTEXT 0 /* should we have this in sctp.h ? */
struct ulp_data {
unsigned int maximumStream_ID;
};
static struct ulp_data ulpData[MAXIMUM_NUMBER_OF_ASSOCIATIONS];
static unsigned char localAddressList[MAXIMUM_NUMBER_OF_LOCAL_ADDRESSES][MAX_IP_LEN];
static unsigned short noOfLocalAddresses = 0;
static int verbose = 0;
static int vverbose = 0;
void getArgs(int argc, char **argv)
{
int c;
extern char *optarg;
extern int optind;
while ((c = getopt(argc, argv, "s:vV")) != -1)
{
switch (c) {
case 's':
if ((noOfLocalAddresses < MAXIMUM_NUMBER_OF_LOCAL_ADDRESSES) &&
(strlen(optarg) < MAX_IP_LEN )) {
strcpy(localAddressList[noOfLocalAddresses], optarg);
noOfLocalAddresses++;
};
break;
case 'v':
verbose = 1;
break;
case 'V':
verbose = 1;
vverbose = 1;
break;
}
}
}
void dataArriveNotif(unsigned int assoc_id, unsigned int stream_id, unsigned int len,
unsigned int protoID, unsigned int unordered, void* ulpDataPtr)
{
unsigned char chunk[MAXIMUM_PAYLOAD_LENGTH];
int length;
if (vverbose) {
fprintf(stdout, "%-8u: Data arrived (%u bytes on stream %u, %s)\n",
assoc_id, len, stream_id, (unordered==SCTP_ORDERED_DELIVERY)?"ordered":"unordered");
fflush(stdout);
}
/* read it */
length = MAXIMUM_PAYLOAD_LENGTH;
sctp_receive(assoc_id, stream_id, chunk, &length);
/* and send it */
sctp_send(assoc_id,
min(stream_id, ((struct ulp_data *) ulpDataPtr)->maximumStream_ID),
chunk, length,
protoID,
SCTP_USE_PRIMARY, NO_CONTEXT, SCTP_INFINITE_LIFETIME, unordered, SCTP_BUNDLING_DISABLED);
}
void sentFailureNotif(unsigned int assoc_id,
unsigned char *unsent_data, unsigned int data_len, unsigned int *context, void* dummy)
{
if (verbose) {
fprintf(stdout, "%-8u: Sent failure\n", assoc_id);
fflush(stdout);
}
}
void networkStatusChangeNotif(unsigned int assoc_id, short dest_addr_index, unsigned short new_state, void* ulpDataPtr)
{
SCTP_AssociationStatus assocStatus;
SCTP_PathStatus pathStatus;
unsigned short path_id;
if (verbose) {
fprintf(stdout, "%-8u: Network status change: path %u is now %s\n",
assoc_id, dest_addr_index, ((new_state == SCTP_PATH_OK) ? "ACTIVE" : "INACTIVE"));
fflush(stdout);
}
/* if the primary path has become inactive */
if ((new_state == SCTP_PATH_UNREACHABLE) &&
(dest_addr_index == sctp_getPrimary(assoc_id))) {
/* select a new one */ /* should we have a sctp_get_primary()? */
sctp_get_assoc_status(assoc_id, &assocStatus);
for (path_id=0; path_id < assocStatus.number_of_addresses; path_id++){
sctp_get_path_status(assoc_id, path_id, &pathStatus);
if (pathStatus.state == SCTP_PATH_OK)
break;
}
/* and use it */
if (path_id < assocStatus.number_of_addresses) {
sctp_setPrimary(assoc_id, path_id);
}
}
}
void* communicationUpNotif(unsigned int assoc_id, unsigned short status,
int noOfDestinations,
unsigned short noOfInStreams, unsigned short noOfOutStreams, void* dummy)
{
unsigned int index;
if (verbose) {
fprintf(stdout, "%-8u: Communication up (%u paths)\n", assoc_id, noOfDestinations);
fflush(stdout);
}
/* look for a free ULP data */
for (index=0; index < MAXIMUM_NUMBER_OF_ASSOCIATIONS; index++) {
if (ulpData[index].maximumStream_ID == 0)
break;
}
/* if found */
if (index < MAXIMUM_NUMBER_OF_ASSOCIATIONS) {
/* use it */
ulpData[index].maximumStream_ID = noOfOutStreams - 1;
return &ulpData[index];
} else {
/* abort assoc due to lack of resources */
sctp_abort(assoc_id);
return NULL;
}
}
void communicationLostNotif(unsigned int assoc_id, unsigned short status, void* ulpDataPtr)
{
unsigned char buffer[MAXIMUM_PAYLOAD_LENGTH];
unsigned int bufferLength = sizeof(buffer);
unsigned short streamId, streamSN;
unsigned int protoID;
if (verbose) {
fprintf(stdout, "%-8u: Communication lost (status %u)\n", assoc_id, status);
fflush(stdout);
}
/* retrieve data */
while (sctp_receive_unsent(assoc_id, buffer, &bufferLength,
&streamId, &streamSN, &protoID) > 0){
/* do something with the retrieved data */
/* after that, reset bufferLength */
bufferLength = sizeof(buffer);
}
while (sctp_receive_unacked(assoc_id, buffer, &bufferLength,
&streamId, &streamSN, &protoID) > 0){
/* do something with the retrieved data */
/* after that, reset bufferLength */
bufferLength = sizeof(buffer);
}
/* free ULP data */
((struct ulp_data *) ulpDataPtr)->maximumStream_ID = 0;
/* delete the association */
sctp_delete_association(assoc_id);
}
void communicationErrorNotif(unsigned int assoc_id, unsigned short status, void* dummy)
{
if (verbose) {
fprintf(stdout, "%-8u: Communication error (status %u)\n", assoc_id, status);
fflush(stdout);
}
}
void restartNotif(unsigned int assoc_id, void* ulpDataPtr)
{
SCTP_AssociationStatus assocStatus;
if (verbose) {
fprintf(stdout, "%-8u: Restart\n", assoc_id);
fflush(stdout);
}
sctp_get_assoc_status(assoc_id, &assocStatus);
/* update ULP data */
((struct ulp_data *) ulpDataPtr)->maximumStream_ID = assocStatus.outstreams - 1;
}
void shutdownCompleteNotif(unsigned int assoc_id, void* ulpDataPtr)
{
if (verbose) {
fprintf(stdout, "%-8u: Shutdown complete\n", assoc_id);
fflush(stdout);
}
/* free ULP data */
((struct ulp_data *) ulpDataPtr)->maximumStream_ID = 0;
}
int main(int argc, char **argv)
{
unsigned short sctp_instance;
struct ULPcallback echo_ulp;
unsigned int index;
/* initialize UPL data */
for (index=0; index < MAXIMUM_NUMBER_OF_ASSOCIATIONS; index++) {
ulpData[index].maximumStream_ID == 0;
}
/* initialize the echo_ulp variable */
echo_ulp.dataArriveNotif = &dataArriveNotif;
echo_ulp.sentFailureNotif = &sentFailureNotif;
echo_ulp.networkStatusChangeNotif = &networkStatusChangeNotif;
echo_ulp.communicationUpNotif = &communicationUpNotif;
echo_ulp.communicationLostNotif = &communicationLostNotif;
echo_ulp.communicationErrorNotif = &communicationErrorNotif;
echo_ulp.RestartNotif = &restartNotif;
echo_ulp.ShutdownCompleteNotif = &shutdownCompleteNotif;
/* handle all command line options */
getArgs(argc, argv);
/* set up the "server" */
sctp_instance = sctp_registerSCTP_instance(ECHO_PORT,
MAXIMUM_NUMBER_OF_IN_STREAMS,
MAXIMUM_NUMBER_OF_OUT_STREAMS,
noOfLocalAddresses, localAddressList,
echo_ulp);
/* run the event handler forever */
while (sctp_event_loop() >= 0);
/* this will never be reached */
return 0;
}
/*
* $Id: sctp.h,v 1.8 2001/02/27 17:46:02 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 interface for the ULP, the application
* that uses SCTP.
* Further comments on message distribution can be found in the implemen-
* tation of this interface distribution.c.
*
* function prefix: sctp_
*/
/* MT: General comment: Please stick to one naming convention: sctp_set_parameter or sctp_setParameter ?*/
/* We are now using both which is not very good. */
#ifndef SCTP_H
#define SCTP_H
#ifdef HAVE_CONFIG_H
#include
#endif
/* MT: The next three lines should be deleted */
/* might be needed for struct timeval ? */
/* #include */
/* #include */
/* the maximum length of an IP address string (IPv4 or IPv6, NULL terminated) */
#define MAX_IP_LEN 46 /* == INET6_ADDRSTRLEN */
/* MT: 8 * 4 + 7 + 1 <> 46, I would like to understand this constant */
/* reasonable sized SACK, SCTP and IP header + one data chunk should be less than MTU */
/* this is ethernet..... ;-) */
#define MAXIMUM_DATA_LENGTH 1400
/******************** Defines *********************************************************************/
/* 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
/******************** 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 ULPcallback
{
/** @{ */
/**
* indicates new data have 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 (*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 (*sentFailureNotif) (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 (*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, (except for Restart or Duplicate Inits ?)
* @return the callback is to return a pointer, that will be transparently returned with every callback
*/
void* (*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 (*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 (*communicationErrorNotif) (unsigned int, unsigned short, void*);
/**
* indicates that a RESTART has occurred. (chapter 10.2.G)
* Currently not implemented !
* @param 1 associationID
* @param 2 pointer to ULP data
*/
void (*RestartNotif) (unsigned int, void*);
/**
* indicates that a RESTART has occurred. (chapter 10.2.H)
* Currently not implemented !
* @param 1 associationID
* @param 2 pointer to ULP data
*/
void (*ShutdownCompleteNotif) (unsigned int, void*);
/** @} */
};
typedef struct InstanceParameters {
/** @{ */
/** 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 path ? 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; /* MT was InstanceParams */
/*
* This struct contains the data to be returned to the ULP with the
* status primitive. Pointers point to arrays indexed by the number of
* destination addresses.
*/
typedef struct SCTP_Association_Status
{
unsigned short state; /* MT: was association_state; */
unsigned short number_of_addresses;
unsigned char primaryDestinationAddress[MAX_IP_LEN];
unsigned short outstreams;
unsigned short instreams;
unsigned short primaryAddressIndex;
unsigned int currentReceiverWindowSize; /* from FlowControl */
unsigned int outstanding_bytes;
unsigned int noOfChunksInSendQueue;
unsigned int noOfChunksInRetransmissionQueue; /* from ReliableTransfer */
unsigned int noOfChunksInReceptionQueue; /* from StreamEngine ? */
/** 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; /* was SCTP_AssociationState */
typedef struct SCTP_Path_Status
{
unsigned char address_string[MAX_IP_LEN];
/* SCTP_PATH_ACTIVE 0, SCTP_PATH_INACTIVE 1 */
short state; /* MT: was 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; /* MT: was SCTP_PathState; */
/******************** Function Definitions ********************************************************/
unsigned short sctp_registerSCTP_instance(unsigned short localPort,
unsigned short noOfInStreams,
unsigned short noOfOutStreams,
unsigned int noOfLocalAddresses,
unsigned char localAddressList[][MAX_IP_LEN],
struct ULPcallback ULPcallbackFunctions);
int sctp_unregisterSCTP_instance(unsigned short instance_name);
unsigned int sctp_associate(unsigned short SCTP_InstanceName,
unsigned short noOfOutStreams,
unsigned char destinationAddress[],
unsigned short destinationPort);
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 ORDERED_DELIVERY, UNORDERED_DELIVERY */
int dontBundle); /* use constants BUNDLING_ENABLED, 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_getSRTT_Report(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_get_assoc_status(unsigned int associationID, SCTP_AssociationStatus* status);
int sctp_set_assoc_status(unsigned int associationID, SCTP_AssociationStatus* new_status);
int sctp_get_path_status(unsigned int associationID, short path_id, SCTP_PathStatus* status);
int sctp_set_path_status(unsigned int associationID, unsigned short path_id,
SCTP_PathStatus *new_status);
/* Warum nicht sctp_getPathState usw? */
/*----------------------------------------------------------------------------------------------*/
/* MT: Do we really need this? These can be build up from the above functions ? */
int sctp_changeHeartBeat(unsigned int associationID,
short path_id, int heartbeatON, unsigned int timeIntervall);
int sctp_requestHeartbeat(unsigned int associationID, short path_id);
/* MT: Do we really need this? These can be build up from the above functions ? */
int sctp_setFailureThreshold(unsigned int associationID,
short path_id,
unsigned short pathMaxRetransmissions);
int sctp_receive_unsent(unsigned int associationID, unsigned char *buffer, unsigned int *length,
unsigned short *streamID, unsigned short *streamSN,unsigned int* protocolId);
int sctp_receive_unacked(unsigned int associationID, unsigned char *buffer, unsigned int *length,
unsigned short *streamID, unsigned short *streamSN,unsigned int* protocolId);
int sctp_delete_association(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. length of source address
*/
typedef void (*Socket_callback_function) (int, unsigned char *, int, unsigned char[] , int);
/**
* 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_register_udp_callback(unsigned char me[],
unsigned short my_port,
Socket_callback_function scf);
/**
* 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_register_stdin_callback(Socket_callback_function 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 (*Timer_expires_callback) (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_start_timer(unsigned int milliseconds,
Timer_expires_callback 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_stop_timer(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_restart_timer(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_get_events(void);
int sctp_event_loop(void);
#endif
- [SCTP-Discussion] API, second version, Michael Tüxen, 02/27/2001
Archive powered by MHonArc 2.6.19+.